netlib.narod.ru< Назад | Оглавление | Далее >

1.6. Массивы

Давайте напишем программу для подсчета числа появлений каждой из цифр, символов разделителей (пробел, табуляция, новая строка) и всех остальных символов. Конечно, такая задача несколько искусственна, но она позволит нам проиллюстрировать в одной программе сразу несколько аспектов языка Си.

Имеется двенадцать категорий вводимых символов. Для хранения числа появлений каждой из цифр удобнее использовать массив, а не десять отдельных переменных. Вот один из вариантов этой программы:

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

Сайт управляется системой uCoz