основыкнигиwin/dos*nixготовоелирикагостиФОРУМПОИСК
Б.В. Керниган, Д.М. Ричи -- Язык C

1.6. Массивы

      Давайте напишем программу подсчета числа появлений каждой цифры, символов пустых промежутков/пробел, табуляции, новая строка/ и всех остальных символов. Конечно, такая задача несколько искусственна, но она позволит нам проиллюстрировать в одной программе сразу несколько аспектов языка "C".
      Мы разбили вводимые символы на двенадцать категорий, и нам удобнее использовать массив для хранения числа появлений каждой цифры, а не десять отдельных переменных. Вот один из вариантов программы:

 MAIN()  /* COUNT DIGITS, WHITE SPACE, OTHERS */
 {
     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("DIGITS =");
     FOR (I = 0; I < 10; ++I)
     PRINTF(" %D", NDIGIT[I]);
     PRINTF("\NWHITE SPACE = %D, OTHER = %D\N",
      NWHITE, NOTHER);
 }

      Описание

    INT  NDIGIT[10];

объявляет, что NDIGIT является массивом из десяти целых. В языке "C" индексы массива всегда начинаются с нуля /а не с 1, как в фортране или PL/1/, так что элементами массива являются NDIGIT[0], NDIGIT[1],..., NDIGIT[9]. Эта особенность отражена в циклах FOR, которые инициализируют и печатают массив.
      Индекс может быть любым целым выражением, которое, конечно, может включать целые переменные, такие как I, и целые константы.
      Эта конкретная программа сильно опирается на свойства символьного представления цифр. Так, например, в программе проверка

    IF( C >= '0' && C <= '9')...

определяет, является ли символ в 'C' цифрой, и если это так, то численное значение этой цифры определяется по формуле / C - '0'/. Такой способ работает только в том случае, если значения символьных констант '0', '1' и т.д. Положительны, расположены в порядке возрастания и нет ничего, кроме цифр, между константами '0' и '9'. К счастью, это верно для всех общепринятых наборов символов.
      По определению перед проведением арифметических операций, вовлекающих переменные типа CHAR и INT, все они преобразуются к типу INT, так что в арифметических выражениях переменные типа 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  (условие)
             оператор
     ELSE IF  (условие)
             оператор
     ELSE
             оператор

часто встречаются в программах как средство выражения ситуаций, в которых осуществляется выбор одного из нескольких возможных решений.
      Программа просто движется сверху вниз до тех пор, пока не удовлетворится какое-нибудь условие; тогда выполняется соответствующий 'оператор', и вся конструкция завершается. /Конечно, 'оператор' может состоять из нескольких операторов, заключенных в фигурные скобки/. Если ни одно из условий не удовлетворяется, то выполняется 'оператор', стоящий после заключительного ELSE, если оно присутствует. Если последнее ELSE и соответствующий 'оператор' опущены (как в программе подсчета слов), то никаких действий не производится. Между начальным IF и конечным ELSE может помещаться произвольное количество групп

 ELSE IF (условие)
    оператор

      С точки зрения стиля целесообразно записывать эту конструкцию так, как мы показали, с тем чтобы длинные выражения не залезали за правый край страницы.
      Оператор SWITCH (переключатель), который рассматривается в главе 3, представляет другую возможность для записи разветвления на несколько вариантов. этот оператор особенно удобен, когда проверяемое выражение является либо просто некоторым целым, либо символьным выражением, совпадающим с одной из некоторого набора констант. Версия этой программы, использующая оператор SWITCH, будет для сравнения приведена в главе 3.
      Упражнение 1-12.
      ----------------
      Напишите программу, печатающую гистограмму длин слов из файла ввода. Самое легкое -- начертить гистограмму горизонтально; вертикальная ориентация требует больших усилий.

ПРЕДЫДУЩАЯ ЧАСТЬ
1.5.5. Подсчет слов
СОДЕРЖАНИЕ СЛЕДУЮЩАЯ ЧАСТЬ
1.7. Функции