WWW.DISS.SELUK.RU

БЕСПЛАТНАЯ ЭЛЕКТРОННАЯ БИБЛИОТЕКА
(Авторефераты, диссертации, методички, учебные программы, монографии)

 

Pages:     || 2 | 3 | 4 | 5 |

«xw Полный справочник ПО Четвертое издание Примеры программ Содержит описание Рассмотрены новейшие свойства языка совместимы со всеми международного в частности, перегрузка, наследование, стандарта C++, в том ...»

-- [ Страница 1 ] --

%

O sborne

xw

Полный

справочник

ПО

Четвертое издание

Примеры программ

Содержит описание Рассмотрены новейшие свойства языка совместимы со всеми

международного в частности, перегрузка, наследование, стандарта C++, в том компиляторами языка виртуальные функции, пространства числе ключевых слов, C++, включая имен, шаблоны, стандартная библиотека синтаксиса и библиотек Visual C++ шаблонов STL и механизм RTTI Автор наиболее популярных книг по программированию Количество проданных экземпляров превышает 3 миллиона!

Полный справочник по C++ 4-е издание C++:

The Complete Reference Fourth Edition Herbert Schildt McGraw-Hill/Osborne New York Chicago San Francisco Lisbon London Madrid Mexico City Milan New Delhi San Juan Seoul Singapore Sydney Toronto Полный справочник по C++ 4-е издание Герберт Шилдт Издательский дом “Вильямс” М осква С анкт-П етербург Киев ББК 32.973.26-018.2. Ш УДК 681.3. Издательский дом “ Вильямс” Зав. редакцией С.И. Тригуб Перевод с английского и редакция канд. физ.-мат. наук Д А. Илюшина По общим вопросам обращайтесь в Издательский дом “ Вильямс” по адресу:

[email protected], http://www.williamspublisliing.com Ш илдт, Герберт.

Ш57 Полный справочник по C + +, 4-е издание.. Пер. с англ. — М. : Издательский дом “ Вильямс”, 2006. — 800 с. : ил. — Парал. тит. англ.

ISBN 5-8459-0489-7 (рус.) В четвертом издании этой книги полностью описаны и проиллюстрированы все ключевые слова, функции, классы и свойства языка C + +, соответствующие стандарту A N SI/ISO. Информацию, изложенную в книге, можно использовать во всех современных средах программирования. Освещены все аспекты языка C + +, включая его основу — язык С. Справочник состоит из пяти частей: 1) подмноже­ ство С; 2) язы к C + + ; 3) библиотека стандартных функций; 4) библиотека стан­ дартных классов; 5) приложения на языке C + +.

Книгу предназначена для широкого круга программистов.

Б Б К 32.973.26-018.2. Все названия программных продуктов являются зарегистрированными торговыми марками соответствующих фирм.

Никакая часть настоящего издания ни в каких целях не может быть воспроизведена в ка­ кой бы то ни было форме и какими бы то ни было средствами, будь то электронные или ме­ ханические, включая фотокопирование и запись на магнитный носитель, если на это нет письменного разрешения издательства Osborne Publishing.

Authorized translation from the English language edition published by McGraw-Hill Companies, Copyright © All rights reserved. No part o f this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher.

Russian language edition published by Williams Publishing House according to the Agreement with R&I Enterprises International, Copyright © ISBN 0-07-222680-3 (англ.) Оглавление Глава 7. Структуры, объединения, перечисления и оператор typedef Глава 13. Массивы, указатели, ссылки и операторы динамического Глава 14. Перегрузка функций, конструкторы копирования и аргументы Глава 22. Динамическая идентификация типа и операторы приведения Глава 23. Пространства имен, преобразования функций и другие Глава 24. Введение в стандартную библиотеку шаблонов

ЧАСТЬ III. БИБЛИОТЕКА СТАНДАРТНЫХ ФУНКЦИЙ

Глава 29. Функции динамического распределения памяти

ЧАСТЬ IV. БИБЛИОТЕКА СТАНДАРТНЫХ КЛАССОВ

Глава 35. Стандартные итераторы, распределители памяти и функторы Глава 38. Обработка исключительных ситуаций и прочие классы Глава 39. Интеграция новых классов: пользовательский класс для работы Приложение А. Расширение языка C ++ для платформы.NET Приложение Б. Язык C ++ и робототехника Содержание И зменения, внесенные в четвертое издание ЧАСТЬ I. ОСНОВЫ ЯЗЫКА C++: ПОДМНОЖЕСТВО С Ш естнадцатеричные и восьмеричные константы Преобразования типов в операторе присваивания Содержание Оператор доступа к члену структуры и ссылки на член структуры Объявление параметров функции в классическом и современном стиле Глава 7. Структуры, объединения, перечисления и оператор typedef Содержание Применение оператора sizeof для обеспечения машинонезависимости П рименение функций fopen(), getc(), putc() и fclose() Применение функции freopen() для перенаправления стандартных потоков Что такое объектно-ориентированное программирование Содержание Глава 13. Массивы, указатели, ссылки и операторы динамического Инициализированные и неинициализированные массивы Глава 14. Перегрузка функций, конструкторы копирования и аргументы Создание инициализированных и неинициализированных объектов Создание префиксной и постфиксной форм операторов инкрементации Применение дружественных функций для перегрузки операторов “+ + ” и “-----” Перегрузка операторов new и delete, не генерирующих Вызов виртуальной функции с помощью ссылки на объект базового класса Содержание Использование стандартных параметров шаблонных функций Применение аргументов по умолчанию в шаблонных классах Обработчики, связанные с функциями term inate() и unexpected() Глава 22. Динамическая идентификация типа и операторы приведения Применение оператора dynamic_cast к шаблонным классам Глава 23. Пространства имен, преобразования функций и другие новшества П рим енен ие бинарны х операций ввода-вы вода к буферизованны м Глава 24. Введение в стандартную библиотеку шаблонов Содержание Изменение порядка следования элементов последовательности

ЧАСТЬ III. БИБЛИОТЕКА СТАНДАРТНЫХ ФУНКЦИЙ



Функции vprintf, vfprintf и vsprintf Глава 26. Строковые и символьные функции Содержание Глава 28. Функции времени, даты илокализации Глава 29. Функции динамического распределения памяти Макрос assert Ф ункция atexit Функция atof Функция atoi Функция atol Функция bsearch Функция div Функция exit Функция getenv Ф ункция longjmp Ф ункция mblen Ф ункция mbstowcs Ф ункция mbtowc Ф ункция qsort Функция raise Функция rand Функция setjmp Функция signal Функция srand Ф ункция strtod Функция strtol Функция strtoul Функция system Функция wcstombs Ф ункция wctomb Ф ункции классификации расширенных символов Функции ввода-вывода расширенных символов Ф ункции обработки строк, состоящих из расширенных символов Ф ункции преобразования строк, состоящих из расширенных символов Ф ункции обработки массивов расширенных символов Функции преобразования многобайтовых и расширенных символов

ЧАСТЬ IV. БИБЛИОТЕКА СТАНДАРТНЫХ КЛАССОВ

Классы ввода-вывода Заголовки ввода-вывода Флаги форматирования и манипуляторы ввода-вывода Некоторые типы данных Типы streamsize и streamoff Типы streampos и wstreampos Типы pos type и off_type Класс failure Перегрузка операторов “« ” и “ » ” Содержание Функция bad Функция clear Функция cof Функция exceptions Функция fail Функция fill Функция flags Функция flush Функции fstream, ifstream и. ofstream Функция gcount Функция get Функция getline Функция good Функция ignore Функция open Функция peek Функция precision Функция put Ф ункция putback Функция rdstate Функция read Ф ункция readsome Функции seekg и seekp Функция setf Функция setstate Функция str Функции stringstream, istringstream и ostringstream Функция sync with stdio Функции tellg и tellp Контейнерные классы Класс bitset Класс deque Класс multimap Класс multiset Класс queue Класс priority_queue Класс stack Класс vector Алгоритм adjacent find Алгоритм binary_search Алгоритм copy_backward Алгоритмы fill и fill_n Алгоритмы remove, rem o v eif, remove_copy и remove_copy_if Алгоритмы replace, replace_copy, replace_if и replace_copy_if Глава 35. Стандартные итераторы, распределители памяти и функторы Содержание Глава 38. Обработка исключительных ситуаций и прочие классы Глава 39. Интеграция новых классов: пользовательский класс для работы Простая программа синтаксического анализа выражений С интаксический анализатор, работающий с переменными П роверка синтаксических ош ибок при рекурсивном нисходящ ем анализе Содержание Об авторе Герберт Ш илдт — автор наиболее популярны х книг по программированию. Он является при знанн ы м специалистом по язы кам С, C + +, Java и С #, а также по програм м ированию в среде Windows. К ниги, нап исанны е Ш илдтом, переведены на все основны е язы ки мира. О бш ий объем их продаж превыш ает 3 м иллиона э к ­ зем пляров. Он является автором м ногочисленны х бестселлеров, в частности:

C + + : The Complete Reference, С#: The Complete Reference, Java 2: The Complete Reference, C: The Complete Reference, C + + from the Ground Up, C + + : A Beginner's Guide, C#: A Beginner's Guide и Java 2: A Beginner's Guide. Ш илдт получил звание магистра по компьютерным наукам в Университете штата Иллинойс (University o f Illinois).

Его консультацию можно получить по телефону офиса: (217) 586-4683.

Введение Язы к C + + оказывает огромное влияние на все области современного программи­ рования. Его синтаксис, стиль и основные принципы стали стандартом при разработ­ ке новых языков. Благодаря своей универсальности он все чаще используется при описании алгоритмов и технологий программирования. Долговременный успех языка C + + определил основные тенденции развития компьютерных языков. Например, языки Java и C# являются его непосредственными наследниками. Скажем прямо, не­ возможно стать профессиональным программистом, не овладев языком C + +. Это единственный язык, игнорировать который программист не имеет права.

Перед вами перевод четвертого издания книги C + +: The Complete Reference. Здесь подробно описаны и проиллюстрированы все ключевые слова, функции, классы и свойства языка C + +. Точнее говоря, в книге рассматривается вариант языка C + + под названием Standard C++. Именно эта версия соответствует международному стандарту ANSI/ISO и подерживается всеми основными компиляторами, включая Visual C + + компании Microsoft и C + + Builder компании Borland. Таким образом, информацию, из­ ложенную в книге, можно использовать во всех современных средах программирования.

За время, прошедшее после выхода в свет предыдущего издания книги, язык C + + не претерпел никаких изменений. В то же время радикально изменилась сама среда про­ граммирования. Например, появился новый стандарт языка С, получивший название С99, язык Java захватил господствующее положение в области Web-программирования, приобретает все большую популярность среда программирования.NET Framework.

В потоке всех изменений, происшедших за последние годы, осталось незыблемым лишь одно — мощь языка C + +. Его преимущество над другими языками в области разработки высокоэффективного программного обеспечения по-прежнему бесспорно.

Изменения, внесенные в четвертое издание Общая структура справочника осталась прежней. Если вы читали третье издание, то сможете легко ориентироваться и в четвертом. Большинство изменений касается стиля изложения: в некоторых случаях добавлены новые подробности, в других местах иначе раскрыта тема. Кроме того, мы стремились учесть изменения, касающиеся со­ временной среды программирования. В книгу также добавлено несколько новых раз­ делов, например, в первой части иллюстрируется взаимосвязь между язы ком C + + и новым стандартом язы ка С, получившим название С99.

Книга содержит два новых приложения. В первом описаны расширенные ключевые слова, предложенные компанией Microsoft для создания управляемого кода по техноло­ гии.NET Framework. Второе приложение отражает личные вкусы автора и посвяшено роботам, которые долгое время были его хобби. Надеемся, что у читателей вызовет ин­ терес разработанный автором экспериментальный робот. Разумеется, большая часть программного обеспечения, управляющего этим роботом, написана на языке C++!

В заключение отметим, что все программы были заново перепроверены на совре­ менных компиляторах, включая компиляторы Visual Studio.NET компании Microsoft и C + + Builder компании Borland.

Содержание книги В книге подробно освещены все аспекты язы ка C + +, включая его основу — язы к С. Справочник состоит из пяти частей.

• Подмножество С — основа языка C + +.

Введение • Библиотека стандартных функций.

• Библиотека стандартных классов.

• Приложения, написанные на языке C + +.

