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 = %DN”, 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, TAK что в арифметических выражениях переменные типа 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, если оно присутствует. Если последнеE ELSE и соответствующий 'оператор' опущены (как в программе подсчета слов), то никаких действий не производится. Между начальным IF и конечным ELSE может помещаться произвольное количество групп
ELSE IF (условие) оператор С точки зрения стиля целесообразно записывать эту конст-рукцию так, как мы показали, с тем чтобы длинные выражения не залезали за правый край страницы.
Оператор SWITCH (переключатель), который рассматривается в главе 3, представляет другую возможность для записи разветвления на несколько вариантов. этот оператор особенно удобен, когда проверяемое выражение является либо просто некоторым целым, либо символьным выражением, совпадающим с одной из некоторого набора констант. Версия этой программы, использующая оператор SWITCH, будет для сравнения приведена в главе 3.
Упражнение 1-12.
Напишите программу, печатающую гистограмму длин слов из файла ввода. Самое легкое - начертить гистограмму горизонтально; вертикальная ориентация требует больших усилий.
1.7. Функции.
В языке “C” функции эквивалентны подпрограммам или функциям в фортране или процедурам в PL/1, паскале и т.д. Функции дают удобный способ заключения некоторой части вычислений в черный ящик, который в дальнейшем можно использовать, не интересуясь его внутренним содержанием. Использование функций является фактически единственным способом справиться с потенциальной сложностью больших программ. Если функции организованы должным образом, то можно игнорировать то, как делается работа; достаточно знание того, что делается. Язык “C” разработан таким образом, чтобы сделать использование функций легким, удобным и эффективным. Вам будут часто встречаться функции длиной всего в несколько строчек, вызываемые только один раз, и они используются только потому, что это проясняет некоторую часть программы.
До сих пор мы использовали только предоставленные нам функции типа PRINTF, GETCHAR и PUTCHAR; теперь пора написать несколько наших собственных. так как в “C” нет операции возведения в степень, подобной операции ** в фортране или PL/1, давайте проиллюстрируем механику определения функции на примере функции POWER(M,N), возводящей целое м в целую положительную степень N. Так значение POWER(2,5) равно 32. Конечно, эта функция не выполняет всей работы операции **, поскольку она действует только с положительными степенями небольших чисел, но лучше не создавать дополнительных затруднений, смешивая несколько различных вопросов.
Ниже приводится функция POWER и использующая ее основная программа, так что вы можете видеть целиком всю структуру.
MAIN() /* TEST POWER FUNCTION */
{ INT I;
FOR(I = 0; I < 10; ++I) PRINTF(“%D %D %DN”,I,POWER(2,I),POWER(-3,I));
}
POWER(X,N) /* RAISE X N-TH POWER; N > 0 */ INT X,N;
{ INT I, P;
P = 1;
FOR (I =1; I <= N; ++I) P = P * X;
RETURN (P);
}
Все функции имеют одинаковый вид: имя (список аргументов, если они имеются) описание аргументов, если они имеются
{ описания операторы
}
Эти функции могут быть записаны в любом порядке и находиться в одном или двух исходных файлах. Конечно, если исходная программа размещается в двух файлах, вам придется дать больше указаний при компиляции и загрузке, чем если бы она находилась в одном, но это дело операционной системы, а не атрибут языка. В данный момент, для того чтобы все полученные сведения о прогоне “C”- программ, не изменились в дальнейшем, мы будем предполагать, что обе функции находятся в одном и том же файле.
Функция POWER вызывается дважды в строке PRINTF(“%D %D %DN”,I,POWER(2,I),POWER(-3,I));
при каждом обращении функция POWER, получив два аргумента, вазвращает целое значение, которое печатается в заданном формате. В выражениях POWER(2,I) является точно таким же целым, как 2 и I. /Не все функции выдают целое значение; мы займемся этим вопросом в главе 4/.
Аргументы функции POWER должны быть описаны соответствующим образом, так как их типы известны. Это сделано в строке INT X,N;
которая следует за именем функции.
Описания аргументов помещаются между списком аргументов и открывающейся левой фигурной скобкой; каждое описание заканчивается точкой с запятой. Имена, использованные для аргументов функции POWER, являются чисто локальными и недоступны никаким другим функциям: другие процедуры могут использовать те же самые имена без возникновения конфликта.
Это верно и для переменных I и P; I в функции POWER никак не связано с I в функции MAIN.
Значение, вычисленное функцией POWER, передаются в MAIN с помощью оператора RETURN, точно такого же, как в PL/1.
внутри круглых скобок можно написать любое выражение. Функция не обязана возвращать какое-либо значение; оператор RETURN, не содержащий никакого выражения, приводит к такой же передаче управления, как “сваливание на конец” функции при достижении конечной правой фигурной скобки, но при этом в вызывающую функцию не возвращается никакого полезного значения.
Упражнение 1-13.
Апишите программу преобразования прописных букв из айла ввода в строчные, используя при этом функцию OWER©, которая возвращает значение 'C', если C'- не буква, и значение соответствующей строчной уквы, если 'C'-буква.
... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...
... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...
... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...
... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...
0 комментариев