Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛЕКЦИИ_ПО_ПРОГРАММИРОВАНИЮ_ПРЕПОД_3403_220301.doc
Скачиваний:
27
Добавлен:
06.11.2018
Размер:
845.31 Кб
Скачать

8.3 Составные операторы.

Составной оператор (блок) представляет собой два или более операторов, объединенных с помощью фигурных скобок.

Сравните между собой фрагменты программ:

ФРАГМЕНТЫ ПРОГРАММ:

/*=============*/

/* фрагмент1 */

index = 0;

while (index ++ < 10) sam = 10 * index + 2;

printf(" sam = %d\n", sam);

/*=============*/

/* фрагмент2*/

index = 0;

while(index ++ < 10)

{/*.---------------------------.begin while */

sam = 10*index + 2;

printf(" sam = %d\n", sam);

}/*.---------------------------.end while */

/*=============*/

ПОЯСНЕНИЯ К ФРАГМЕНТАМ ПРОГРАММ.

  • В фрагменте 1 в цикл while включен только оператор присваивания. При отсутствии фигурных скобок область действия оператора while распространяется от ключевого слова while до следующего символа "точка с запятой". Печать данных будет произведена только один раз - после завершения цикла.

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

  • Обратим внимание на то, как использованы отступы от поля в строках для выделения цикла while. Отступы в строках предназначены для того, чтобы с первого взгляда можно было понять, как устроена программа. Для компилятора отступы в строке не имеют никакого значения; при решении вопроса о том, как интерпретировать инструкции.

***************************************************************

8.4 Преобразование типов.

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

  1. Если операция выполняется над данными двух различных типов, обе величины приводятся к "высшему" из двух типов. Этот процесс называется "повышением" типа.

  2. Последовательность имен типов, упорядоченных от "высшего" к "низшему", выглядит так: double, float, long, int, short и char.

  3. Применение ключевого слова unsigned повышает ранг соответствующего типа данных со знаком.

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

Автоматическое преобразование типов удобно, но может оказаться опасным. Повышение типа обычно происходит гладко, в то время как понижение может привести к затруднениям. Самое лучшее - это вообще избегать преобразования типов особенно в порядке убывания ранга. Причина этого проста: все число целиком может не поместиться в элементе данных низшего типа. Переменная типа char может иметь целое значение 101, но не 22334. Пример, приведенный ниже, иллюстрирует применение этих правил:

/* ПРОГРАММА:

type_transform.c – преобразование типов.

*/

/*#############################################*/

/*============================= include */

#include<stdio.h>

/*============================= main() */

main()

{/*.---------------------------.begin main() */

char ch; /* строка 5 */

int i; /* строка 6 */

float fl; /* строка 7 */

fl = i = ch = 'А'; /* строка 8 */

printf(" ch = %c, i = %d, fl = %2.2f\n", ch, i, fl); /* строка 9 */

ch = ch + 1; /* строка 10 */

i = fl + 2*ch; /* строка 11 */

fl = 2.0*ch + i; /* строка 12 */

printf(" ch = %c, i = %d, fl = %2.2f\n", ch, i, fl); /* строка 13 */

ch = 2.0e30; /* строка 14 */

printf(" Теперь ch = %с \n" , ch); /* строка 15 */

return 0;

}/*.---------------------------.end main() */

/*#############################################*/

РЕЗУЛЬТАТ РАБОТЫ ПРОГРАММЫ.

ch =A, i = 65, fl = 65.00

ch =B, i = 197, fl = 329.00

Теперь ch =

ПОЯСНЕНИЯ К ПРОГРАММЕ.

  • Строка 8: Величина ' А' присваивается символьной переменной ch. Переменная i получает целое значение, являющееся преобразованием символа ' А' в целое число, т. е ' 65'. И, наконец, переменная fl получает значение 65.00, являющееся преобразованием числа 65 в число с плавающей точкой.

  • Строка 9. Печать переменных ch, i, fl.

  • Строка 10: Значение символьной переменной 'А' преобразуется в целое число 65, к которому затем добавляется 1. После этого получившееся в результате число 66 преобразуется в значение символьной переменной 'В'. Значение символьной переменной 'В' присваивается переменной ch.

  • Строка 11. При умножении на 2 значение переменной ch преобразуется в целое число (132). При сложении с величиной переменной fl получившееся в результате число (197) преобразуется в число с плавающей точкой. Результат (197.00) преобразуется в число целого типа (197) и присваивается переменной i.

  • Строка 12. Перед умножением на 2.0 значение переменной ch ('В') преобразуется в число с плавающей точкой (66.00). После умножения получаем 132.00. Перед выполнением сложения величина переменной i (197) преобразуется в число с плавающей точкой (197.00), а результат операции (329.00) присваивается переменной fl.

  • Строка 13. Печать переменных ch, i, fl.

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

  • Строка 15. В итоге переменная ch имеет значение, соответствующее какому-то непечатаемому знаку.

***************************************************************