Первая часть содержит подробное обсуждение язы ка С, который представляет со­ бой подмножество языка C + +. Как известно, язы к С — эго фундамент, на котором построен язы к C + +. И менно из язы ка С позаимствованы основные конструкции язы ка C + +, например, циклы f o r и оператор i f. Кроме того, язык С определил ос­ новные свойства блочных структур, указателей и функций в языке C + +. Поскольку многие читатели уже хорошо знакомы с языком С, обсуждение его особенностей в самом начале книги позволит опытным программистам избежать повторения прой­ денного и перейти непосредственно к темам, посвященным собственно языку C + +.

Во второй части справочника обсуждение выходит за рамки языка С и посвящает­ ся особенностям языка C + +. Здесь рассматриваются его объектно-ориентированные свойства, например, классы, конструкторы, деструкторы, механизм динамической идентификации типа (Run-Tim e Type Identification — RTTI) и шаблоны. Таким обра­ зом, в части II описаны те конструкции, которые определяют сущность языка C + +.

Третья часть посвящ ена стандартной библиотеке функций, а четвертая —классов, включая стандартную библиотеку шаблонов STL (Standard Template Library). В пятой части приведены два практических приложения, созданных с помощью язы ка C + + и объектно-ориентированного программирования.

Рекомендуемая литература Полный справочник по C + + открывает перед читателями мир интереснейших книг по программированию, написанных Гербертом Ш илдтом (Herbert Schildt).

Для дальнейшего изучения язы ка C + + обратите внимание на следующие издания.

C ++: A Beginner's Guide C + + from the Ground Up Teach Yourself C ++ ST L Programming from the Ground Up C + + Programmer's Reference Для освоения язы ка Java мы рекомендуем такие книги.

Java 2: A Beginner's Guide Java 2: The Complete Reference Java 2: Programmer's Reference О языке C# Герберт Ш илдт написал следующие справочники.

С#: A Beginner's Guide С#: The Complete Reference При изучении программирования в среде Windows вам помогут такие книги.

Windows 98 Programming from the Ground Up Windows 2000 Programming from the Ground Up MFC Programming from the Ground Up The Windows Programming Annotated Archives Если вы захотите освоить язы к С, лежащ ий в основе всего современного програм­ мирования, обязательно прочтите следующие издания.

С: The Complete Reference Teach Yourself С Если вам нужен быстрый и правильный ответ на ваш вопрос, обратитесь к Герберту Шилдту, признанному авторитету в области программирования.

Полный справочник по Часть I Основы языка C ++:

подмножество С Описание языка C++ в книге разделено на две части.

В части I обсуждаются свойства языка С, унаследованные языком C++. Обычно их называют подмножеством С языка C++. В части II рассматриваются специфические особенности языка C++. В совокупности эти две части содержат полное описание языка C++.

ероятно, читателям уже известно, что язык C + + создан на основе языка С. Ф ак­ В тически язы к C + + включает в себя весь язык С, и все программы (за некоторым исключением), написанные на языке С, можно считать программами на языке C + +.

В процессе разработки язы ка C + + в качестве отправной точки был выбран язык С. За­ тем к нему были добавлены новые свойства и возможности, разработанные для под­ держки объектно-ориентированного программирования. Однако от языка С при этом не отказались, и стандарт 1989 года A N SI/ISO С Standard стал базовым документом при создании международного стандарта язы ка C + + (International Standard). Таким образом, осваивая язык C + +, программисты одновременно овладевают языком С.

Разделение свойств язы ка С и специфических особенностей язы ка C + + позволяет достичь трех основных целей.

Четко провести разделительную линию между языками С и C + +.

Предоставить читателям, владеющим языком С, возможность легко усвоить информацию об особенностях язы ка C + +.

Выделить и подробно описать свойства языка C + +, унаследованные от языка С.

Очень важно точно провести линию, отделяющую язы к С от язы ка C + +, посколь­ ку они очень широко распространены, и от программиста иногда требуется поддержка программ, написанных на обоих языках. Если вы пишете программу на языке С, нужно четко понимать, где заканчивается язы к С и начинается язы к C + +. Многие программисты, работающие на язы ке C + +, иногда пишут программы на языке С и не используют специфические свойства язы ка C + +. В особенности это относится к программированию встроенных систем и поддержке существующих приложений.

Таким образом, понимание различий между этими языками является необходимым условием профессионального программирования на C + +.

Полное и свободное владение языком С абсолютно необходимо для перевода про­ грамм на язы к C + +. Чтобы сделать это на высоком уровне, необходимо хорошо знать язык С. Например, без ясного понимания механизмов ввода-вывода, предусмотренных в языке С, невозможно трансформировать программу, осуществляющую интенсивный обмен данными с внешними устройствами, в эффективную программу на языке C + +.

Многие читатели уже владеют языком С. Вследствие этого выделение тем, связан­ ных с языком С, позволяет опытным программистам избежать повторения пройден­ ного и перейти непосредственно к изучению особенностей язы ка C + +. Разумеется, в части I подчеркиваются малейшие отличия язы ка C + + от язы ка С. Кроме того, от­ деление подмножества С от остальных свойств языка C + + позволяет в дальнейшем сосредоточиться на его объектно-ориентированных особенностях.

Несмотря на то что язык C + + полностью содержит язык С, как правило, не все свой­ ства языка С используются в программах, написанных “в стиле C + + ”. Например, система ввода-вывода, предусмотренная в языке С, по-прежнему доступна в языке C + +, хотя в C + + существуют свои объектно-ориентированные механизмы ввода-вывода данных. Еще одним примером такого анахронизма является препроцессор. Он играет чрезвычайно важ­ ную роль в языке С и очень скромную — в языке C ++. Обсуждение свойств, присущих “стилю языка С”, в первой части книги позволяет избежать путаницы в остальных главах.

Запомните: подмножество С, описанное в части I, является ядром язы ка C + + и фундаментом, на котором воздвигнуты его объектно-ориентированные конструк­ ции. Все свойства, описанные здесь, являются неотъемлемой частью язы ка C + + и могут быть использованы в ваших программах.

Часть I содержит материалы из моей книги С: The Complete Reference (McGrawHillНа заметку Osbome) (Русский перевод: Г. Шилдт. Полный справочник по языку С. — М.: Изд.

дом ‘Вильямс”, 2001. — Прим. ред.). Если язык С интересует вас как самостоятель­ ный язык программирования, эта книга окажется для вас ценным помощником.

Полный справочник по Глшш Обзор языка С тобы понять язы к C + +, необходимо понять мотивы его создания, идеи, положен­ Ч ные в его основу, и свойства, которые он унаследовал от своих предшественников.

Таким образом, история язы ка C + + начинается с языка С. В главе представлен обзор языка С, а также описана история его возникновения, способы применения и основ­ ные принципы. Поскольку язы к C + + создан на основе языка С, эту главу можно счи­ тать описанием предыстории языка C + +. М ногое из того, что сделало язы к C + + та­ ким популярным, уходит корнями в язы к С.

Ш Происхождение и история языка С Язык С был изобретен и впервые реализован Деннисом Ритчи (Dennis Ritchie) на компьютере DEC P D P -1 1 под управлением операционной системы UNIX. Язык С поя­ вился в результате развития языка под названием BCPL. В свою очередь, этот язы к был разработан М артином Ричардсом (M artin Richards) под влиянием другого языка, имевшего название В, автором которого был Кен Томпсон (Ken Tompson). Итак, в 1970-х годах развитие языка В привело к появлению языка С.

М ногие годы фактическим стандартом языка С была версия для операционной системы UNIX. Впервые она была описана в книге Брайана Кернигана (Brian Kernigan) и Денниса Ритчи The С Programming Language в 1978 году. (Русский перевод: Керниган Б., Ритчи Д. Язык программирования С. — СПб: Невский диалект, 2001. — Прим.

ред.). Летом 1983 года был создан комитет Американского института национальных стандартов (American National Standards Institute — ANSI), целью которого была разра­ ботка стандарта языка С. Работа комитета неожиданно растянулась на шесть лет.

В итоге стандарт ANSI С был одобрен в декабре 1989 года и стал распространяться в начале 1990-го. Этот стандарт был также одобрен Организацией международных стандар­ тов (International Standards Organization — ISO), получив название AN SI/ISO Standard С.

В 1995 году была одобрена Первая поправка, которая помимо всего прочего добавила не­ сколько новых библиотечных функций. В 1989 году стандарт языка С вместе с Первой по­ правкой стали базовым документом для стандарта языка C ++, в котором было выделено под­ множество С. Версию языка С, определенную стандартом 1989 года, обычно называют С89.

После 1989 года в центре внимания программистов оказался язык C + +. Развитие этого языка на протяжении 1990-х годов завершилось одобрением стандарта в конце 1998 года. Между тем работа над языком С продолжалась, не вызывая излишнего шума.

В итоге в 1999 году появился новый стандарт языка С, который обычно называют С99.

В целом стандарт С99 сохранил практически все свойства стандарта С89, не изменив основных аспектов языка. Таким образом, язык С, описанный стандартом С99, практи­ чески совпадает с языком, соответствующим стандарту С89. Комитет по разработке стандарта С99 сосредоточился на двух вопросах: включении в язык нескольких матема­ тических библиотек и развитии некоторых специфических и весьма сложных свойств, например, массивов переменной длины и квалификатора указателей r e s t r i c t. В стан­ дарт С99 вошли также некоторые свойства, позаимствованные из языка C + +, например, однострочные комментарии. Поскольку разработка стандарта языка C + + завершилась до создания стандарта С99, ни одно из новшеств языка С не вошло в стандарт C + +.

Ш Сравнение стандартов С89 и С Н есмотря на то что все новш ества, внесенны е в стандарт С99, весьма важны с теоретической точки зр ен и я, они имели мало практических последствий, так как до сих пор нет ни одного ш ироко распространенного ком пилятора, который поддерживал бы стандарт С99. Больш инство программ истов до сих пор считаю т язы ком С его вариант, определенны й стандартом С89. И м енно его реализую т все основны е ком пиляторы. Более того, подмнож ество С язы ка C + + описывается им енн о стандартом С89. Хотя некоторы е новш ества, вклю ченные в стандарт С99, в конце концов обязательно будут учтены следую щим стандартом язы ка C + +, по­ ка они несовм естим ы с язы ком C + +.

Поскольку подмножество С язы ка C + + соответствует стандарту С89, и эту версию изучают большинство программистов, именно ее мы рассмотрим в части I. Итак, ис­ пользуя название С, мы будем иметь в виду версию языка, определенную стандартом С89. Однако мы будем отмечать важные различия между версиями С89 и С99, по­ скольку это улучшит совместимость языков С и C + +.

I С - язык среднего уровня Язы к С часто называют языком среднего уровня. Это не означает, что он менее эф ­ фективен, более неудобен в использовании или менее продуман, чем языки высокого уровня, такие как Basic или Pascal. Отсюда также не следует, что он запутан, как язык ассемблера (и порождает связанные с этим проблемы). Это выражение означает лиш ь, что язы к С объединяет лучшие свойства языков высокого уровня, возможности управления и гибкость языка ассемблера. В табл. 1.1 показано место языка С среди других языков программирования.

Таблица 1.1. Место языка С среди остальных языков программирования

FORTRAN

Средний уровень Низший уровень Будучи язы ком среднего уровня, язы к С позволяет осущ ествлять м анипуляции с битам и, байтам и и адресами — основны м и элем ентам и, с которыми работают ф ункц ии о п ераци онной системы. Н есмотря на это, программы, нап исанны е на язы ке С, можно вы полнять на разны х компью терах. Это свойство программ н а­ зы вается машинонезависимостью (portability). Н априм ер, если программу, н ап и ­ санную для операци онной системы U N IX, м ож но легко преобразовать, чтобы она работала на платформ е W indows, то говорят, что такая программа является м аш и­ нонезависимой (portable).

Все языки высокого уровня используют концепцию типов данных. Тип данных (data type) определяет множество значений, которые может принимать переменная, а также множество операций, которые над ней можно выполнять. К основным типам данных относятся целое число, символ и действительное число. Несмотря на то что в языке С существует пять встроенных типов данных, он не является строго типизи­ Глава 1. Обзор языка С рованным языком, как языки Pascal и Ada. В языке С разрешены практически все преобразования типов. Например, в одном и том же выражении можно свободно ис­ пользовать переменные символьного и целочисленного типов.

В отличие от языков высокого уровня, язы к С практически не проверяет ошибки, возникающие на этапе выполнения программ. Например, не осуществляется проверка возможного выхода индекса массива за пределы допустимого диапазона. Предотвра­ щение ош ибок такого рода возлагается на программиста.

Кроме того, язы к С не требует строгой совместимости типов параметров и аргу­ ментов функций. Как известно, языки высокого уровня обычно требуют, чтобы тип аргумента точно совпадал с типом соответствующего параметра. Однако в языке С та­ кого условия нет. Он позволяет использовать аргумент любого типа, если его можно разумным образом преобразовать в тип параметра. Кроме того, язы к С предусматри­ вает средства для автоматического преобразования типов.

О собенность язы ка С заклю чается в том, что он позволяет непосредственно м а­ нипулировать битами, байтами, маш инны м и словами и указателями. Это делает его очень удобным для системного программирования, в котором эти операции ш ироко распространены.

Другой важный аспект язы ка состоит в том, что в нем предусмотрено очень не­ большое количество ключевых слов, которые можно использовать для конструирова­ ния выражений. Например, стандарт С89 содержит лиш ь 32 ключевых слова, а стан­ дарт С99 добавил к ним всего 5 слов. Некоторые языки программирования содержат в несколько раз больше ключевых слов. Скажем, самые распространенные версии языка BASIC предусматривают более 100 таких слов!

С - структурированный язык Возможно, вы уже слышали словосочетание блочно-структурированный (blockstructured) по отношению к языку программирования. Хотя этот термин нельзя напрямую применять к языку С, его обычно тоже называют структурированным. Он имеет много общего с другими структурированными языками, такими как ALGOL, Pascal и Modula-2.

Язык С (как и C++) не считается блочно-структурированным, поскольку не по­ зволяет объявлять одну функции внутри других.

Отличительной особенностью структурированных языков является обособление кода и данных (compartmentalization). О но позволяет выделять и скрывать от остальной части программы данные и инструкции, необходимые для решения конкретной зада­ чи. Этого можно достичь с помощью подпрограмм (subroutines), в которых использу­ ются локальные (временные) переменные. Используя локальные переменные, можно создавать подпрограммы, не порождающие побочных эффектов в других модулях. Это облегчает координацию модулей между собой. Если программа разделена на обособ­ ленные функции, нужно лиш ь знать, что делает та или иная ф ункция, не интересуясь, как именно она выполняет свою задачу. Помните, что чрезмерное использование гло­ бальных переменных (которые доступны в любом месте программы) повышает веро­ ятность ош ибок и нежелательных побочных эффектов. (Каждый программист, рабо­ тавший на языке BASIC, хорошо знает эту проблему.) м | й | Н | Концепция обособления широко применяется в языке C++. В частности, кажI дая часть программы, написанной на этом языке, может четко управлять Структурные язы ки предоставляю т ш ирокий спектр возм ож ностей. О ни допус­ кают использование влож енны х циклов, наприм ер w h i l e, d o - w h i l e и f o r.

В структурированны х язы ках использование оператора g o t o либо запрещ ено, л и ­ бо неж елательно и не вклю чается в набор основны х средств управления пото­ ком вы полнения програм м ы (как это принято в стандарте язы ка BASIC и в тра­ д ици онном язы ке FO R TRA N ). С труктурированны е язы ки позволяю т разм е­ шать несколько инструкций программы в одной строке и не ограничи­ вают програм м иста ж естким и полям и для ввода команд (как это делалось в ста­ рых версиях язы ка FO R TRA N ).

Рассмотрим несколько примеров структурированных и неструктурированных язы ­ ков (табл. 1.2).

Таблица 1.2. Структурированные и неструктурированные языки программирования Неструктурированные Структурированные BASIC COBOL Структурированные языки считаются более современными. В настоящее время не­ структурирован ность является признаком устаревших языков программирования, и лиш ь немногие программисты выбирают их для создания серьезных приложений.

Новые версии старых языков программирования (например Visual Basic) вклю­ На заметку чают элементы структурированости. И все же врожденные недостатки этих языков вряд пи будут до конца исправлены, поскольку структурированность не Основным структурным элементом языка С является функция. И менно функции служат строительными блоками, из которых создается программа. Они позволяют разбивать программу на модули, решающие отдельные задачи. Создав функцию, мож­ но не беспокоиться о побочных эффектах, которые она вызовет в других частях про­ граммы. Способность создавать отдельные функции чрезвычайна важна при реализа­ ции больших проектов, в которых один фрагмент кода не должен взаимодействовать с другими частями программы непредсказуемым образом.

Другой способ структурирования и обособления программы, написанной на язы ке С, — блоки. Блок (code block) — это группа операторов, логически связанных между собой, и рассматриваемых как единое целое. В язы ке С блок можно создать с помощью фигурных скобок, ограничиваю щ их последовательность операторов. Вот типичный прим ер блока.

