Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
if (х > 0)
printf("Инкрементирование х:\n"); х + +;
else // здесь возникнет ошибка
printf("х <= 0 \n");
Компилятор трактует оператор printf() как часть оператора if, но оператор х++; — как отдельный оператор, а не часть if. Поэтому компилятор считает, что else не принадлежит if, что является ошибкой. Взамен воспользуйтесь следующей формой:
if (х > 0)
{
printf("Инкрементирование х:\n"); х++;
>
else
printf("х <= 0 \n");
Управляющие операторы С: ветвление и переходы 251
Оператор if позволяет выбрать между выполнением или не выполнением одного действия. Оператор if else позволяет делать выбор между двумя действиями. На рис. 7.1 приведено сравнение этих двух операторов.
Рис. 7.1. Опералюры if u if else
Еще один пример: знакомство
С ФУНКЦИЯМИ getchar() И putchar()
В большинстве рассмотренных до сих пор примеров применялись числовые входные данные. Чтобы попрактиковаться с данными других типов, рассмотрим пример, ориентированный на обработку символов. Вы уже знаете, как использовать функции scanf() и printf() со спецификатором %с для чтения и вывода символов, но в этом примере мы будем иметь дело с парой функций С, специально предназначенных для символьного ввода-вывода — getchar() и putchar().
Функция getchar() не принимает аргументов и возвращает очередной символ из входного потока. Например, показанный далее оператор читает следующий входной символ и присваивает его значение переменной ch:
ch = getchar();
Этот оператор дает тот же самый результат, что и оператор
scanf("%с", &ch);
252 Глава 7
Функция putchar() выводит переданный ей аргумент. Например, следующий оператор выводит в виде символа значение, ранее присвоенное переменной ch:
putchar(ch);
Этот оператор обеспечивает такой же результат, что и оператор
printf ("%с", ch);
Поскольку эти функции работают только с символами, они быстрее и компактнее, чем более универсальные функции scanf() и printf(). Кроме того, обратите внимание, что они не нуждаются в спецификаторах формата, т.к. предназначены для работы только с символами. Обе функции обычно определены в файле stdio.h (Кроме того, они обычно являются макросами препроцессора, а не истинными функции; о функционально-подобных макросах речь пойдет в главе 16.)
Давайте посмотрим, как эти функции работают, написав программу, которая отображает введенную строку, но заменяет каждый отличный от пробела символ следующим за ним символом в последовательности кодов ASCII. Пробелы будут выводиться без изменений. Результат можно сформулировать так: “Если символ является пробелом, он выводится, в противном случае выводится символ, следующий за ним в последовательности кодов ASCII”.
Код программы представлен в листинге 7.2.
Листинг 7.2. Программа cypher1.с
(Пусть вас не беспокоит предупреждение компилятора о возможной потере данных. Все прояснится в главе 8 при рассмотрении последовательности EOF.)
Ниже показан результат выполнения программы:
CALL ME HAL.
DBMM NF IBM/
Сравните этот цикл с циклом из листинга 7.1. В листинге 7.1 для определения момента прекращения цикла применялось возвращаемое значение scanf(), а не значение введенного элемента. Однако в листинге 7.2 для этой цели используется значение самого введенного элемента. Такое отличие в результате приводит к несколько другой структуре цикла, с одним оператором чтения перед циклом и еще одним оператором
Управляющие операторы С: ветвление и переходы 253
чтения в конце цикла. Тем не менее, гибкий синтаксис языка С позволяет эмулировать программу из листинга 7.1 за счет объединения чтения и проверки в одно выражение. То есть цикл следующего вида:
ch = getchar(); /* читать символ */
while (ch != '\n') /* пока не встретится конец строки */
{
... /* обработать символ */
ch = getchar(); /* получить следующий символ */
}
можно заменить таким циклом:
while ((ch = getchar()) != '\n')
{
/* обработать символ */
}
Интерес представляет следующая строка:
while ((ch = getchar()) != '\n')
Она демонстрирует характерный стиль программирования на языке С — объединение двух действий в одно выражение. Возможность свободного форматирования в С помогает сделать отдельные компоненты строки яснее:
while (
(ch = getchar()) // присвоить значение переменной ch
!= '\n') // сравнить ch с \n
Действиями являются присваивание значения переменной ch и ее сравнение с символом новой строки. Круглые скобки, в которые заключено выражение ch = getchar(), делают его левым операндом операции ! =. Чтобы вычислить это выражение, сначала вызывается функция getchar(), после чего возвращаемое ею значение присваивается переменной ch. Поскольку значением выражения присваивания является значение его левого члена, значением ch = getchar() будет как раз новое значение ch. Таким образом, после того как значение для ch прочитано, условие проверки сводится к ch != ‘\n' (т.е. значение ch неравно символу новой строки).
Конструкция подобного рода весьма распространена в программировании на С, поэтому вы должны быть с ней знакомы. Кроме того, не забывайте с помощью круглых скобок правильно группировать подвыражения.
Все скобки обязательны. Предположим, что вы по ошибке записали следующее выражение:
while (ch = getchar() != '\n')
Операция != имеет более высокий приоритет, чем =, следовательно, первым будет вычислено выражение getchar() ! = ‘\n'. Поскольку это условное выражение, оно принимает значение 1 или 0 (истина или ложь). Затем это значение присваивается переменной ch. Отсутствие скобок означает, что ch будет присвоено 0 или 1, а не возвращаемое значение функции getchar(); это совсем не то, что планировалось.
Оператор
putchar(ch + 1); /* изменить другие символы */
еще раз иллюстрирует, что символы хранятся в виде целых чисел. В выражении ch + 1 тип переменной ch расширяется до int для выполнения вычислений, а результирующее значение int nередается в функцию putchar(), которая принимает аргумент типа int, но при отображении символа задействует только последний байт этого значения.
254 глава 7
Семейство функций для работы с символами ctype.h
Обратите внимание, что в выводе программы из листинга 7.2 точка была преобразована в косую черту; причина в том, что в ASCII код символа косой черты на единицу больше, чем код символа точки. Однако если цель программы заключается в преобразовании только букв, было бы неплохо оставлять неизменными все небуквениые символы, а не только пробелы. Логические операции, обсуждаемые позже в главе, предоставляют способ проверки, не является ли символ пробелом, запятой и т.д., но перечислять все возможные варианты было бы довольно утомительно. К счастью, в С имеется стандартный набор функций для анализа символов; их прототипы содержатся в заголовочном файле ctype.h Эти функции принимают символ в качестве аргумента и возвращают ненулевое значение (истина), если символ принадлежит к конкретной категории, и ноль (ложь) в противном случае. Например, функция isalpha() возвращает ненулевое значение, если ее аргумент является буквой. В листинге 7.3 обобщается программа из листинга 7.2 за счет применения этой функции; здесь также задействована только что рассмотренная укороченная структура цикла.
Читать дальшеИнтервал:
Закладка: