Мегаобучалка Главная | О нас | Обратная связь


ФУНКЦИИ И СТРУКТУРА ПРОГРАММ



2019-12-29 217 Обсуждений (0)
ФУНКЦИИ И СТРУКТУРА ПРОГРАММ 0.00 из 5.00 0 оценок




 

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

Язык «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.

 



2019-12-29 217 Обсуждений (0)
ФУНКЦИИ И СТРУКТУРА ПРОГРАММ 0.00 из 5.00 0 оценок









Обсуждение в статье: ФУНКЦИИ И СТРУКТУРА ПРОГРАММ

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Как распознать напряжение: Говоря о мышечном напряжении, мы в первую очередь имеем в виду мускулы, прикрепленные к костям ...
Почему двоичная система счисления так распространена?: Каждая цифра должна быть как-то представлена на физическом носителе...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (217)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.006 сек.)