- •2. Оператор цикла while.
- •Билет 2.
- •Билет 3
- •2. Оператор цикла for
- •Билет 4
- •Билет 5
- •1. Константы
- •1.1 Целые Константы
- •1.3 Символьные Константы
- •1.4 Строки
- •2. Оператор if
- •Билет 6
- •Билет 7
- •1.1 Описания Функций
- •1.2 Определения Функций
- •1.3 Описания
- •2.1.1 Область Видимости
- •2.1.2 Объекты и Адреса (Lvalue)
- •2.1.3 Время Жизни
- •2. Логические операции.
- •Билет 8
- •1. Указатели. Использование указателей при работе с массивами
- •2. Оператор Goto
- •Билет 9
- •2. Указатели и операции над ними.
- •Билет 10
- •Билет 11
- •1. Оператор if
- •2. Строки
- •Билет 12
- •1. Увеличение и уменьшение
- •Билет 13
- •1. Побитовые логические операции
- •2. Функция scanf
- •Билет 14
- •Основные сведения о функциях
- •2. Функции operator new() и operator delete()
- •Билет 15
- •1. Объединения
- •2. Форматный вывод - функция printf
- •Билет 16
- •1. Оператор Выражение
- •2. Области видимости объектов
- •Билет 17
- •1.1 Оператор Return
- •1.2 Оператор Break
- •1.3 Оператор Continue
- •2. Ввод-вывод текстового файла: getc( ), putc( )
- •Билет 18
- •Билет 19
- •1. Аргументы функции main()
- •2. Операции Отношения
- •Билет 20
- •1. Стандартный ввод и вывод - функции getchar и putchar
- •2.1 Оператор typedef
- •Билет 21
- •1. Глобальные переменные
- •2. Открытие файла: fopen( )
- •Закрытие файла: fclose( )
- •Билет 22
- •2. Директивы Препроцессора
- •2.1. Директива #include
- •2.2. Директива #define
- •2.3. Директива #undef
- •Билет 23
- •1. Преобразование типов.
- •2. Операция Запятая
- •Билет 24
- •1. Определение
- •2. Арифметические Преобразования
- •Билет 25
- •Билет 26
- •1. Передача Параметров
- •Билет 27
- •1. Преобразования символов
- •2. Массив и константный указатель
- •Билет 28
- •2. Операции Отношения
- •Билет 29
- •1. Оператор return. Точка вызова и точка возврата
- •Билет 30
- •2. Рекурсивная функция
- •Билет 31
- •2. Функция. Прототип
- •Билет 32
- •2. Генерация случайных чисел
- •Билет 33
- •2. Шаблоны функций и шаблонные функции
Билет 27
1. Преобразования символов
Символ или короткое целое могут использоваться, если может использоваться целое. Во всех случаях значение преобразуется к целому. Преобразование короткого целого к длинному всегда включает в себя знаковое расширение; целые являются величинами со знаком. Содержат символы знаковый разряд или нет, является машинно зависимым, см. #2.6. Более явный тип unsigned char ограничивает изменение значения от 0 до машинно зависимого максимума.
В машинах, где символы рассматриваются как имеющие знак (знаковые), символы множества кода ASCII являются положительными. Однако, символьная константа, заданная восьмеричной escпоследовательностью подвергается знаковому расширению и может стать отрицательным числом; так например, '\377' имеет значение -1.
Когда длинное целое преобразуется в короткое или в char, оно урезается влево; избыточные биты просто теряются.
Некоторые макросы выполняют проверку символов и преобра- зования:
SALPHA(C) не 0, если "C" алфавитный символ, 0 - если нет. SUPPER(C) Не 0, если "C" буква верхнего регистра, 0 - если нет. SLOWER(C) Не 0, если "C" буква нижнего регистра, 0 - если нет. SDIGIT(C) Не 0, если "C" цифра, 0 - если нет. SSPACL(C) Не 0, если "C" пробел, табуляция или новая строка, 0 - если нет. OUPPER(C) Преобразует "C" в букву верхнего регистра. OLOWER(C) Преобразует "C" в букву нижнего регистра.
2. Массив и константный указатель
Несмотря на некоторое сходство с константным указателем, массив является особым типом данных. В этом разделе мы рассмотрим основные отличия массива и константного указателя.
Прежде всего, рассмотрим варианты инициализации указателя:
char * const pcchVal_1 = chArray_2;
char * const pcchVal_2 = new char[5];
char * const pcchVal_3 = (char *) malloc(5*sizeof(char));
Для инициализации последнего константного указателя был использован вызов функции malloc().
Каждый из этих операторов демонстрирует один из трёх возможных способов инициализации константного указателя: непосредственное присвоение значения, использование операции new, вызов функции. Операция new и функции распределения памяти, выделяют соответствующие участки памяти и возвращают начальный адрес выделенной области памяти. Ни один из этих способов не подходит для инициализации массива.
В свою очередь, при определении константных указателей не используются уже известные инициализаторы массивов с явным указанием размерности и списком инициализаторов.
Определим массив и константный указатель на область памяти:
int intArray[5]= {11,22,33,44,55};
int * const pciVal = new int[5];
К константным указателям и массивам применимы одни и те же методы навигации, связанные с использованием операции индексации:
intArray[-25] = 10;
*(intArray + 25) = 10;
pciVal[2] = 100;
*(pciVal + 5) = 100;
А теперь применим операцию sizeof по отношению к проинициализированным указателям:
cout << "pciVal:"<< sizeof(pciVal)<<
" intArray:"<< sizeof(intArray);
Для Borland C++ 4.5, операция sizeof покажет размер области памяти, занимаемой указателем (4 байта) и размер массива (размер элемента * размерность массива)==(10 байт). Операция sizeof различает указатели и имена массивов.
Кроме того, следующий тест также даёт различные результаты.
if (intArray == &intArray)
cout << "Yes, массив." << endl;
else
cout << "No, массив." << endl;
if (pciVal == &pciVal)
cout << "Yes, указатель. " << endl;
else
cout << "No, указатель." << endl;
Результат выполнения:
Yes, массив.
No, указатель.
Значение указателя, представляющего массив, совпадает с адресом первого элемента массива.
Значением указателя, проинициализированного с помощью выражения размещения, является адрес начала этой области. Сам указатель как объект обладает своим собственным адресом.
Интересно, что сравнение значения указателя с результатом выполнения операции взятия адреса не является абсолютно корректным с точки зрения соответствия типов. Операция взятия адреса возвращает лишь определённое значение адреса. И при этом после выполнения этой операции как бы ничего не известно о типе операнда, чей адрес определяли с помощью этой самой операции взятия адреса. Транслятор отслеживает это нарушение принципа соответствия типов и выдаёт предупреждение "Nonportable pointer comparison".
Поскольку это всего лишь предупреждение, выполнение процесса трансляции не прерывается и загрузочный модуль, построенный на основе этого программного кода, корректно выполняется. "Успокоить" транслятор можно с помощью операции явного преобразования типа, которая отключает контроль над типами:
if (intArray == (int *)&intArray)
cout << "Yes";
else
cout << "No";