А теперь напишем программу, подсчитывающую по отдельности каждую цифру, символы-разделители (пробелы, табуляции и новые-строки) и все другие символы. Это несколько искусственная программа, но она позволит нам в одном примере продемонстрировать еще несколько возможностей языка Си. Имеется двенадцать категорий вводимых символов. Удобно все десять счетчиков цифр хранить в массиве, а не в виде десяти отдельных переменных. Вот один из вариантов этой программы:
>#include ‹stdio.h›
>/* подсчет цифр, символов-разделителей и прочих символов */
>main()
>{
> int с, 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' && с ‹= '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, прочие =%d\n", nwhite, 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' каждое следующее значение на 1 больше предыдущего. К счастью, это правило соблюдается во всех наборах символов.
По определению, значения типа char являются просто малыми целыми, так что переменные и константы типа char в арифметических выражениях идентичны значениям типа int. Это и естественно, и удобно; например, c-'0' есть целое выражение с возможными значениями от 0 до 9, которые соответствуют символам от '0' до '9', хранящимся в переменной c. Таким образом, значение данного выражения является правильным индексом для массива ndigit.
Следующий фрагмент определяет, является символ цифрой, символом-разделителем или чем-нибудь иным.
>if (c ›= '0' && c ‹= '9')
> ++n[c-'0'];
>else if (c ==' ' || c == '\n' || c == '\t')
> ++nwhite;