netlib.narod.ru | < Назад | Оглавление | Далее > |
Давайте напишем программу для подсчета числа появлений каждой из цифр, символов разделителей (пробел, табуляция, новая строка) и всех остальных символов. Конечно, такая задача несколько искусственна, но она позволит нам проиллюстрировать в одной программе сразу несколько аспектов языка Си.
Имеется двенадцать категорий вводимых символов. Для хранения числа появлений каждой из цифр удобнее использовать массив, а не десять отдельных переменных. Вот один из вариантов этой программы:
#inclue <stdio.h> /* Подсчет цифр, символов-разделителей и прочих символов */ main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9' ) ++ndigit[c - '0']; else if (c == ' ' || c == '\n' || c =='\t') ++nwhite; else ++ nother; printf ("Цифры :"); for (i = 0; i < 10; ++i) printf(" %d", ndigit[i]); printf (", символы-разделители : %d", nwhite); printf (", прочие : %d\n", nother); }
В результате выполнения этой программы будет напечатана строка следующего вида:
Цифры : 9 3 0 0 0 0 0 0 0 1, символы-разделители : 123, прочие : 345
Объявление
int ndigit[10];
указывает, что ndigit является массивом из 10 значений типа int. В Си элементы массива всегда нумеруются начиная с нуля, так что элементами объявленного массива будут ndigit[0], ndigit[1], ..., ndigit[9]. Это отражено в циклах for, выполняющих инициализацию и печать массива.
Индекс может быть любым целым выражением, которое может включать целые переменные, такие как i, и целые константы.
Приведенная программа зависит от определенных свойств кодировки цифр. Например, проверка
if (c >='0' && c <='9') ...
определяет, является ли находящийся в переменной c символ цифрой. Если это так, то результат вычисления выражения
c - '0'
равен числовому значению цифры. Данный способ работает только в том случае, если коды символов '0', '1', ..., '9' образуют неразрывную последовательность увеличивающихся значений. К счастью, это верно для всех наборов символов.
Согласно стандарту, значения типа char в арифметических выражениях рассматриваются как значения типа int. Это и естественно и удобно; например, c - '0' является целым выражением с возможными значениями от 0 до 9, которые соответствуют символам от '0' до '9', хранящимся в переменной c. Таким образом, значение данного выражения является правильным индексом для массива ndigit.
Следующий фрагмент программы определяет, является ли символ цифрой, символом разделителем или чем-нибудь иным.
if (c >= '0' && c <='9') ++ndigit[c-'0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother;
Конструкция вида
if (условие1) инструкция1 else if (условие2) инструкция2 . . . else инструкцияn
часто применяется в программе для выбора одного из нескольких альтернативных путей. Условия вычисляются сверху вниз в порядке их появления до тех пор, пока одно из них не окажется истиным, в этом случае будет выполнена соответствующая ему инструкция и работа всей конструкции завершится. (Любая из инструкций может быть группой инструкций в фигурных скобках.) Если ни одно из условий не является истиным, выполняется инструкция, расположенная сразу за последней инструкцией else, если такая имеется. Если же завершающей инструкции else и следующей за ней инструкции нет (как это было в программе подсчета слов), то никакие действия вообще не производятся. Между первым if и завершающим else может быть сколько угодно комбинаций вида
else if (условие) инструкция
Когда таких комбинаций несколько, текст программы лучше форматировать так, как показано в примере. Если вместо этого каждый следующий if сдвигать вправо относительно предыдущего else, то при длинном каскаде проверок текст выйдет за правый край страницы.
Инструкция switch, речь о которой пойдет в главе 3, обеспечивает другой способ реализации множественного ветвления на языке Си. Эта инструкция особенно удобна, когда проверяемое выражение является целым или символьным выражением, совпадающим с одной из некоторого набора констант. Версия этой программы, использующая инструкцию switch, будет для сравнения приведена в разделе 3.4.
Упражнение 1-13 |
Напишите программу, печатающую гистограммы длин вводимых слов. Гистограмму легко рисовать горизонтальными полосами. Рисование вертикальных полос — более трудная задача. |
Упражнение 1-14 |
Напишите программу, печатающую гистограммы частот встречаемости вводимых символов. |
netlib.narod.ru | < Назад | Оглавление | Далее > |