Главная страница
Навигация по странице:

  • Программный код — из Web- пространства

  • Для дальнейшего изучения программирования

  • 7.6. Ключевое слово typedef7.7. Поразрядные операторы7.8. Операторы сдвига7.9. Оператор “знак вопроса” 7.10.

  • ВАЖНО! 7.1. Спецификаторы типа const и volatile

  • Так параметр val // объявляется const-указателем.

  • Спецификатор типа volatile

  • Спецификатор класса памяти auto

  • ВАЖНО! 7.2. Спецификатор класса памяти extern

  • Спецификатор компоновки extern

  • ВАЖНО! 7.3. Статические переменные

  • Локальные static -переменные

  • Справочник по C, Полный справочник по C


    Скачать 393.9 Kb.
    НазваниеСправочник по C, Полный справочник по C
    Анкорaboba
    Дата09.07.2021
    Размер393.9 Kb.
    Формат файлаpdf
    Имя файлаcrukovodstvodlyanachinayushchih.pdf
    ТипСправочник
    #223848
    страница2 из 5
    1   2   3   4   5
    19
    Требуемое программное
    обеспечение
    Чтобы скомпилировать и выполнить программы, приведенные в этой книге, вам понадобится любой из таких современных компиляторов, как Visual C++
    (Microsoft) и C++ Builder (Borland).
    Программный код — из Web-
    пространства
    Помните, что исходный код всех примеров программ и учебных проектов, приведенных в этой книге, можно бесплатно загрузить с Web-сайта по адресу: http://www.osborne.com. Загрузка кода избавит вас от необходимости вво- дить текст программ вручную.
    Для дальнейшего изучения
    программирования
    Книга C#: руководство для начинающих — это ваш “ключ” к серии книг по программированию, написанных Гербертом Шилдтом. Ниже перечислены те из них, которые могут представлять для вас интерес.
    Те, кто желает подробнее изучить язык C++, могут обратиться к следую- щим книгам.
    Полный справочник по C++,
    C++: базовый курс,
    Освой самостоятульно C++,
    STL Programming from the Ground Up,
    Справочник программиста по C/C++.
    Тем, кого интересует программирование на языке Java, мы рекомендуем такие издания.
    Java 2: A Beginner’s Guide,
    Полный справочник по Java 2,
    Java 2: Programmer’s Reference,
    Искусство программировантя на Java.

    20
    Введение
    Если вы желаете научиться программировать на C#, обратитесь к следующим книгам.
    C#: A Beginner’s Guide,
    Полный справочник по C#.
    Тем, кто интересуется Windows-программированием, мы можем предложить такие книги Шилдта.
    Windows 98 Programming from the Ground Up,
    Windows 2000 Programming from the Ground Up,
    MFC Programming from the Ground Up,
    The Windows Annotated Archives.
    Если вы хотите поближе познакомиться с языком C, который является фунда- ментом всех современных языков программирования, обратитесь к следующим книгам.
    Полный справочник по C,
    Освой самостоятельно C.
    Если вам нужны четкие ответы, обращайтесь к Герберту Шилдту, общепризнанно- му авторитету в области программирования.
    От издательства
    Вы, читатель этой книги, и есть главный ее критик и комментатор. Мы ценим ваше мнение и хотим знать, что было сделано нами правильно, что можно было сде- лать лучше и что еще вы хотели бы увидеть изданным нами. Нам интересно услы- шать и любые другие замечания, которые вам хотелось бы высказать в наш адрес.
    Мы ждем ваших комментариев и надеемся на них. Вы можете прислать нам бумажное или электронное письмо, либо просто посетить наш Web-сервер и оставить свои замечания там. Одним словом, любым удобным для вас способом дайте нам знать, нравится или нет вам эта книга, а также выскажите свое мнение о том, как сделать наши книги более интересными для вас.
    Посылая письмо или сообщение, не забудьте указать название книги и ее авто- ров, а также ваш обратный адрес. Мы внимательно ознакомимся с вашим мнением и обязательно учтем его при отборе и подготовке к изданию последующих книг.
    Наши координаты:
    E-mail: info@williamspublishing.com
    WWW: http://www.williamspublishing.com
    Информация для писем из:
    России:
    115419, Москва, а/я 783
    Украины: 03150, Киев, а/я 152

    Модуль
    7
    Еще о типах данных и операторах
    7.1.
    Спецификаторы типа const и volatile
    7.2.
    Спецификатор класса памяти extern
    7.3.
    Статические переменные
    7.4.
    Регистровые переменные
    7.5.
    Перечисления
    7.6.
    Ключевое слово typedef
    7.7.
    Поразрядные операторы
    7.8.
    Операторы сдвига
    7.9.
    Оператор “знак вопроса”
    7.10.
    Оператор “запятая”
    7.11.
    Составные операторы присваивания
    7.12.
    Использование ключевого слова sizeof

    304
    Модуль 7. Еще о типах данных и операторах
    В этом модуле мы возвращаемся к теме типов данных и операторов. Кроме уже рассмотренных нами типов данных, в C++ определены и другие. Одни типы данных состоят из модификаторов, добавляемых к уже известным вам типам.
    Другие включают перечисления, а третьи используют ключевое слово typedef.
    C++ также поддерживает ряд операторов, которые значительно расширяют об- ласть применения языка и позволяют решать задачи программирования в весь- ма широком диапазоне. Речь идет о поразрядных операторах, операторах сдвига, а также операторах “?” и sizeof.
    ВАЖНО!
    7.1.
    Спецификаторы типа const
    и volatile
    В C++ определено два спецификатора типа, которые оказывают влияние на то, каким образом можно получить доступ к переменным или модифицировать их. Это спецификаторы const и volatile. Официально они именуются cv-спецификато-
    рами и должны предшествовать базовому типу при объявлении переменной.
    Спецификатор типа
    const
    Переменные, объявленные с использованием спецификатора const, не могут изменить свои значения во время выполнения программы. Выходит, const-пе- ременную нельзя назвать “настоящей” переменной. Тем не менее ей можно при- своить некоторое начальное значение. Например, при выполнении инструкции const int max_users = 9;
    создается int-переменная max_users, которая содержит значение 9, и это зна- чение программа изменить уже не может. Но саму переменную можно использо- вать в других выражениях.
    Чаще всего спецификатор const используется для создания именованных кон-
    стант. Иногда в программах многократно применяется одно и то же значение для различных целей. Например, в программе необходимо объявить несколько раз- личных массивов таким образом, чтобы все они имели одинаковый размер. Такой общий для всех массивов размер имеет смысл реализовать в виде const-перемен- ной. Затем вместо реального значения можно использовать имя этой переменной, а если это значение придется впоследствии изменить, вы измените его только в одном месте программы (а не в объявлении каждого массива). Такой подход позво- ляет избежать ошибок и упростить программу. Следующий пример предлагает вам попробовать этот вид применения спецификатора const “на вкус”.

    С++: руководство для начинающих
    305
    Еще о типах данных и операторах
    7
    #include using namespace std; const int num_employees = 100; //
    Создаем именованную
    //
    константу num_employees, которая
    //
    содержит значение 100.
    int main()
    { int empNums[num_employees]; //
    Именованная константа
    double salary[num_employees]; //
    num_employees здесь
    char *names[num_employees]; //
    используется для задания
    //
    размеров массивов.
    // ...
    }
    Если в этом примере понадобится использовать новый размер для массивов, вам потребуется изменить только объявление переменной num_employees и перекомпилировать программу. В результате все три массива автоматически по- лучат новый размер.
    Спецификатор const также используется для защиты объекта от модифика- ции посредством указателя. Например, с помощью спецификатора const можно не допустить, чтобы функция изменила значение объекта, адресуемого ее пара- метром-указателем. Для этого достаточно объявить такой параметр-указатель с использованием спецификатора const. Другими словами, если параметр-указа- тель предваряется ключевым словом const, никакая инструкция этой функции не может модифицировать переменную, адресуемую этим параметром. Напри- мер, функция negate() в следующей короткой программе возвращает результат отрицания значения, на которое указывает параметр. Использование специфи- катора const в объявлении параметра не позволяет коду функции модифициро- вать объект, адресуемый этим параметром.
    // Использование const-параметра-указателя.
    #include using namespace std; int negate(const int *val);

    306
    Модуль 7. Еще о типах данных и операторах int main()
    { int result; int v = 10; result = negate(&v); cout << "Результат отрицания " << v << " равен " << result; cout << "\n"; return 0;
    } int negate(const int *val) //
    Так параметр val
    //
    объявляется const-указателем.
    { return - *val;
    }
    Поскольку параметр val является const-указателем, функция negate() не может изменить значение, на которое он указывает. Так как функция negate() не пытается изменить значение, адресуемое параметром val, программа скомпи- лируется и выполнится корректно. Но если функцию negate() переписать так, как показано в следующем примере, компилятор выдаст ошибку.
    // Этот вариант работать не будет! int negate(const int *val)
    {
    *val = - *val; // Ошибка: значение, адресуемое
    // параметром val, изменять нельзя.
    return *val;
    }
    В этом случае программа попытается изменить значение переменной, на кото- рую указывает параметр val, но это не будет реализовано, поскольку val объяв- лен const-параметром.
    Спецификатор const можно также использовать для ссылочных параметров, чтобы не допустить в функции модификацию переменных, на которые ссылают- ся эти параметры. Например, следующая версия функции negate() некоррек- тна, поскольку в ней делается попытка модифицировать переменную, на кото- рую ссылается параметр val.

    С++: руководство для начинающих
    307
    Еще о типах данных и операторах
    7
    // Этот вариант также не будет работать! int negate(const int &val)
    { val = -val; // Ошибка: значение, на которое ссылается
    // параметр val, изменять нельзя.
    return val;
    }
    Спецификатор типа
    volatile
    Спецификатор volatile сообщает компилятору о том, что значение соответству- ющей переменной может быть изменено в программе неявным образом. Например, адрес некоторой глобальной переменной может передаваться управляемой преры- ваниями подпрограмме тактирования, которая обновляет эту переменную с прихо- дом каждого импульса сигнала времени. В такой ситуации содержимое переменной изменяется без использования явно заданных инструкций программы. Существуют веские основания для того, чтобы сообщить компилятору о внешних факторах из- менения переменной. Дело в том, что C++-компилятору разрешается автоматически оптимизировать определенные выражения в предположении, что содержимое той или иной переменной остается неизменным, если оно не находится в левой части инструкции присваивания. Но если некоторые факторы (внешние по отношению к программе) изменят значение этого поля, такое предположение окажется неверным, в результате чего могут возникнуть проблемы. Для решения подобных проблем не- обходимо объявлять такие переменные с ключевым словом volatile.
    volatile int current_users;
    Теперь значение переменной current_users будет опрашиваться при каждом ее использовании.
    Вопросы для текущего контроля
    1. Может ли значение const-переменной быть изменено программой?
    2.
    Как следует объявить переменную, которая может изменить свое значе- ние в результате воздействия внешних факторов?*
    1. Нет, значение const
    -переменной программа изменить не может.
    2. Переменную, которая может изменить свое значение в результате воздействия внешних факторов, нужно объявить с использованием спецификатора volatile.

    308
    Модуль 7. Еще о типах данных и операторах
    Спецификаторы классов памяти
    C++ поддерживает пять спецификаторов классов памяти:
    auto extern register static mutable
    С помощью этих ключевых слов компилятор получает информацию о том, как должна храниться переменная. Спецификатор классов памяти необходимо ука- зывать в начале объявления переменной.
    Спецификатор mutable применяется только к объектам классов, о которых речь впереди. Остальные спецификаторы мы рассмотрим в этом разделе.
    Спецификатор класса памяти
    auto
    Спецификатор auto (достался языку C++ от C “по наследству”) объявляет локальную переменную. Но он используется довольно редко (возможно, вам ни- когда и не доведется применить его), поскольку локальные переменные являют- ся “автоматическими” по умолчанию. Вряд ли вам попадется это ключевое слово и в чужих программах.
    ВАЖНО!
    7.2.
    Спецификатор класса памяти extern
    Все программы, которые мы рассматривали до сих пор, имели довольно скром- ный размер. Реальные же компьютерные программы гораздо больше. По мере уве- личения размера файла, содержащего программу, время компиляции становится иногда раздражающе долгим. В этом случае следует разбить программу на не- сколько отдельных файлов. После этого небольшие изменения, вносимые в один файл, не потребуют перекомпиляции всей программы. При разработке больших проектов такой многофайловый подход может сэкономить существенное время.
    Реализовать этот подход позволяет ключевое слово extern.
    В программах, которые состоят из двух или более файлов, каждый файл должен
    “знать” имена и типы глобальных переменных, используемых программой в целом.
    Однако нельзя просто объявить копии глобальных переменных в каждом файле.
    Дело в том, что в C++ программа может включать только одну копию каждой гло- бальной переменной. Следовательно, если вы попытаетесь объявить необходимые глобальные переменные в каждом файле, возникнут проблемы. Когда компонов- щик попытается объединить эти файлы, он обнаружит дублированные глобальные

    С++: руководство для начинающих
    309
    Еще о типах данных и операторах
    7
    переменные, и компоновка программы не состоится. Чтобы выйти из этого затруд- нительного положения, достаточно объявить все глобальные переменные в одном файле, а в других использовать extern-объявления, как показано на рис. 7.1.
    Файл F1
    Файл F2
    int x, y:
    char ch;
    int main()
    {
    // ...
    }
    void func1()
    {
    x = 123;
    }
    extern int x, y:
    extern char ch;
    void func22()
    {
    x = y/10;
    } void func23()
    {
    y = 10;
    }
    Рис. 7.1. Использование глобальных переменных в от-
    дельно компилируемых модулях
    В файле F1 объявляются и определяются переменные x, y и ch. В файле F2 ис- пользуется скопированный из файла F1 список глобальных переменных, к объ- явлению которых добавлено ключевое слово extern. Спецификатор extern делает переменную известной для модуля, но в действительности не создает ее.
    Другими словами, ключевое слово extern предоставляет компилятору инфор- мацию о типе и имени глобальных переменных, повторно не выделяя для них памяти. Во время компоновки этих двух модулей все ссылки на внешние пере- менные будут определены.
    До сих пор мы не уточняли, в чем состоит различие между объявлением и определением переменной, но здесь это очень важно. При объявлении переменной присваивается имя и тип, а посредством определения для переменной выделяется память. В большинстве случаев объявления переменных одновременно являют- ся определениями. Предварив имя переменной спецификатором extern, можно объявить переменную, не определяя ее.
    Спецификатор компоновки
    extern
    Спецификатор extern позволяет также указать, как та или иная функция связывается с программой (т.е. каким образом функция должна быть обработана

    310
    Модуль 7. Еще о типах данных и операторах компоновщиком). По умолчанию функции компонуются как C++-функции. Но, используя спецификацию компоновки (специальную инструкцию для компилято- ра), можно обеспечить компоновку функций, написанных на других языках про- граммирования. Общий формат спецификатора компоновки выглядит так:
    extern "
    язык" прототип_функции
    Здесь элемент язык означает нужный язык программирования. Например, эта инструкция позволяет скомпоновать функцию myCfunc() как C-функцию.
    extern "C" void myCfunc();
    Все C++-компиляторы поддерживают как C-, так и C++-компоновку. Неко- торые компиляторы также позволяют использовать спецификаторы компоновки для таких языков, как Fortran, Pascal или BASIC. (Эту информацию необходи- мо уточнить в документации, прилагаемой к вашему компилятору.) Используя следующий формат спецификации компоновки, можно задать не одну, а сразу несколько функций.
    extern "
    язык" {
    прототипы_функций
    }
    Спецификации компоновки используются довольно редко, и вам, возможно, никогда не придется их применять.
    ВАЖНО!
    7.3.
    Статические переменные
    Переменные типа static — это переменные “долговременного” хранения, т.е. они хранят свои значения в пределах своей функции или файла. От глобальных они отличаются тем, что за рамками своей функции или файла они неизвестны.
    Поскольку спецификатор static по-разному определяет “судьбу” локальных и глобальных переменных, мы рассмотрим их в отдельности.
    Локальные
    static
    -переменные
    Если к локальной переменной применен модификатор static , то для нее вы- деляется постоянная область памяти практически так же, как и для глобальной переменной. Это позволяет статической переменной поддерживать ее значение между вызовами функций. (Другими словами, в отличие от обычной локальной переменной, значение static-переменной не теряется при выходе из функции.)
    Ключевое различие между статической локальной и глобальной переменными

    С++: руководство для начинающих
    311
    Еще о типах данных и операторах
    7
    состоит в том, что статическая локальная переменная известна только блоку, в котором она объявлена.
    Чтобы объявить статическую переменную, достаточно предварить ее тип клю- чевым словом static. Например, при выполнении этой инструкции переменная count объявляется статической.
    static int count;
    Статической переменной можно присвоить некоторое начальное значение.
    Например, в этой инструкции переменной count присваивается начальное зна- чение 200:
    static int count = 200;
    Локальные static-переменные инициализируются только однажды, в на- чале выполнения программы, а не при каждом входе в функцию, в которой они объявлены.
    Возможность использования статических локальных переменных важна для создания функций, которые должны сохранять их значения между вызовами.
    Если бы статические переменные не были предусмотрены в C++, пришлось бы использовать вместо них глобальные, что открыло бы “лазейку” для всевозмож- ных побочных эффектов.
    Рассмотрим пример использования static-переменной. Она служит для хранения текущего среднего значения от чисел, вводимых пользователем.
    /* Вычисляем текущее среднее значение от чисел, вводимых пользователем.
    */
    #include
    using namespace std;
    int running_avg(int i);
    int main()
    {
    int num;
    do {
    cout << "Введите числа (-1 означает выход): ";
    cin >> num;
    if(num != -1)
    cout << "Текущее среднее равно: "

    1   2   3   4   5


    написать администратору сайта