4.1. Основные сведения.
Для начала давайте разработаем и составим программу пе-
чати каждой строки ввода, которая содержит определенную ком-
бинацию символов. /Это - специальный случай утилиты GREP
системы “UNIX”/. Например, при поиске комбинации “THE” в на-
боре строк
NOW IS THE TIME
FOR ALL GOOD
MEN TO COME TO THE AID
OF THEIR PARTY
в качестве выхода получим
NOW IS THE TIME
MEN TO COME TO THE AID
OF THEIR PARTY
основная схема выполнения задания четко разделяется на три
части:
WHILE (имеется еще строка)
IF (строка содержит нужную комбинацию)
вывод этой строки
· 74 -
Конечно, возможно запрограммировать все действия в виде
одной основной процедуры, но лучше использовать естественную
структуру задачи и представить каждую часть в виде отдельной
функции. С тремя маленькими кусками легче иметь дело, чем с
одним большим, потому что отдельные не относящиеся к сущест-
ву дела детали можно включить в функции и уменьшить возмож-
ность нежелательных взаимодействий. Кроме того, эти куски
могут оказаться полезными сами по себе.
“Пока имеется еще строка” - это GETLINE, функция, кото-
рую мы запрограммировали в главе 1, а “вывод этой строки” -
это функция PRINTF, которую уже кто-то подготовил для нас.
Это значит, что нам осталось только написать процедуру для
определения, содержит ли строка данную комбинацию символов
или нет. Мы можем решить эту проблему, позаимствовав разра-
ботку из PL/1: функция INDEX(S,т) возвращает позицию, или
индекс, строки S, где начинается строка T, и -1, если S не
содержит т . В качестве начальной позиции мы используем 0, а
не 1, потому что в языке “C” массивы начинаются с позиции
нуль. Когда нам в дальнейшем понадобится проверять на совпа-
дение более сложные конструкции, нам придется заменить толь-
ко функцию INDEX; остальная часть программы останется той же
самой.
После того, как мы потратили столько усилий на разработ-
ку, написание программы в деталях не представляет затрудне-
ний. ниже приводится целиком вся программа, так что вы може-
те видеть, как соединяются вместе отдельные части. Комбина-
ция символов, по которой производится поиск, выступает пока
в качестве символьной строки в аргументе функции INDEX, что
не является самым общим механизмом. Мы скоро вернемся к об-
суждению вопроса об инициализации символьных массивов и в
главе 5 покажем, как сделать комбинацию символов параметром,
которому присваивается значение в ходе выполнения программы.
Программа также содержит новый вариант функции GETLINE; вам
может оказаться полезным сравнить его с вариантом из главы
1.
#DEFINE MAXLINE 1000
MAIN() /* FIND ALL LINES MATCHING A PATTERN */
{
CHAR LINE[MAXLINE];
WHILE (GETLINE(LINE, MAXLINE) > 0)
IF (INDEX(LINE, “THE”) >= 0)
PRINTF(“%S”, LINE);
}
· 75 -
GETLINE(S, LIM) /* GET LINE INTO S, RETURN LENGTH *
CHAR S[];
INT LIM;
{
INT C, I;
I = 0;
WHILE(--LIM>0 && (C=GETCHAR()) != EOF && C != '\N')
S[I++] = C;
IF (C == '\N')
S[I++] = C;
S[I] = '\0';
RETURN(I);
}
INDEX(S,T) /* RETURN INDEX OF T IN S,-1 IF NONE */
CHAR S[], T[];
{
INT I, J, K;
FOR (I = 0; S[I] != '\0'; I++) {
FOR(J=I, K=0; T[K] !='\0' && S[J] == T[K]; J++; K++)
;
IF (T[K] == '\0')
RETURN(I);
}
RETURN(-1);
}
Каждая функция имеет вид имя (список аргументов, если они
имеются) описания аргументов, если они имеются
{
описания и операторы , если они имеются
}
Как и указывается, некоторые части могут отсутство-
вать; минимальной функцией является
DUMMY () { }
которая не совершает никаких действий.
/Такая ничего не делающая функция иногда оказывается
удобной для сохранения места для дальнейшего развития прог-
раммы/. если функция возвращает что-либо отличное от целого
значения, то перед ее именем может стоять указатель типа;
этот вопрос обсуждается в следующем разделе.
· 76 -
Программой является просто набор определений отдельных
функций. Связь между функциями осуществляется через аргумен-
ты и возвращаемые функциями значения /в этом случае/; ее
можно также осуществлять через внешние переменные. Функции
могут располагаться в исходном файле в любом порядке, а сама
исходная программа может размещаться на нескольких файлах,
но так, чтобы ни одна функция не расщеплялась.
Оператор RETURN служит механизмом для возвращения зна-
чения из вызванной функции в функцию, которая к ней обрати-
лась. За RETURN может следовать любое выражение:
RETURN (выражение)
Вызывающая функция может игнорировать возвращаемое
значение, если она этого пожелает. Более того, после RETURN
может не быть вообще никакого выражения; в этом случае в вы-
зывающую программу не передается никакого значения. Управле-
ние также возвращется в вызывающую программу без передачи
какого-либо значения и в том случае, когда при выполнении мы
“проваливаемся” на конец функции, достигая закрывающейся
правой фигурной скобки. EСли функция возвращает значение из
одного места и не возвращает никакого значения из другого
места, это не является незаконным, но может быть признаком
каких-то неприятностей. В любом случае “значением” функции,
которая не возвращает значения, несомненно будет мусор. От-
ладочная программа LINT проверяет такие ошибки.
Механика компиляции и загрузки “C”-программ, располо-
женных в нескольких исходных файлах, меняется от системы к
системе. В системе “UNIX”, например, эту работу выполняет
команда 'CC', упомянутая в главе 1. Предположим, что три
функции находятся в трех различных файлах с именами MAIN.с,
GETLINE.C и INDEX.с . Тогда команда
CC MAIN.C GETLINE.C INDEX.C
компилирует эти три файла, помещает полученный настраиваемый объектный код в файлы MAIN.O, GETLINE.O и INDEX.O и загружа-ет их всех в выполняемый файл, называемый A.OUT .
Если имеется какая-то ошибка, скажем в MAIN.C, то этот
файл можно перекомпилировать отдельно и загрузить вместе с
предыдущими объектными файлами по команде
CC MAIN.C GETLIN.O INDEX.O
Команда 'CC' использует соглашение о наименовании с “.с” и “.о” для того, чтобы отличить исходные файлы от объектных.
Упражнение 4-1.
Составьте программу для функции RINDEX(S,T), которая
возвращает позицию самого правого вхождения т в S и -1, если
S не содержит T.
·
77 -
... основаниям. При этом философская абстракция языка оказывается неразрывно связана с основными темами и движениями философии в целом. Более конкретно, на ранние стадии традиционно рассматриваемого в рамках АФ анализа обыденного языка глубокое влияние оказала философия Дж. Э. Мура, особенно его учение о здравом смысле, согласно которому такие понятия, как «человек», «мир», «я», «внешний мир», « ...
... и других странах СНГ, а также облегчение доступа к русской и мировой культуре и науке. Таким образом, судя по данным наших исследований, востребованность русского языка осталась в республике достаточно высокой. Многие представители современной молдавской молодежи продолжают, как их отцы и деды, тянуться к русской культуре, научным и техническим достижениям России. Русский язык остается языком ...
... рисуночное словесно-слоговое письмо). Памятники среднеэламского периода (14—12 вв. до н.э.) выполнены аккадской клинописью. Памятники новоэламского периода относятся к 8—6 вв. до н.э. Был официальным языком в персидском государстве Ахеменидов в 6—4 вв. предполагается, что он, подвергшись влиянию древнеперсидского, сохранился до раннего средневековья. 7. Бурушаски язык Язык бурушаски ( ...
... /диалект), скифский, согдийский, среднеперсидский, таджикский, таджриши (язык/диалект), талышский, татский, хорезмийский, хотаносакский, шугнано-рушанская группа языков, ягнобский, язгулямский и др. Они относятся к индоиранской ветви индоевропейских языков. Области распространения: Иран, Афганистан, Таджикистан, некоторые районы Ирака, Турции, Пакистана, Индии, Грузии, Российской Федерации. Общее ...
0 комментариев