pr i n t f ("Слишком мало, попробуйте снова.\п";

scanf("%d", & х ) ;

Два оператора, расположенных внутри фигурных скобок, выполняются, если зна­ чение переменной х меньш е 10. Эти два оператора вместе с фигурными скобками об­ разуют блок. Блок — это логическая единица, поскольку оба оператора обязательно должны быть выполнены. Блоки позволяют ясно, элегантно и эффективно реализо­ вывать различные алгоритмы. Более того, они помогают программисту лучше выра­ зить природу алгоритма.

Глава 1. Обзор языка С —I С - язык для программистов К ак ни странно, не все язы ки программирования предназначены для програм­ мистов. Рассмотрим классические примеры язы ков, ориентированных не на про­ граммистов, — COBOL и BASIC. Язык COBOL был разработан вовсе не для того, чтобы облегчить участь программистов, улучшить ясность кода и повысить его н а­ дежность, и даже не для того, чтобы ускорить вы полнение программ. Он был соз­ дан, в частности, для того, чтобы люди, не являю щ иеся программистами, могли чи­ тать и (по возможности) понимать (хотя это вряд ли) написанны е на нем програм­ мы. В свою очередь, язы к BASIC был разработан для пользователей, которые решают на компьютере простые задачки.

В противоположность этому, язык С был создан для программистов, учитывал их интересы и многократно проверялся на практике, прежде чем был окончательно реа­ лизован. В итоге этот язы к дает программистам именно то, чего они желали: сравни­ тельно небольшое количество ограничений, минимум претензий, блочные структуры, изолированные функции и компактный набор ключевых слов. Язык С обладает эф ­ фективностью ассемблера и структурированностью языков ALGOL или Modula-2. По­ этому неудивительно, что именно языки С и C + + стали наиболее популярными среди профессиональных программистов высокого уровня.

Тот ф акт, что язы к С часто используют вместо ассемблера, является одной из основных причин его популярности. Я зы к ассемблера использует символьное пред­ ставление фактического двоичного кода, который непосредственно выполняется компьютером. Каждая операция, выраженная на язы ке ассемблера, представляет собой отдельную задачу, выполняемую компьютером. Хотя язы к ассемблера предос­ тавляет программисту наибольш ую гибкость, разрабатывать и отлаживать програм­ мы на нем довольно сложно. Кроме того, поскольку язы к ассемблера является н е­ структурированным, код напоминает спагетти — запутанную смесь переходов, вы­ зовов и индексов. Вследствие этого программы, написанны е на языке ассемблера, трудно читать, модифицировать и эксплуатировать. Вероятно, основным недостат­ ком программ на язы ке ассемблера является их маш инозависимость. Программа, предназначенная для конкретного центрального процессора, не может выполняться на компьютерах другого типа.

Изначально язы к С предназначался для системного программирования. Системная программа (system program) представляет собой часть операционной системы или яв­ ляется одной из ее утилит. Рассмотрим некоторые из них.

• Операционные системы • Диспетчеры реального времени По мере роста популярности языка С многие программисты стали применять его для программирования всех задач, используя его машинонезависимость и эф ф ектив­ ность, а кроме того, он им просто нравился! К моменту появления языка С языки программирования прошли сложный и трудный путь совершенствования. Разумеется, вновь созданный язы к вобрал в себя все лучшее.

С появлением язы ка C + + некоторые программисты посчитали, что язы к С поте­ ряет самостоятельность и сойдет со сцены. Однако этого не произошло. Во-первых, не все программы должны быть объектно-ориентированными. Например, программ­ ное обеспечение встроенных систем по-прежнему создается на языке С. Во-вторых, существует огромное множество программ на языке С, которые активно эксплуатиру­ ются и нуждаются в модификации. Поскольку язы к С является основной языка C + +, он продолжает ш ироко использоваться, имея блестящие перспективы.

Структура программы на языке С В табл. 1.3 перечислены 32 ключевых слова, которые используются при формиро­ вании синтаксиса язы ка С, стандарта С89 и подмножества С языка C + +. Все они, ко­ нечно, являются и ключевыми словами языка C + +.

Таблица 1.3. Ключевые слова подмножества С языка C++ case Кроме того, м ногие ком пиляторы для более эф ф ективного использования сре­ ды програм м ирования вносят в язы к С дополнительны е клю чевые слова. Н ап р и ­ мер, некоторы е ком пиляторы предусматриваю т клю чевые слова для управления памятью процессоров сем ейства 8086, поддерж ки м ногоязы чного програм м ирова­ ния и доступа к систем ны м преры ваниям. П еречислим некоторые из этих расш и ­ ренны х клю чевы х слов.

Ваш компилятор может изменить этот список, стремясь наиболее эффективно ис­ пользовать конкретную среду программирования.

Обратите внимание на то, что все ключевые слова набраны строчными буквами.

Язык C /C + + чувствителен к регистру (case sensitive), т.е. прописные и строчные бук­ вы в нем различаются. Это значит, что слово e l s e является ключевым, а слово e l s e — нет Ключевые слова нельзя использовать в программе для иных целей, на­ пример, в качестве имени переменной или функции.

Все программы на языке С состоят из одной или нескольких функций. В любом случае программа должна содержать функцию m a i n ( ), которая при выполнении программы вызывается первой. В хорошо написанном коде функция m a in ( ) должна содержать, по существу, схему работы всей программы. Несмотря на то что имя m a in () не включено в список ключевых слов, по своей природе оно является именно таковым. Скажем, назвать переменную именем m a in нельзя, так как компилятор сра­ зу выдаст сообщ ение об ошибке.

Глава 1. Обзор языка С Общий вид программы на язы ке С показан в листинге 1.1. Ф ункции с именами f l ( ),..., f N () определяются пользователем.

Листинг 1.1. Общий вид программы на языке С последоват ельност ь операт оров последоват ельност ь операт оров последоват ельност ь операт оров последоват ельност ь операт оров ! И Библиотека и связывание С формальной точки зрения можно написать законченную и вполне осмысленную программу на языке С, не используя ни одной стандартной функции. Однако это до­ вольно затруднительно, так как в языке С нет ключевых слов, имеющих отношение к вводу-выводу, математическим операциям высокого уровня или обработке симво­ лов. В результате большинство программ вынуждены вызывать различные функции, содержащиеся в стандартной библиотеке (standard library).

Все компиляторы языка C + + сопровождаются стандартной библиотекой функций, выполняющих наиболее распространенные задачи. В этой библиотеке определен ми­ нимальный набор ф ункций, которые поддерживаются большинством компиляторов.

Однако конкретный компилятор может содержать много других функций. Например, стандартная библиотека не содержит графических функций, но в каждом компиляторе всегда есть определенный набор таких функций.

С тандартная библиотека язы ка C + + разделена на две части: ф ункц ии и клас­ сы. С тандартная библиотека ф у н кц и й представляет собой наследие язы ка С. Я зык C + + поддерж ивает все ф у н кц и и, предусм отренны е стандартом С89. Таким обра­ зом, все стандартны е ф ункц ии язы ка С м ож но свободно использовать в програм ­ мах на язы ке C + +.

Кроме стандартной библиотеки функций, язы к C + + имеет собственную библиоте­ ку классов. Эта библиотека состоит из объектно-ориентированных модулей, которые можно использовать в собственных программах. Кроме того, существует стандартная библиотека шаблонов STL, содержащая ш ирокий набор готовых решений многих за­ дач. В части I используется только стандартная библиотека ф ункций, поскольку именно она относится к языку С.

Стандартная библиотека состоит из многих универсальных функций. При вызове библиотечной функции компилятор “запоминает” ее имя. Позднее редактор связей объединит ваш код с объектным кодом этой библиотечной функции. Этот процесс называется редактированием связей (linking). Некоторые компиляторы имеют свои собственные редакторы связей, остальные используют редактор связей, предусмот­ ренный операционной системой.

Ф ункции в библиотеке имеют машинонезависимый формат (relocatable format). Это значит, что адреса памяти для разных маш инных инструкций не являются абсолют­ ными — сохраняется лиш ь информация о смещении их адреса. Ф актические адреса ячеек, используемых стандартными функциями, определяются во время редактирова­ ния связей. Подробное описание этих процессов можно найти в соответствующих технических руководствах. Более детальные объяснения были бы излишни.

В стандартной библиотеке содержится много функций, которые могли бы оказать­ ся полезными. Они представляют собой крупные строительные блоки, из которых можно сконструировать свою программу. В частности, если какую-то функцию вы используете в своих программах очень часто, ее следует поместить в библиотеку.

Раздельная компиляция Больш инство коротких программ обычно можно уместить в одном файле. О дна­ ко по мере возрастания объема программы увеличивается время ее ком пилирова­ ния. Для реш ения этой проблемы в язы ке C /C + + предусмотрена возможность д е­ лить программу на файлы и компилировать каждый из них отдельно. С компилиро­ вав все ф айлы, отредактировав связи между ним и и библиотечными ф ункциям и, вы получите заверш енны й объектный код. Преимуш ество раздельной ком пиляции за­ ключается в том, что при изм енении кода, записанного в одном из файлов, нет не­ обходимости компилировать заново всю программу. Это сущ ественно эконом ит время на этапе ком пиляции. Д окум ентация, сопровождающая компиляторы языка C /C + +, содержит инструкции, которые позволят вам скомпилировать программу, записанную в нескольких файлах.

Расширения файлов.С и.СРР Разумеется, программы, приведенные в части I, являются вполне корректными программами на языке C + +. Их можно компилировать с помощью любого современ­ ного компилятора языка C + +. Одновременно они являются корректными програм­ мами на языке С и могут компилироваться с помошью компиляторов этого языка.

Итак, если вы собираетесь писать программы на языке С, можете рассматривать программы из первой части в качестве примера. Традиционно программы на языке С используют расширения файла.С, а программы на языке C + + —.СРР. Компилятор языка C + + использует расширение файла для определения типа программы. Это име­ ет большое значение, поскольку компилятор рассматривает любую программу, ис­ пользующую расширение.С, как программу на языке С, а программу, записанную в файл с расширением.С РР, — как программу на языке C + +. Если обратное не ука­ зано явно, вы можете выбрать любое расширение для файла с программой из первой Глава 1. Обзор языка С части книги. Однако программы, приведенные в остальной части книги, должны быть записаны в файлы с расширением.СРР.

И последнее: хотя язы к С является подмножеством языка C + +, между ним и суще­ ствует несколько отличий. В некоторых случаях программу на языке С нужно компи­ лировать именно как программу на языке С (используя расширение.С). Все такие слу­ чаи мы оговариваем отдельно.

Полный справочник по Глава Выражения э т о й главе рассматриваются самые важные элементы языка С (и, соответственно, язы ка C + + ) — выражения (expressions). В языке C /C + + выражения носят намного более абстрактный характер, чем в больш инстве других языков программирования, и обладают большей экспрессивностью. Выражения состоят из атомарных элементов:

данных и операторов. Данные представляют собой либо переменные, либо константы.

К ак и во многих языках программирования, в языке C /C + + предусмотрено большое количество разнообразных типов данных и операторов.

Пять основных типов данных В подмножестве С существуют пять элементарных типов данных: символ, целое чис­ ло, число с плавающей точкой, число с плавающей точкой удвоенной точности и пере­ менная, не имеющая значений. Им соответствуют следующие ключевые слова: c h a r, i n t, f l o a t, d o u b le и v o id. Все другие типы данных в языке С создаются на основе элементарных типов, указанных выше. Размер переменных и диапазон их значений за­ висит от типа процессора и компилятора. Однако во всех случаях размер символа равен 1 байт. Размер целочисленной переменной обычно равен длине машинного слова, при­ нятой в конкретной операционной системе. В большинстве 16-битовых операционных систем, например, DOS и Windows 3.1, размер целочисленной переменной равен 16 бит.

В большинстве 32-битовых операционных систем, например Windows 2000, этот размер равен 32 бит. Однако, стремясь к машинонезависимости программ, следует избегать конкретных предположений о размере целочисленных переменных. Важно четко по­ нимать, что и в языке С, и в языке C + + оговаривается лиш ь минимальный диапазон, в котором изменяются значения переменных каждого типа, а не их размер в байтах.

К пяти основным типам данных, определенных в языке С, язык C++ добавляет еще На заметку два: b o o l и wcbar t. Эти типы будут рассмотрены во второй части книги.

Точное представление чисел с плавающей точкой зависит от их конкретной реализа­ ции. Размер целого числа обычно равен длине машинного слова, принятой в операцион­ ной системе. Значения переменных типа c h a r, как правило, используются для представ­ ления символов, предусмотренных в системе кодирования ASCII. Значения, выходящие за пределы допустимого диапазона, на разных компьютерах обрабатываются по-разному.

Д иапазон изменения переменных типа f l o a t и d o u b l e зависит от способа пред­ ставления чисел с плавающей точкой. В любом случае, этот диапазон достаточно ш и­ рок. Стандарт языка С определяет минимальный диапазон изменения чисел с пла­ вающей точкой: от IE— до IE+37. М инимальное количество цифр, определяющих точность чисел с плавающей точкой, указано в табл. 2.1.

Таблица 2.1. Все типы данных, определенные в стандарте ANSI/IS0 С Standard Тип В стандарте языка C++ минимальный размер и диапазон изменения перемен­ На заметку ных, имеющих элементарный тип, не определен. Вместо этого в нем просто указано, что они должны соответствовать определенным условиям. Напри­ мер, стандарт требует, чтобы переменная типа i n t ‘Ьмепа естественный размер, соответствующий архитектуре операционной системы". В любом случае, ее диапазон должен совпадать или превосходить диапазон изменения переменной данного типа, предусмотренный стандартом языка С. Каждый компилятор языка C++ задает размер и диапазон изменения переменных всех Тип v o id используется для определения функции, не возвращающей никаких зна­ чений, либо для создания обобщ енного указателя (generic pointer). Оба эти случая мы рассмотрим в следующих главах.

I—J Модификация основных типов За исключением типа v o i d, основные типы данных могут иметь различные модифи­ каторы (modifiers), которые используются для более точной настройки. Вот их список.

Целочисленные типы можно модифицировать с помощью ключевых слов s i g n e d, s h o r t, lo n g и u n s i g n e d. Символьные типы можно уточнять с помощью модифика­ торов u n s i g n e d и s i g n e d. Кроме того, тип d o u b l e можно модифицировать ключе­ вым словом lo n g. В табл. 2.1 указаны все возможные комбинации типов данных, а также их минимальные диапазоны и приблизительный размер в битах. (Эти значе­ ния относятся также и к языку C + +.) Учтите, что в этой таблице приведены мини­ мальные диапазоны переменных, а не типичные. Например, в компьютерах, исполь­ зующих арифметику дополнительных кодов (two's complement arithmetic), минималь­ ный диапазон целого числа простирается от — 32768 до 32767.

Применение модификатора s i g n e d допускается но является излишним, поскольку по умолчанию все целые числа имеют знак. Наиболее важен этот модификатор при уточне­ нии типа c h a r в тех реализациях языка С, где тип c h a r по умолчанию знака не имеет.

Разница между целыми числами, имеющими и не имеющими знак заключается в интерпретации бита в старшем разряде. Если в программе определено целое число со знаком, то компилятор генерирует код, в котором старший бит интерпретируется как признак знака (sign flag). Если признак знака равен 0, число считается положи­ тельным, если он равен I — отрицательным.

Глава 2. Выражения Иначе говоря, отрицательные числа представляются с помощью дополнительного кода (two's complement), в котором все биты числа (за исключением старшего разряда) инвертированы, затем к полученному числу добавляется единица, а признак знака ус­ танавливается равным I.

Целые числа со знаком играют весьма важную роль в очень многих алгоритмах, но диапазон их изменения вдвое короче, чем у целых чисел, не имеющих знака. Рас­ смотрим двоичное представление числа 32767.

|о Допустим, старший бит равен I, значит, это число станет равным —1. Однако, если бы эта переменная была объявлена как u n s i g n e d i n t, ее значение стало бы равным 65535.

Если модификатор типа используется отдельно (т.е. без указания элементарного типа), по умолчанию предполагается, что объявляемая переменная имеет тип i n t.

Итак, указанные ниже спецификаторы типов эквивалентны.

Хотя одного спецификатора i n t вполне достаточно, многие программисты пред­ почитают явно указывать его модификации.

Идентификаторы В язы ке C /C + + имена переменных, ф ункций, меток и других объектов, опреде­ ленных пользователем, называются идентификаторами (indentifiers). Идентификаторы могут состоять из одного или нескольких символов. Первый символ идентификатора должен быть буквой или символом подчеркивания, а следующие символы должны быть буквами, цифрами или символами подчеркивания. Ниже приведены примеры правильных и неправильных идентификаторов.

В языке С длина идентификаторов может быть произвольной. Однако не все сим ­ волы, образующие идентификатор, считаются значащими. Если идентификатор ис­ пользуется в процессе редактирования внеш них связей, то значащими считаются, по крайней мере, шесть его первых символов. Эти идентификаторы называются внешни­ ми именами (external names). К ним относятся имена функций и глобальных перемен­ ных, используемых несколькими файлами. Если идентификатор не используется в про­ цессе редактирования внешних связей, то значащими считаются, по крайней мере, 31 первый символ. Такие идентификаторы называются внутренними именами (internal names). К ним относятся, например, имена локальных переменных. В языке C + + нет ограничений на длину идентификаторов и значащими считаются, по крайней мере, первых символа. При переходе от языка с к языку C + + этот нюанс следует учитывать.

Символы, набранные в верхнем и нижнем регистре, различаются. Следовательно, c o u n t, C o u n t и COUNT — это разные идентификаторы.

Ключевые слова нельзя использовать в качестве идентификаторов ни в языке С, ни в языке C + +. Кроме того, идентификаторы не должны совпадать с именами функций из стандартных библиотек.

— Переменные Переменная (variable) представляет собой имя ячейки памяти, которую можно использо­ вать для хранения модифицируемого значения. Все переменные должны быть объяв­ лены до своего использования. Ниже приведен общий вид объявления переменной.

тип список переменных;

Здесь слово тип означает один из допустимых типов данных, включая модификаторы, а списокпеременных может состоять из одного или нескольких идентификаторов, раз­ деленных запятыми. Рассмотрим несколько примеров объявлений.

int i,j,1;

Ishort int si;

unsigned int ui;

double balance, profit, loss;

Учтите, в язы ке C /C + + имя переменной никак не связано с ее типом.

Где объявляются переменные Как правило, переменные объявляют в трех местах: внутри функций, в определе­ нии параметров функции и за пределами всех функций. Соответственно такие пере­ менные называются локальными, формальными параметрами и глобальными.

Локальные переменные Переменные, объявленные внутри ф ункции, называются локальными (local variables). В некоторых книгах, посвященных язы ку C /C + +, эти переменные называ­ ются автоматическими (automatic variables). В нашей книге мы будем придерживаться более общей терминологии и называть их локальными. Локальные переменные мож­ но использовать только в операторах, расположенных внутри блока, где они объявле­ ны. Иначе говоря, локальные переменные невидимы снаружи их блока. Напомним, что блок ограничен открывающей и закрывающей фигурными скобками.

Чаще всего локальны е переменны е объявляю тся внутри функций. Рассмотрим void f u n d (void) два примера.

void func2 (void) Переменная х объявлена дважды: сначала — в функции f i n c l O, а затем — в ф унк­ ции f u n c 2 ( ). Переменная х из функции f u n d О не имеет никакого отношения Глава 2. Выражения к переменной х, объявленной внутри функции f u n c 2 ( ). Каждая из этих переменных существует только внутри блока, где она была объявлена.

Язык С содержит ключевое слово a u t o, которое можно использовать для объявле­ ния локальных переменных. Однако, поскольку все локальные переменные по умол­ чанию считаются автоматическими, это ключевое слово на практике никогда не ис­ пользуется. По этой причине в нашем справочнике мы также не будем его применять.

(Говорят, что ключевое слово a u t o было включено в язы к С для обеспечения совмес­ тимости с его предшественником — языком В. Затем это слово перекочевало в язы к C + + для обеспечения совместимости с языком С.) Из соображений удобства и по традиции большинство программистов объявляют все переменные, используемые в функции, сразу после открывающей фигурной скобки и перед всеми остальными операторами. Однако следует иметь в виду, что локальные переменные можно объявлять в любом месте блока. Рассмотрим следующий пример.

void f(void) char s[80]; /* Эта переменная создается только p r i n t f ("Введите и м я :");

gets(s);

В этом фрагменте локальная переменная s создается при входе в блок i f и разруша­ ется сразу после выхода из него. Кроме того, переменная s является видимой только внутри блока i f, и к ней невозможно обратиться извне, даже из других частей функ­ ции, содержащей данны й блок.

Объявление переменных внутри блоков позволяет избежать побочных эффектов.

Поскольку локальная переменная вне блока не существует, ее значение невозможно изменить непреднамеренно.

Способы объявления локальных переменных в языке С (в соответствии со стан­ дартом С89) и в языке C + + существенно отличаются друг от друга. В языке С все ло­ кальные переменные должны быть объявлены в начале блока до выполнения какихлибо “активных” операторов. Например, попытка объявить локальные переменные так, как показано в приведенном ниже фрагменте, вызовет ошибку.

/* Если эта функция является частью программы на языке С, при компиляции возникнет ошибка. Если эта функция представляет собой часть программы на языке C++, void f(void) int j; /* Этот оператор порождает ошибку */ Между тем, в язы ке C + + эта ф ункция считается абсолютно правильной, по­ скольку в этом язы ке локальны е перем енны е можно объявлять в любом месте бло­ ка, но до их первого использования. (Более подробно эта тема будет рассматривать­ ся во второй части книги.) И нтересно, что стандарт С99 также позволяет объявлять локальны е переменны е где угодно.

Поскольку локальная переменная создается при входе в блок, где она объявлена, и разрушается при выходе из него, ее значение теряется. Это особенно важно учиты­ вать при вызове функции. Локальные переменные функции создаются при ее вызове и уничтожаются при возврате управления в вызывающий модуль. Это значит, что ме­ жду двумя вызовами функции значения ее локальных переменных не сохраняются.

(Заставить их сохранять свои значения можно с помощью модификатора s t a t i c. ) По умолчанию локальные переменные хранятся в стеке. Поскольку стек является динамической структурой, и объем занимаемой им памяти постоянно изменяется, становится понятны м, почему локальные переменные в принципе не могут сохранять свои значения между двумя вызовами функции, внутри которой они объявлены.

Локальную переменную можно проинипиализировать неким значением. Оно будет присваиваться переменной каждый раз при входе в блок. Рассмотрим в качестве при­ мера программу, которая десять раз выводит на печать число 10.

#include void f(void);

int main(void) Здесь переменной у присваивается значение 100. Если бы значение переменной х бы­ ло меньше 9, то переменная у стала бы равно 200. Тот же самый код можно записать с помощью оператора i f - e l s e.

| х = 10;

Глава 2. Выражения Более подробно оператор “ ? ” обсуждается в главе 3, в которой рассматриваются другие условные операторы.

Операторы взятия адреса и разыменования Указатель (pointer value) — это переменная, объявленная особым образом, в кото­ рой хранится адрес объекта определенного типа. М ожно выделить три основные об­ ласти применения указателей в языке C /C + +. Во-первых, с их помощью легко индек­ сировать элементы массивов. Во-вторых, они позволяют функциям модифицировать свои параметры. И, в-третьих, на основе указателей можно создавать связанные спи­ ски и другие динамические структуры данных. Подробнее указатели описываются в главе 5, а пока мы изучим два оператора, позволяющих ими манипулировать.

Первый из них — унарный оператор взятия адреса &, возвращающий адрес своего операнда. (Унарным называется оператор, имеющий только один операнд.) Н апри­ мер, оператор | m = & count;

помещает в переменную m адрес переменной c o u n t. Этот адрес относится к ячейке памяти, в которой находится переменная c o u n t, и никак не связан с ее значением.

Выражение & c o u n t можно перевести как “адрес переменной c o u n t ”. Таким образом, оператор присваивания, приведенный выше, означает: “ Присвоить переменной m ад­ рес переменной c o u n t ”.

Чтобы лучше понять, что при этом происходит, допустим, что переменная c o u n t расположена в ячейке с адресом 2000, а ее значение равно 100. Тогда в предыдущем примере переменной m будет присвоено число 2000.

Второй оператор — оператор разыменования указателя *, являющийся противопо­ ложностью оператора &. Этот унарный оператор возвращает значение объекта, распо­ ложенного по указанному адресу. Например, если переменная m содержит адрес пере­ менной c o u t, то оператор | q = *ш;

присвоит значение переменной c o u n t переменной q. Теперь значение переменной q будет равно 100, поскольку именно это число записано в ячейке, в которой хранится переменная т. Оператор разыменования указателя * можно перевести как “значение, хранящееся по адресу”. Ф рагмент программы, показанный выше, читается следую­ щим образом: “ присвоить переменной q значение, хранящееся по адресу т ”. К сожа­ лению, символ оператора разыменования указателя совпадает с символом операции умножения, а символ оператора взятия адреса — с символом оператора побитового И.

Эти операторы никак не связаны друг с другом. Приоритет операторов разыменова­ ния указателя * и взятия адреса & выше, чем приоритет любого арифметического опе­ ратора, за исключением унарного минуса, имеющего такой же приоритет.

В объявлении между именем типа и именем указателя ставится символ *. Он со­ общает компилятору, что объявляемая переменная является указателем на перемен­ ную заданного типа. Например, объявление указателя на переменную типа c h a r за­ писывается следующим образом:

В оригинале автор использует несколько иную терминологию, называя указателем адрес переменной, а то, что мы называем указателем, — переменной-указателем. Как нам кажется, это не вполне соответствует как нормам литературного языка, так и традициям, установившим­ ся в русскоязычной литературе по программированию. — Прим. ред.

Обратите внимание на то, что переменная c h в данном фрагменте программы является указателем на переменную типа c h a r, а не символьной переменной. Именно в этом за­ ключается их принципиальное различие. Тип переменной, на которую ссылается указатель (в данном случае тип c h a r), называется базовым типом указателя. Сам указатель представ­ ляет собой переменную, в которой хранится адрес объекта базового типа. Таким образом, указатель на символьную переменную (как и любой другой указатель) должен иметь доста­ точный размер, чтобы хранить любой адрес в соответствии с архитектурой компьютера.

Однако, как правило, указатели ссылаются только на объекты своего базового типа.

В одном объявлении можно смешивать и указатели, и обычные переменные. На­ пример, оператор | int х, *у, count;

объявляет целочисленные переменные х и c o u n t вместе с указателем у, ссылающим­ ся на целочисленные переменные.

В следующей программе операторы * и & используются для записи значения в переменную t a r g e t. В результате на экран выводится число 10.

#include int main(void) int target, source;

source = 10;

m = &source;

target = *m;

return 0;

Статический оператор sizeof Статический унарный оператор s i z e o f вычисляет длину операнда в байтах. Опе­ рандом может быть как отдельная переменная, так и имя типа, заключенное в скобки.

Предположим, что размер типа i n t равен 4 байт, а типа d o u b le — 8 байт. В этом случае следующий фрагмент программы выведет на экран числа 8 4.

double f ;

Iprintf("%d ", sizeof f );

printf("%d ", siz e o f (int));

Следует помнить, что для вычисления размера типа его имя должно быть заключе­ но в скобки. Имя переменной в скобки заключать не обязательно, хотя и вреда от этого не будет.

С помощью оператора переопределения типа t y p e d e f в языке C /C + + выделен специальный тип s i z e _ t, отдаленно напоминающ ий целое число без знака. С ф ор­ мальной точки зрения результат оператора s i z e o f имеет тип s i z e _ t, но на практике его можно считать целым числом без знака.

Оператор s i z e o f позволяет создавать машинонезависимые программы, в которых автоматически учитываются размеры встроенных типов. В качестве примера рассмотрим базу данных, каждая запись которой состоит из шести целых чисел. Если такую базу не­ обходимо реализовать на разных компьютерах, нельзя надеяться, что размер целочис­ Глава 2. Выражения ленного типа везде будет одинаков. Фактическую длину типа следует определить с помо­ щью оператора s i z e o f. Таким образом, программа должна иметь примерно такой вид.

/* Запись 6 целых чисел в файл. */ void put_rec(int rec[6], FILE *fp) len = fwrite(rec, s i z e o f (i n t )*6, 1, fp);

if(len != 1) p r i n t f ("Ошибка при записи");

Функция p u t _ r e c ( ) правильно компилируется и выполняется в любой средс, в том числе на 16- и 32-разрядных компьютерах.

В заключение отметим, что оператор s i z e o f выполняется па этапе компиляции, и его результат в программе рассматривается как константа.

Оператор последовательного вычисления Оператор последовательного вычисления (operator comma) связывает в одно целое несколько выражений. Символом этого оператора является запятая. Подразумевается, что левая часть оператора последовательного вычисления всегда имеет тип v o id. Это означает, что значение выражения, стоящего в его правой части, становится значени­ ем всего выражения, разделенного запятыми. Например, оператор сначала присваивает переменной у значение 3, а затем присваивает переменной х значение 4. Скобки здесь необходимы, поскольку приоритет оператора последова­ тельного вычисления меньше, чем приоритет оператора присваивания.

По существу, выполнение оператора последовательного вычисления сводится к выполнению нескольких операторов подряд. Если этот оператор стоит в правой час­ ти оператора присваивания, то его результатом всегда будет результат выражения, стоящего последним в списке.

Оператор последовательного вычисления можно сравнить с союзом “и ” в выраже­ нии “сделай это и это и это’ Оператор доступа к члену структуры и ссылки на член структуры В языке С символы и обозначают операторы доступа к элементам струк­ тур и объединений. Структуры и объединения являются составными типами данных (иногда их еще называют агрегированными), в которых одно имя связывает несколько объектов, (см. главу 7). Оператор доступа к члену структуры (точка) используется для непосредственного обращения к элементу структуры или объединения. Оператор ссылки на член структуры используется для обращения к члену структуры или объе­ динения через указатель. Рассмотрим фрагмент программы.

struct employee int age;

float wage;

} emp;

struct employee *p = &emp; /* Записать адрес структуры emp Для того чтобы присвоить члену w age структуры ешр значение 123.33, нужно выпол­ нить следующий оператор | emp.wage = 123.23;

То же самое можно сделать, использовав указатель на структуру ешр.

| p->wage = 123.23;

Операторы “[]» и “()” Круглые скобки — это оператор, повышающий приоритет операций, заключенных внутри. Квадратные скобки используются для индексации массива (массивы подробно обсуждаются в главе 4). Если в программе определен массив, то значение выражения, заключенного в квадратные скобки, равно индексу элемента массива. Рассмотрим де­ монстрационную программу.

#include char s [80] ;

int main(void) printf("%c”, s [3]);

return 0;

Здесь символ • x 1 сначала присваивается четвертому элементу массива (в языке С элементы всех массивов нумеруются, начиная с нуля), а затем выводится на экран.

Приоритеты операторов Приоритеты всех операторов указаны в табл. 2.8. Обратите внимание на то, что все операторы, за исключением унарных и тернарного, выполняются слева направо.

Унарные операторы и выполняются справа налево.

Таблица 2.8. Приоритеты операторов в языке С Высший и дробная часть была бы потеряна.

6 языке C++ предусмотрены еще несколько операторов приведения типов, Глава 2. Выражения Пробелы и круглые скобки Пробелы и символы табуляции облегчают чтение программ. Например, два сле­ дующих оператора совершенно одинаковы.

Лиш ние скобки не приводят к ошибкам и не замедляют выполнение программ. Одна­ ко они позволяют прояснить точный порядок вычислений. Как вы полагаете, какой из операторов легче понять?

х = y/3-34*temp+127;

|х = (у/3) - (34*temp) + 127;

Составные операторы присваивания В языке C /C + + существуют составные формы оператора присваивания, представ­ ляющ ие собой комбинации оператора присваивания и арифметических операторов.

Например, оператор | X = Х+10;

можно переписать в виде | х += 10;

Оператор “+=” сообщает компилятору, что к старому значению переменной х сле­ дует прибавить число 10.

Оператор присваивания образует составные формы практически со всеми бинар­ ными операторами. Итак, выражение вида переметая = переметая оператор выражение можно переписать следующим образом:

переменная оператор= выражение Например, выражение | х = х-100;

можно переписать как В х -= 100;

Составные формы присваивания широко используются в профессиональных про­ граммах на языке C /C + +. Часто их называют сокращенными операторами присваивания (shorthand assignments), поскольку они более лаконичны.

Полный справочник по Глава Операторы ператор — это часть программы, которую можно выполнить отдельно.3 Иными словами, оператор определяет некое действие. Операторы языка С и C + + разде­ ляются на следующие категории.

• Условные операторы • Операторы перехода • Операторы-выражения К условным (conditional) относятся операторы i f и s w i t c h. (Условные операторы иногда называют операторами ветвления (selection statement).) Операторы цикла (iteration statements) обозначаются ключевыми словами w h i l e, f o r и d o w h i l e. Груп­ па операторов перехода состоит из операторов b r e a k, c o n t i n u e, g o t o и r e t u r n.

М етками служат операторы c a s e, d e f a u l t (они рассматриваются в разделе “Оператор switch”) и собственно метки, которые описываются в разделе “Оператор goto”. Операторы-выражения — это операторы, состоящие из допустимых выражений. Блок пред­ ставляет собой фрагмент текста программы, заключенный в фигурные скобки. Иногда блоки называют составными операторами (compound statements).

В языке C++ есть еще два оператора: блок t r y (для обработки исключи­ тельных ситуаций) и оператор объявления (declaration statement). Они об­ Поскольку во многих операторах результат вычисления зависит от истинности или ложности некоторых проверок, начнем с понятий “ истина” и “лож ь”.

Истинные и ложные значения в языках С и C++ При выполнении многих операторов язы ка C /C + + вычисляются значения услов­ ных выражений, которые имеют истинные или ложные значения. В языке С истин­ ным считается любое ненулевое значение, в том числе отрицательное. Ложное значе­ ние всегда равно нулю. Такое представление истинных и ложных значений позволяет создавать чрезвычайно эффективные программы.

В языке C + + полностью поддерживается описанная выше концепция истинных и ложных значений. Наряду с этим в язы ке C + + используется булев тип данных с именем b o o l, который предусматривает только два значения: t r u e и f a l s e. Как указано в главе 2, в языке C + + число 0 автоматически преобразовывается в значение f a l s e, а любое ненулевое значение — в значение t r u e. Справедливо и обратное ут­ верждение: значение f a l s e преобразуется в 0, a t r u e — в 1. С формальной точки зрения условное выражение, входящее в условный оператор, имеет тип b o o l. Однако, поскольку любое ненулевое значение преобразуется в значение t r u e, а число 0 — в значение f a l s e, между языками С и C + + в этом отношении нет никакой разницы.

В книгах по языку C++ слово “statement” иногда переводится как “инструкция”. В качестве аргумента приводят утверждение, что слово “оператор” в языке C++ относится к символу опера­ ции, который собственно и называется английским словом “operator”. Не желая оспаривать эту точку зрения, заметим только, что традиционно любая строка программы в русскоязычной литера­ туре по программированию называется оператором. Аналогично, пытаясь разрешить неоднознач­ ность “строка” — “line” и “строка” — “string”, мы будем вынуждены придумать название для символьной строки, например стринг. И так можно продолжать до бесконечности! Нам кажется, что разумнее придерживаться старых добрых правил и руководствоваться контекстом, поскольку перепутать строку программы с символом операции довольно трудно. — Прим. ред.

— I Условные операторы В языке C /C + + предусмотрены два условных оператора: i f и s w itc h. Кроме того, в некоторых ситуациях в качестве альтернативы условному оператору i f можно при­ менять тернарный оператор “ ? ” Оператор if Здесь оператор может состоять из одного или нескольких операторов или отсутство­ вать вовсе (пустой оператор). Раздел e l s e является необязательным.

Если выражение истинно (т.е. не равно нулю), выполняется оператор или блок, указанный в разделе i f, в противном случае выполняется оператор или блок, преду­ смотренный в разделе e l s e. Операторы, указанные в разделах i f или e l s e, являются взаимоисключающими.

В языке С результатом условного выражения является скаляр, т.е. целое число, сим­ вол, указатель или число с плавающей точкой. В языке C + + к этому набору типов до­ бавляется тип b o o l. Число с плавающей точкой редко применяется в качестве результа­ та условного выражения, входящего в условный оператор, поскольку значительно замед­ ляет выполнение программы. (Это объясняется тем, что операции над числами с плавающей точкой выполняются медленнее, чем над целыми числами или символами.) Проиллюстрируем применение оператора i f с помощью программы, которая представляет собой упрощенную версию игры “угадай волшебное число”. Если игрок выбрал задуманное число, программа выводит на экран сообщение **Верно**.

"Волшебное число” генерируется с помощью стандартного датчика псевдослучайных чисел r a n d ( ), возвращающего произвольное число, лежащее в диапазоне от 0 до r a n d _ m a x. Как правило, это число не превышает 32767. Функция r a n d О объявлена в заголовочном файле s t d l i b ( ).

Глава 3. Операторы Следующая версия программы иллюстрирует применение оператора e l s e в случае, если игрок ошибся.

Вложенные операторы if Вложенным (nested) называется оператор i f, который находится внутри другого оператора i f или e l s e. Вложенные операторы i f встречаются довольно часто. Во вложенном условном операторе раздел e l s e всегда связан с ближайшим оператором i f, находящимся с ним в одном блоке и не связанным с другим оператором e l s e.

Рассмотрим пример.

i f (i> Последний раздел e l s e связан не с оператором i f ( j ), который находится в дру­ гом блоке, а с оператором i f ( i ). Внутренний раздел e l s e связан с оператором i f ( к ), потому что этот оператор i f является ближайшим Я з ы к С допускает до 15 уровней вложенности условных операторов. На практике многие компиляторы предусматривают намного большую глубину. Гораздо важнее, что язы к C + + допускает до 256 уровней вложения. Однако на практике глубоко вло­ женные условные операторы используются крайне редко, поскольку это значительно усложняет логику программы.

Используем вложенные операторы i f для модификации нашей программы.

magic = rand(); /* Генерируем волшебное число */ Цепочка операторов if-then-else В программах на язы ке C /C + + часто используется конструкция, которая называет­ ся цепочка i f - t h e n - e l s e (if-then-alse ladder), или лестница i f - t h e n - e l s e (if-thenelse staircase). Обший вид этой конструкции выглядит так.

Эти условия вычисляются сверху вниз. Как только значение условного выражения становится истинным, выполняется связанный с ним оператор, и оставшаяся часть конструкции игнорируется. Если все условные выражения оказались ложными, вы­ полняется оператор, указанный в последнем разделе e l s e. Если этого раздела нет, то не выполняется ни один оператор.

Поскольку по мере увеличения глубины вложенности количество отступов в строке возрастает, лестницу i f - t h e n - e l s e часто записывают иначе операт ор;

Глава 3. Операторы “ волшебного числа” можно переписать следующим образом.

Тернарная альтернатива вид заменяемых операторов i f - e l s e выглядит следующим образом.

i f {условие) выражение;

e l s e выражение'.

О днако в данном случае с операторам и i f и e l s e связаны отдельные вы раж е­ н и я, а не операторы.

О ператор “ ? ” назы вается тернарным, поскольку имеет три операнда. Его об­ щ ий вид таков.

Выражение 1? Выражение2: ВыражениеЗ Обратите внимание на использование и местоположение двоеточия.

Оператор “ ? ” выполняется следующим образом. Сначала вычисляется Выражение1.

Если оно является истинным, вычисляется Выражение2, и его значение становится значением всего тернарного оператора. Если Выражение1 является ложным, вычисля­ ется ВыражениеЗ, и результатом выполнения тернарного оператора считается именно его значение. Рассмотрим пример.

В данном случае переменной у присваивается значение 100. Если бы переменная х была меньше 9, то переменная у получила бы значение 200 Этот код можно перепи­ сать с помощью операторов i f - e l s e.

В следующем примере оператор “ ? ” используется для “ возведения в квадрат с со­ хранением знака” числа, введенного пользователем. Эта программа учитывает знак исходного числа следующим образом: например, 10 в квадрате равно 100, а — в квадрате равно —100.

Тернарный оператор можно использовать вместо конструкции i f - e l s e не только для присвоения значений. Как известно, все функции возвращают какое-либо значе­ ние (кроме функций, возвращающих значение типа v o id ). Следовательно, вместо вы­ ражений в операторе можно использовать вызовы функций. Если в операторе “ ? ” встречается имя функции, она вызывается, а ее результат используется вместо значе­ ния соответствующего выражения. Это означает, что, используя вызовы функций в качестве операндов тернарного оператора, можно выполнить одну или несколько функций сразу. Рассмотрим пример.

/ * Вывод соответствующего сообщения * / Глава 3. Операторы Если в программу введен нуль, вызывается функция p r i n t f ( ), и на экране появ­ ляется сообщение "Введен нуль”. Если введено любое другое число, выполняются обе функции f l ( ) и f 2 ( ). Обратите внимание на то, что результат оператора “ ? ” в дан­ ной программе игнорируется и не присваивается ни одной переменной.

Учтите, компилятор языка C + +, стремясь оптимизировать объектный код, может произвольно менять порядок вычисления выражений. В таком случае очередность вы­ зовов функций f i ( ) и f 2 ( ) в операторе “? ” остается неизвестной.

Используя тернарный оператор, можно еще раз переписать программу для угады­ вания “ волшебного числа”.

В этой программе оператор “ ? ” в зависимости от результата проверки выводит на экран соответствующие сообщения.

Условное выражение Иногда начинающих программистов на языке C /C + + приводит в смятение тот факт, что в качестве условных выражений в операторах i f или “? ” можно использовать лю­ бые допустимые выражения. Иначе говоря, условное выражение не обязано состоять из операторов сравнения или логических операторов, как в языках BASIC и Pascal. Значе­ нием выражения может быть любое число, которое в зависимости от своего значения интерпретируется как “истина” или “лож ь”. Например, приведенный ниже фрагмент программы считывает с клавиатуры два целых числа и выводит на экран их частное.

ttinclude < s t d io.h > Если число Ь равно нулю, то условие оператора i f является ложным, и выполняется оператор e l s e. В противном случае условие является истинным, и выполняется деление.

Оператор i f можно было бы записать иначе.

| if(b != 0) p r i n t f ("%d\n", a/b) ;

Однако следует заметить, что последняя запись избыточна, может снизить эф ф ектив­ ность вычислений и поэтому считается признаком плохого стиля программирования.

Для проверки условия оператора i f достаточно значения самой переменной Ь и нет никакой необходимости сравнивать ее с нулем.

Оператор switch В языке C /C + + предусмотрен оператор многовариантного ветвления s w itc h, ко­ торый последовательно сравнивает значение выражения со списком целых чисел или символьных констант. Если обнаруживается совпадение, выполняется оператор, свя­ занный с соответствующей константой. Оператор s w itc h имеет следующий вид.

s w itc h (выражение) последовательность операторов c a s e константа2\ последовательность операторов c a s e константаЗ:

последовательность операторов последовательность операторов Значением выражения должен быть символ или целое число. Например, выражения, ре­ зультатом которых является число с плавающей точкой, не допускаются. Значение выра­ жения последовательно сравнивается с константами, указанными в операторах c a se. Если обнаруживается совпадение, выполняется последовательность операторов, связанных с данным оператором c a s e, пока не встретится оператор b r e a k или не будет достигнут ко­ нец оператора s w itc h. Если значение выражения не совпадает ни с одной из констант, выполняется оператор d e f a u l t. Этот раздел оператора s w itc h является необязательным.

Если он не предусмотрен, в отсутствие совпадений не будет выполнен ни один оператор.

В языке С оператор s w i tc h допускает до 257 операторов c a se ! Стандарт языка C + + предусматривает до 16384 операторов c a s e ! Н а практике количество разделов c a s e в операторе s w i t c h следует ограничивать, поскольку оно влияет на эф ф ектив­ ность программы. Несмотря на то что оператор c a s e является меткой, он использует­ ся только внутри оператора s w itc h.

Глава 3. Операторы Оператор b r e a k относится к группе операторов перехода. Его можно использовать как в операторе s w itc h, так и в циклах (см. раздел “Операторы циклов”). Когда по­ ток управления достигает оператора b r e a k, программа выполняет переход к операто­ ру, следующему за оператором s w itc h.

Следует знать три важных свойства оператора s w itc h.

• Оператор s w itc h отличается от оператора i f тем, что значение его выражения сравнивается исключительно с константами, в то время как в операторе i f можно выполнять какие угодно сравнения или вычислять любые логические выражения.

• Две константы в разных разделах c a s e не могут иметь одинаковых значений, за исключением случая, когда один оператор s w itc h вложен в другой.

• Если в операторе s w i t c h используются символьные константы, они автомати­ чески преобразовываются в целочисленные.

Оператор s w itc h часто используется для обработки команд, введенных с клавиа­ туры, например, при выборе пунктов меню. В приведенном ниже примере функция menu () выводит на экран меню программы для проверки правописания и вызывает соответствующие процедуры.

v o id m enu(void) p r i n t f ("Для пропуска нажмите любую клавишу\п") ;

С формальной точки зрения наличие оператора b r e a k внутри оператора s w itc h не обязательно. Этот оператор прерывает выполнение последовательности операторов, связанных с соответствующей константой. Если его пропустить, будут выполнены все последующие операторы c a s e, пока не встретится следующий оператор b re a k, либо не будет достигнут конец оператора s w itc h. Например, приведенная ниже функция использует этот эф ф ект для обработки информации, поступающей на вход драйвера.

/ * Обработка значения * / int flag;

case 2 : / * последовательность операторов. * / Этот пример иллюстрирует два свойства оператора s w i t c h. Во-первых, оператор c a s e может не иметь связанной с ним последовательности операторов. В этом случае поток управления просто переходит к следующему оператору c a s e, как бы “проваливаясь” вниз. В нашем примере три первых оператора c a s e связаны с одной и той же последовательностью операторов, а именно:

Ibreak;

Во-вторых, если оператор b r e a k отсутствует, выполняется последовательность операторов, связанная со следующим оператором c a s e. Если значение i равно 4, пе­ ременной f l a g присваивается число 1, и, поскольку оператора b r e a k в конце данного раздела c a s e нет, выполнение оператора s w i t c h продолжается, и вызывается функ­ ция e r r o r ( f l a g ). Если значение i равно 5, функция e r r o r будет вызвана с парамет­ ром f l a g, равным —1, а не 1.

То, что в отсутствие оператора b r e a k операторы c a s e выполняются один за дру­ гим, позволяет избежать ненужного дублирования операторов и повысить эф ф ектив­ ность программы.

Вложенные операторы switch Операторы s w i t c h могут быть вложены друг в друга. Даже если константы разделов c a s e внешнего и внутреннего операторов s w i t c h совпадают, проблемы не возникают.

Например, приведенный ниже фрагмент программы является вполне приемлемым.

Глава 3. Операторы — I Операторы цикла В язы ке C /C + +, как и во всех других современны х язы ках програм м ирова­ ния, ператоры цикла предназначены для вы полнения повторяю щ ихся инструк­ ций, пока действует определенное правило. Это условие может быть как зада­ но арапее (в цикле f o r ), так и меняться во время вы полнения цикла (в операто­ Цикл for В том или ином виде цикл f o r есть во всех процедурных язы ках програм м и­ рования. О днако в язы ке C /C + + он обеспечивает особенно высокую гибкость и ф ф ективность.

Общий вид оператора f o r таков.

(инициализация; условие; приращение) Цикл f o r имеет много вариантов. О днако наиболее общая ф орма этого оператора работает следующим образом. Сначала выполняется инициализация (initialization) — оператор присваивания, который задает начальное значение счетчика цикла. Затем проверяется условие (condition), представляющее собой условное выражение. Цикл выполняется до тех пор, пока значение этого выражения остается истинным. При­ ращение (increm ent) изменяет значение счетчика цикла при очередном его вы полне­ нии. Эти разделы оператора отделяются друг от друга точкой с запятой. К ак только условие цикла станет лож ным, программа прекратит его выполнение и перейдет к ледующему оператору.

В следующем примере цикл f o r выводит на экран числа от 1 до 100.

char t a r g e t [80] = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";

Глава 3. Операторы p r i n t f (“Результат: % s \n", target);

/* Эта функция копирует одну строку в другую, перемещаясь от концов к середине. */ void converge(char *targ, char *src) for(i=0, j=strlen(src); i-l; t— ) p r i n t f ("%с“, p[t]);

С формальной точки зрения в стандарте языка C + + строковый литерал имеет тип c o n s t c h a r *. Однако в языке C + + предусмотрено автоматическое преобразование втип c h a r *. Таким образом, рассмотренная выше программа является абсолютно правильной.

И все же эта особенность языка считается нежелательной, поэтому это преобразование не следует применять. Создавая новые программы, строковые литералы необходимо действи­ тельно считать константами, а объявление указателя р записывать следующим образом.

| const char *р = “Здравствуйте";

Ш Указатели на функции Особенно малопонятным, хотя и действенным механизмом языка C++ являются ука­ затели на функции (function pointer). Несмотря на то что функция не является переменной, она располагается в памяти, и, следовательно, ее адрес можно присваивать указателю. Этот адрес считается точкой входа в функцию. Именно он используется при ее вызове. По­ скольку указатель может ссылаться на функцию, ее можно вызывать с помощью этого ука­ зателя. Это позволяет также передавать функции другим функциям в качестве аргументов.

Адрес функции задается ее именем, указанным без скобок и аргументов. Чтобы разобраться в этом механизме, рассмотрим следующую программу.

#include |#include 'лава 5. Указатели void check(char *a, char *b, int (*cmp)(const char *, const char *));

int main(void) char si [80], s2 [80];

int (*p)(const char *, const char *);

void check(char *a, char *b, int (*cmp)(const char *, const char *)) i f (!(*cmp)(a, b ) ) p r i n t f (“Равны");

При вызове функция c h e c k ( ) получает два указателя на символьные переменные и указатель на функцию. Соответствующие аргументы объявлены в ее заголовке. Об­ ратите внимание на то, как объявлен указатель на функцию. Эту форму объявления следует применять для любых указателей на функции, независимо от того, какой тип имеют их аргументы и возвращаемые значения. Объявление * с т р заключено в скобки для того, чтобы компилятор правильно его интерпретировал.

Выражение | (*стр)(а, Ь) внутри функции c h e c k () означает вызов функции s tr c m p O, на которую ссылается указатель с т р, с аргументами а и Ь. Скобки по-прежнему необходимы. Это — один из способов вызвать функцию с помощью указателя. Альтернативный вызов выглядит так:

| стр(а, Ь ) ;

Первый способ применяется чаще, поскольку он позволяет явно продемонстрировать, что функция вызывается через указатель. (Иначе говоря, читатель программы сразу увидит, что переменная с т р является указателем, а не именем функции.) Тем не ме­ нее эти два способа эквивалентны.

Обратите внимание на то, что функцию c h e c k () можно вызвать, непосредственно указав функцию s tr c m p O в качестве ее аргумента.

| check(sl, s 2, strcmp);

В этом случае отпадает необходимость в дополнительном указателе на функцию.

Может возникнуть закономерный вопрос: зачем вызывать функции с помощью указателей? На первый взгляд, это лиш ь усложняет программу, не предлагая взамен никакой компенсации. Тем не менее иногда выгоднее вызывать функции через указа­ тели и даже создавать массивы указателей на функции. Рассмотрим в качестве приме­ ра синтаксический анализатор — составную часть компилятора, вычисляющую выра­ жения. Он часто вызывает различные математические функции (синус, косинус, танЧасть I. Основы языка C++: подмножество С гене и т.д.), средства ввода-вывода или функции доступа к ресурсам системы. Вместо создания большого оператора s w i t c h, в котором пришлось бы перечислять все эти функции, можно создать массив указателей на них. В этом случае к функциям можно было бы обращаться по индексу. Чтобы оценить эффективность такого подхода, рас­ смотрим расширенную версию предыдущей программы. В этом примере функция c h e c k () проверяет на равенство строки, состоящие из букв или цифр. Для этого она просто вызывает разные функции, выполняющие сравнение.

void check(char *a, char *b, int (*cmp)(const char *, const char *));

int numcmp(const char *a, const char * b ) ;

int main(void) char s i [80], s2[80];

if(isalpha(*sl)) void check(char *a, char *b, p r i n t f (“Проверка равенства.\n");

i f (!(*cmp)(a, b ) ) p r i n t f (“Равны");

else printf ("He равны'1);

int numcmp(const char *a, const char *b) if (atoi (a) ==atoi (b) ) return 0 else return 1 -, Если пользователь введет строку, состоящую из букв, функция c h e c k () вызовет функцию s t r c m p O, получив указатель на нее. В противном случае будет передан ука­ затель на функцию numcmp ( ). Итак, в разных ситуациях функция c h e c k () может вы­ зывать разные функции.

—I Функции динамического расспределения памяти Указатели позволяют динамически распределять память в программах на языке C /C + +. Термин динамическое распределение памяти (dynamic allocation) означает, что программа может получать необходимую ей память уже в ходе своего выполнения.

Глава 5. Указатели Как известно, память для глобальных переменных выделяется па этапе компиляции.

Локальные переменные хранятся в стеке. Следовательно, в ходе выполнения про­ граммы невозможно объявить новые глобальные или локальные переменные. И все же иногда в ходе выполнения программы возникает необходимость выделить допол­ нительную память, размер которой заранее не известен. Например, программа может использовать динамические структуры — связанные списки или деревья. Такие струк­ туры данных являются динамическими по своей природе. Они увеличиваются или уменьшаются по мере необходимости. Для того чтобы реализовать такие структуры данных, программа должна иметь возможность распределять и освобождать память.

В языке C + + предусмотрены две системы для динамического распределения па­ мяти: одна унаследована от язы ка С, вторая присуща лиш ь языку C + +. Вторая систе­ ма более совершенна. Ее мы рассмотрим во второй части книги, а пока сосредото­ чимся па системе динамического распределения памяти, предусмотренной языком С.

Память, выделяемая функциями динамического распределения, находится в куче (heap), которая представляет собой область свободной памяти, расположенную между кодом программы, сегментом данных и стеком. Хотя размер кучи заранее не известен, ее объем обычно достаточно велик.

В основе системы динамического распределения памяти в языке С лежат функции m a l l o c () и f r e e ( ) x. (Во многих компиляторах предусмотрены дополнительные функции, позволяющие динамически выделять память, однако эти две — самые важ­ ные.) Эти функции создают и поддерживают список свободной памяти. Функция m a l l o c () выделяет память для объектов, а функция г е е ( ) освобождает ее. Иными словами, при каждом вызове функция m a l l o c () выделяет дополнительный участок памяти, а функция г е е ( ) возвращает его операционной системе. Любая програм­ ма, использующая эти функции, должна включать в себя заголовочный файл s t d l i b. h. (В программах на языке C + + можно также использовать новый стиль за­ головочного файла < c s t d l i b >. ) Прототип функции m a l l o c () имеет следующий вид.

Параметр количество байтов задает размер памяти, которую необходимо выделить (Тип s i z e _ t определен в заголовочном файле s t d l i b. h как целое число без знака.) Функция m a l l o c () возвращает указатель типа v o i d *. Это означает, что его можно присваивать указателю любого типа. В случае успеха функция m a l l o c ( ) возвращает указатель на первый байт памяти, выделенной в куче. Если размера кучи недостаточ­ но для успешного выделения памяти, функция m a llo c () возвращает нулевой указатель.

В приведенном ниже ф рагм енте программы выделяется 1000 байт непреры в­ ной памяти.

char *р;

После выполнения оператора присваивания указатель р ссылается на первый из байт выделенной памяти.

Обратите внимание на то, что в предыдущем примере указатель, возвращаемый функцией m a l l o c ( ), присваивается указателю р без приведения типа. В языке С это допускается, поскольку указатель типа v o i d * автоматически преобразовывается в тип указателя, стоящего в левой части оператора присваивания. Однако следует иметь в виду, что в языке C + + это правило не действует. Следовательно, в программах на языке C + + при присваивании указателя типа v o id * указателю другого типа необхо­ димо выполнять явное приведение:

|р = (char *) m a l l o c (1000);

В принципе, это правило распространяется на любое присваивание или преобра­ зование указателей. В этом заключается одно из принципиальных различий между языками С и C + +.

В следующем примере выделяется память для 50 целых чисел. Обратите внимание на то, что применение оператора s i z e o f гарантирует машинонезависимость этого фрагмента программы.

р = (int *) malloc(50*sizeof(int));

Поскольку размер кучи ограничен, при выделении памяти необходимо проверять указатель, возвращаемый функцией m a l l o c ( ). Если он равен нулю, продолжать вы­ полнение программы опасно. Проиллюстрируем эту мысль следующим примером.

р = (int *) malloc(lOO);

i f (!р> p r i n t f ("Память исчерпана.\п");

Разумеется, если указатель р является нулевым, не обязательно выпрыгивать на хо­ ду — вызов функции e x i t () можно заменить какой-нибудь обработкой возникшей ош ибки и продолжить выполнение программы. Достаточно убедиться, что указатель р больше не равен нулю.

Ф ункция f r e e () является антиподом функции m a l l o c () — она освобождает ра­ нее занятую область динамической памяти. Освобожденную память можно снова ис­ пользовать с помощью повторного вызова функции m a l l o c ( ). Прототип функции f r e e () выглядит следующим образом.

Здесь параметр р является указателем на участок памяти, ранее выделенный функцией m a l l o c O. Принципиально важно то, что функцию f r e e ( ) ни в коем случае нельзя вызывать с неправильным аргументом — это разрушит список свободной памяти.

Проблемы, возникающие при работе с указателями Указатели — головная боль программистов! С одной стороны, они представляют собой чрезвычайно мош ный и необходимый во многих ситуациях механизм. С другой стороны, если указатель содержит непредвиденное значение, обнаружить эту ошибку крайне трудно.

Н еверный указатель трудно найти, поскольку сам по себе он ош ибкой не является.



Pages:     || 2 | 3 | 4 | 5 |


Похожие работы:

«МИНИСТЕРСТВО СЕЛЬСКОГО ХОЗЯЙСТВА РОССИЙСКОЙ ФЕДЕРАЦИИ Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ АГРАРНЫЙ УНИВЕРСИТЕТ УТВЕРЖДАЮ Декан экономического факультета профессор В.И. Гайдук _ 2013 г. РАБОЧАЯ ПРОГРАММА дисциплины Управление карьерой и развитием личности для бакалавров 080200.62 - Менеджмент направления подготовки Производственный менеджмент Факультет Экономический Кафедраразработчик Управления и...»

«МИНИСТЕРСТВО СЕЛЬСКОГО ХОЗЯЙСТВА РОССИЙСКОЙ ФЕДЕРАЦИИ Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ АГРАРНЫЙ УНИВЕРСИТЕТ УТВЕРЖДАЮ Декан факультета агрохимии и почвоведения доцент Лебедовский И. А. _ _2013 г. РАБОЧАЯ ПРОГРАММА дисциплины Экогеохимия ландшафтов для магистров направления подготовки 110100.68 - Агрохимия и агропочвоведение Факультет, на котором проводится обучение Агрохимии и почвоведения Кафедра –...»

«2 ОБЩИЕ ПОЛОЖЕНИЯ Основная образовательная программа послевузовского профессионального образования по специальности 01.02.04. Механика деформируемого твердого тела разработана на основании законодательства Российской Федерации в системе послевузовского профессионального образования, в том числе: Федерального закона РФ от 22.08.1996 № 125-ФЗ О высшем и послевузовском профессиональном образовании, Положения о подготовке научно-педагогических и научных кадров в системе послевузовского...»

«МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ Государственное образовательное учреждение высшего профессионального образования САМАРСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ Факультет _механико-математический (наименование) Кафедра _математического моделирования в механике (наименование) УТВЕРЖДАЮ Проректор по учебной работе В.П. Гарькин _ 2011 г. РАБОЧАЯ ПРОГРАММА ДИСЦИПЛИНЫ Вычислительный эксперимент в аэромеханике Профессиональная образовательная программа специальности 010800 Механика и...»

«Министерство образования и науки Российской Федерации федеральное государственное бюджетное образовательное учреждение высшего профессионального образования Оренбургский государственный педагогический университет Институт естествознания и экономики Кафедра менеджмента и методики преподавания экономических дисциплин УТВЕРЖДАЮ Ректор _ С.А. Алешина _ 2012 г. Основная образовательная программа высшего профессионального образования Направление подготовки (специальность) 100100 Сервис Профиль...»

«Минобрнауки России Филиал государственного образовательного учреждения высшего профессионального образования Вятского государственного гуманитарного университета в г. Кирово-Чепецке Кафедра экономики и управления УТВЕРЖДАЮ зав. кафедрой Федяева И.Ю. 30.11.2011 УЧЕБНО-МЕТОДИЧЕСКИЙ КОМПЛЕКС учебной дисциплины История социально-политических учений для специальности: 080507.65 Менеджмент организации Кирово-Чепецк Учебно-методический комплекс составлен в соответствии с ГОС высшего профессионального...»

«ПОЛОЖЕНИЕ О НАУЧНО-ИССЛЕДОВАТЕЛЬСКОЙ ДЕЯТЕЛЬНОСТИ ИНСТИТУТА Положение разработано в соответствии с Федеральным законом Российской Федерации от 29 декабря 2012 года № 273-ФЗ Об образовании в Российской Федерации (далее ФЗ № 273 - ФЗ), Федеральным законом Российской Федерации от 23 августа 1996 года № 127-ФЗ О науке и научно-технической политике (далее № 127-ФЗ), приказами и распоряжениями ректора вуза, решениями Ученого Совета вуза, другими локальными нормативными актами. Данное положение...»

«Московский Государственный Университет имени М.В. Ломоносова Философский факультет Кафедра Философии образования КОНЦЕПЦИИ СОВРЕМЕННОГО ЕСТЕСТВОЗНАНИЯ Программа курса для студентов факультета Высшая школа переводов МГУ имени М.В.Ломоносова Составитель: доц. Брызгалина Елена Владимировна Москва 2010 год Цель данной программы состоит в том, чтобы помочь студентам освоить содержание курса Концепции современного естествознания, посвященного важной сфере жизни современного общества науке. Данный...»

«МИНИСТЕРСТВО СЕЛЬСКОГО ХОЗЯЙСТВА РОССИЙСКОЙ ФЕДЕРАЦИИ Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования КУБАНСКИЙ ГОСУДАРСТВЕННЫЙ АГРАРНЫЙ УНИВЕРСИТЕТ РАБОЧАЯ ПРОГРАММА дисциплины СД.Ф.11 Экономика отрасли для специальности – 270102.65 Промышленное и гражданское строительство факультета инженерно-строительного Ведущая кафедра кафедра строительного производства Вид учебной Дневная форма обучения Заочная форма обучения работы Всего часов Курс,...»

«1. ОБЩИЕ ПОЛОЖЕНИЯ 1.1. Примерная основная образовательная программа высшего профессионального образования (ПООП ВПО) по специальности 190901 Системы обеспечения движения поездов (специализация Автоматика и телемеханика на железнодорожном транспорте) Настоящая примерная основная образовательная программа высшего профессионального образования (ПООП ВПО) разработана в соответствии с федеральным государственным образовательным стандартом высшего профессионального образования (ФГОС ВПО) подготовки...»

«Министерство образования и науки Российской Федерации Федеральное государственное бюджетное образовательное учреждение высшего профессионального образования Амурский государственный университет Кафедра Геологии и природопользования УЧЕБНО-МЕТОДИЧЕСКИЙ КОМПЛЕКС ДИСЦИПЛИНЫ ЭКОНОМИКА И ОРГАНИЗАЦИЯ ГЕОЛОГО-РАЗВЕДОЧНЫХ РАБОТ Основной образовательной программы по направлению подготовки (специальности) 130301.65 Геологическая съемка, поиски и разведка месторождений полезных ископаемых, для очной и...»

«Приложение к образовательной программе основного и среднего общего образования МБОУ Стрелецкая средняя общеобразовательная школа Орловского района Орловской области ОБРАЗОВАТЕЛЬНАЯ ПРОГРАММА ОСНОВНОГО ОБЩЕГО ОБРАЗОВАНИЯ ПО ФИЗИКЕ (7-9) Пояснительная записка Программа по физике составлена на основе Примерной программы основного общего образования по физике 7-9 классы под редакцией В.А.Орлова, О.Ф.Кабардина, В.А.Коровина, авторской программы Физика 7-9классы под редакцией Е.М.Гутник,...»

«НОЯБРЬСКИЙ ИНСТИТУТ НЕФТИ И ГАЗА (филиал) ПРОГРАММА ПОДГОТОВКИ СПЕЦИАЛИСТОВ СРЕДНЕГО ЗВЕНА СРЕДНЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ по специальности 080114 Экономика и бухгалтерский учет (по отраслям) СМК ППССЗ-177-2013 ПРОГРАММА ПОДГОТОВКИ СПЕЦИАЛИСТОВ СРЕДНЕГО ЗВЕНА ПО СПЕЦИАЛЬНОСТИ 080114 ЭКОНОМИКА И БУХГАЛТЕРСКИЙ УЧЕТ (ПО ОТРАСЛЯМ) Квалификация бухгалтер Форма обучения: очная Нормативный срок обучения на базе основного общего образования 2 года 10месяцев Версия 1 Стр.2 из НОЯБРЬСКИЙ ИНСТИТУТ...»

«Пояснительная записка к учебному плану начального общего образования (для 1-3 классов) МКОУ СОШ №6 г. Омутнинска Учебный план МКОУ СОШ №6 начального общего образования (для 1-3 классов), реализующий основную образовательную программу начального общего образования (для 1-3 классов), фиксирует максимальный объём учебной нагрузки обучающихся в 1-3 классах, состав учебных предметов распределяет учебное время, отводимое на освоение содержания образования по классам и учебным предметам. Учебный план...»

«МЕЖВЕДОМСТВЕННЫЙ СЕВЕРО ЗАПАДНЫЙ КООРДИНАЦИОННЫЙ СОВЕТ ПРИ РАН ПО ФУНДАМЕНТАЛЬНЫМ И ПРИКЛАДНЫМ ИССЛЕДОВАНИЯМ Проект Вторая редакция с изменениями 15.11.2008 Официальная версия СТРАТЕГИЯ РАЗВИТИЯ КОМПЛЕКСА НАУКА ОБРАЗОВАНИЕ ИННОВАЦИИ СЕВЕРО ЗАПАДНОГО ФЕДЕРАЛЬНОГО ОКРУГА РОССИИ до 2030 года  ОГЛАВЛЕНИЕ Предисловие 1. Особенности внешней и внутренней среды комплекса НОИ СЗФО 1.1. Внешняя среда 1.2. Характеристика комплекса НОИ СЗФО 2. Видение желаемого состояния комплекса НОИ...»

«САХАЛИНСКАЯ ОБЛАСТНАЯ УНИВЕРСАЛЬНАЯ НАУЧНАЯ БИБЛИОТЕКА Материалы областной научно-практической конференции Южно-Сахалинск 2006 Составитель Е. С. Хоменко Редакторы: В. А. Малышева, Т. А. Козюра Тех. редактор В. В. Мельникова От составителей В сборник включены доклады и сообщения ведущих специалистов СахОУНБ и научной библиотеки СахГУ, библиотечных специалистов из пяти районов области. Составители выражают признательность всем участникам конференции, предоставившим свои материалы для публикации....»

«Программа вступительного испытания (собеседование/устный экзамен) по дисциплине Современные проблемы геологии для поступающих на направление подготовки магистратуры 05.04.01 – Геология Инженерная геология Понятия об инженерно-геологических условиях. Компоненты инженерногеологических условий. Факторы развития геологических и инженерногеологических условий. Категории сложности инженерно-геологических и природных условий. Экологическая роль и функции литосферы. Понятие об инженерногеологических...»

«Вопросы, программа и литература для подготовки к аттестационному испытанию для перевода на 3 курс философского факультета. Направление подготовки – КУЛЬТУРОЛОГИЯ. Вопросы к экзамену 1. Общая характеристика традиционной (первобытной) культуры 2. Культура первых цивилизаций 3. Культура Осевого времени (по работе К.Ясперса Смысл и назначение истории) 4. Культура Древней Греции 5. Культура Древнего Рима 6. Своеобразие культуры эллинизма 7. Раннее христианство и культура Средиземноморья 8. Основные...»

«МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ Государственное образовательное учреждение высшего профессионального образования Новосибирский государственный университет (НГУ) Факультет информационных технологий Утверждаю: Ректор _ 200 г. Номер внутривузовской регистрации Основная образовательная программа высшего профессионального образования Направление подготовки 230100 ИНФОРМАТИКА И ВЫЧИСЛИТЕЛЬНАЯ ТЕХНИКА Магистерская программа Системы мультимедиа и компьютерная графика Квалификация...»

«ПОЛИТИЧЕСКИЕ ПАРТИИ И ПЕРЕХОД К ДЕМОКРАТИИ Начальный курс демократического партийного строительства для лидеров, организаторов и активистов политических партий Национальный демократический институт международных отношений (НДИ) некоммерческая организация, занимающаяся проблемами развития и укрепления демократии во всем мире. Располагая широкой сетью добровольных экспертов, НДИ оказывает помощь общественным и политическим лидерам в утверждении демократических ценностей, демократических форм...»






 
2014 www.av.disus.ru - «Бесплатная электронная библиотека - Авторефераты, Диссертации, Монографии, Программы»

Материалы этого сайта размещены для ознакомления, все права принадлежат их авторам.
Если Вы не согласны с тем, что Ваш материал размещён на этом сайте, пожалуйста, напишите нам, мы в течении 1-2 рабочих дней удалим его.