| 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 | < Назад | Оглавление | Далее > |