ФУНКЦИИ И СТРУКТУРА ПРОГРАММ
Функции разбивают большие вычислительные задачи на маленькие подзадачи и позволяют использовать в работе то, что уже сделано другими, а не начинать каждый раз с пустого места. Соответствующие функции часто могут скрывать в себе детали проводимых в разных частях программы операций, знать которые нет необходимости, проясняя тем самым всю программу, как целое, и облегчая мучения при внесении изменений. Язык «C» разрабатывался со стремлением сделать функции эффективными и удобными для использования; «C»-программы обычно состоят из большого числа маленьких функций, а не из нескольких больших. Программа может размещаться в одном или нескольких исходных файлах любым удобным образом; исходные файлы могут компилироваться отдельно и загружаться вместе наряду со скомпилированными ранее функциями из библиотек. Мы здесь не будем вдаваться в детали этого процесса, поскольку они зависят от используемой системы. Большинство программистов хорошо знакомы с «библиотечными» функциями для ввода и вывода (getchar, putchar и др.) и для численных расчетов (sin, cos, sqrt и др.). В этой главе мы сообщим больше о написании новых функций.
Основные сведения
Для начала давайте разработаем и составим программу печати каждой строки ввода, которая содержит определенную комбинацию символов (это – специальный случай утилиты 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 (строка содержит нужную комбинацию) ... // Вывод этой строки
Конечно, возможно запрограммировать все действия в виде одной основной процедуры, но лучше использовать естественную структуру задачи и представить каждую часть в виде отдельной функции. С тремя маленькими кусками легче иметь дело, чем с одним большим, потому что отдельные не относящиеся к существу дела детали можно включить в функции и уменьшить возможность нежелательных взаимодействий. Кроме того, эти куски могут оказаться полезными сами по себе. «Пока имеется еще строка» – это getline, функция, которую мы запрограммировали в главе 2, а «вывод этой строки» – это функция printf, которую уже кто-то подготовил для нас. Это значит, что нам осталось только написать процедуру для определения, содержит ли строка данную комбинацию символов или нет. Мы можем решить эту проблему, позаимствовав разработку из PL/1: функция index(s,t) возвращает позицию, или индекс, строки s, где начинается строка t, и -1, если s не содержит t . В качестве начальной позиции мы используем 0, а не 1, потому что в языке «C» массивы начинаются с позиции нуль. Когда нам в дальнейшем понадобится проверять на совпадение более сложные конструкции, нам придется заменить только функцию index; остальная часть программы останется той же самой. Пример 5-1. После того, как мы потратили столько усилий на разработку, написание программы в деталях не представляет затруднений. Ниже приводится целиком вся программа, так что вы можете видеть, как соединяются вместе отдельные части. Комбинация символов, по которой производится поиск, выступает пока в качестве символьной строки в аргументе функции index, что не является самым общим механизмом. Мы скоро вернемся к обсуждению вопроса об инициализации символьных массивов и в главе 6 покажем, как сделать комбинацию символов параметром, которому присваивается значение в ходе выполнения программы. Программа также содержит новый вариант функции getline; вам может оказаться полезным сравнить его с вариантом из главы 2.
#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); }
// Поместить строку в s и возвратить длину int getline(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); }
// Вернуть индекс t в s, или -1 в противном случае int index(char s[], char 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() { } , которая не совершает никаких действий. Такая ничего не делающая функция иногда оказывается удобной для сохранения места для дальнейшего развития программы. Если функция возвращает что-либо отличное от целого значения, то перед ее именем может стоять указатель типа; этот вопрос обсуждается в следующем разделе.
Программой является просто набор определений отдельных функций. Связь между функциями осуществляется через аргументы и возвращаемые функциями значения (в этом случае); её также можно также осуществлять и через внешние переменные. Функции могут располагаться в исходном файле в любом порядке, а сама исходная программа может размещаться на нескольких файлах, но так, чтобы ни одна функция не расщеплялась. Оператор return служит механизмом для возвращения значения из вызванной функции в функцию, которая к ней обратилась. За return может следовать любое выражение:
return (выражение) .
Вызывающая функция может игнорировать возвращаемое значение, если она этого пожелает. Более того, после return может не быть вообще никакого выражения; в этом случае в вызывающую программу не передается никакого значения. Управление также возвращется в вызывающую программу без передачи какого-либо значения и в том случае, когда при выполнении мы «проваливаемся» на конец функции, достигая закрывающейся правой фигурной скобки. Eсли функция возвращает значение из одного места и не возвращает никакого значения из другого места, это не является незаконным, но может быть признаком каких-то неприятностей. В любом случае «значением» функции, которая не возвращает значения, несомненно, будет мусор. Отладочная программа Lint проверяет такие ошибки. Механика компиляции и загрузки «C»-программ, расположенных в нескольких исходных файлах, меняется от системы к системе. 1. В системе Unix, например, эту работу выполняет команда cc, упомянутая в главе 2. Предположим, что три функции находятся в трех различных файлах с именами main.с, getline.c и index.с . Тогда команда: cc main.c getline.c index.c
компилирует эти три файла, помещает полученный настраиваемый объектный код в файлы main.o, getline.o и index.o и загружает их всех в выполняемый файл, называемый a.out . Если имеется какая-то ошибка, скажем в main.c, то этот файл можно перекомпилировать отдельно и загрузить вместе с предыдущими объектными файлами по команде cc main.c getline.o index.o
Команда cc использует соглашение о наименовании: суффиксы «.с» и «.о» для того, чтобы отличить исходные файлы от объектных. 2. В системe Windous XP при использовании оболочки Visual Studio и среды программирования Visual C++ используется прогрессивный «проектный» подход: в состав «рабочего пространства проекта» – Workspace в число исходных файлов – Source Files (см. рис. 1.1) нужно включить только исходные модули с суффиксами «.сpp»: main.сpp, getline.cpp и index.сpp. Решение о том, что нужно перекомпилировать, а что не нужно, – принимает оболочка Visual Studio, причем без дополнительного набора каких-либо команд, как этого, например, требует Unix. Упражнение 5.1. Составьте программу для функции rindex(s,t), которая возвращает позицию самого правого вхождения t в s, и –1, если s не содержит t.
Популярное: Как построить свою речь (словесное оформление):
При подготовке публичного выступления перед оратором возникает вопрос, как лучше словесно оформить свою... Как вы ведете себя при стрессе?: Вы можете самостоятельно управлять стрессом! Каждый из нас имеет право и возможность уменьшить его воздействие на нас... Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы... ©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (237)
|
Почему 1285321 студент выбрали МегаОбучалку... Система поиска информации Мобильная версия сайта Удобная навигация Нет шокирующей рекламы |