Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CИ-часть3студ.doc
Скачиваний:
15
Добавлен:
09.02.2015
Размер:
196.1 Кб
Скачать

6. Программирование с использованием подпрограмм

Подпрограмму можно определить как относительно самостоятельный фрагмент программы, оформленный таким образом, что его можно выполнять многократно, передавая ему управление из разных частей программы для обработки разных данных

Использование подпрограмм позволяет уменьшить размер программы (если в различных частях программы необходимо выполнять обработку данных по одному алгоритму) и сделать её исходный текст более удобным для понимания процесса обработки данных (если алгоритм подпрограммы обладает функциональной законченностью, а имя подпрограммы отражает её назначение, как, например, у стандартных подпрограмм sin(X) или fabs(X)). Преимущества программирования с использованием подпрограмм проявляются также при разработке больших программ, так как становится возможным распараллелить процесс разработки программного продукта, поручив программирование отдельных подпрограмм разным исполнителям, и, что более важно, – упростить процесс разработки и отладки.

Разбиение программы на подпрограммы производится, прежде всего, по функциональному признаку: подпрограмма должна реализовывать одну, но законченную функцию. При этом надо стремиться к сокращению количества межпрограммных связей (количеству передаваемых параметров). Рекомендуемый размер подпрограммы составляет 10-60 строк текста. Нецелесообразно создавать очень короткие подпрограммы, с одной стороны, а с другой стороны, размещение текста подпрограммы в пределах одной страницы текста позволяет программисту охватить весь текст одним взглядом и не тратить лишние усилия, связанные с переключением своего внимания с одной страницы на другую.

В языке C есть только один вид подпрограмм – функции. Функции в языке C являются фактически эквивалентом функций и подпрограмм общего вида языка Фортран или процедур и функций языка Паскаль. Организуя определенным образом функции в языке C, можно фактически получать аналоги процедур и функций языка Паскаль. Язык Паскаль, в свою очередь, также позволяет работать с функциями как с процедурами.

6.1. Объявление функций

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

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

При работе с функциями следует различать термины объявление функции, определение и обращение к функции (вызов функции).

Объявление функции (прототип функции) задает ее имя, тип возвращаемого значения и список передаваемых параметров. Обычно это заголовок функции, за которым следует знак ;. Заголовок функции имеет вид

Тип Имя (Список)

где

Тип – тип возвращаемого функцией значения, Имя – имя функции, Список – не обязательный список формальных параметров.

Имя функции строится так же, как и прочие имена в языке C. Имя функции задаёт её разработчик, и оно должно быть уникальным в своём модуле.

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

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

Определение функции содержит, кроме заголовка, тело функции, представляющее собой блок. Блок функции, как и блок основной функции main, может содержать объявления констант и переменных. Операторы тела функции описывают процесс обработки данных.

В объявлении функции имена параметров можно не указывать, а в определении функции они должны присутствовать.

Выход из функции и возвращаемые значения (результаты) в вызвавшую ее функцию осуществляется оператором

return выражение;

Функция может содержать несколько операторов return (это определяется особенностями реализуемого алгоритма), причём каждый из этих операторов может содержать своё выражение. Выражение, указанное после return, неявно преобразуется к типу возвращаемого функцией значения и передается в точку вызова функции. В функциях типа void операторы return не должны содержать выражений (просто обозначая места выхода из функций) или вовсе отсутствовать (в этом случае выход из функции будет при достижении конца её блока).

Обращение к функции выполняется по её имени и описывает данные (фактические параметры), обработку которых должна выполнить функция. Выполнение обращения приводит к передаче управления в тело функции. Вызовов одной функции может быть несколько, а фактические параметры в них могут быть разными.

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

Между фактическими и формальными параметрами функции должно выполняться соответствие по их количеству, порядку следования и типу.

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

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

В качестве простейшего примера организации функции приведем пример объявления и вызова функции, возвращающей первое из двух значений, представленных параметрами, кратное 5. Если оба значения не кратны 5, то функция возвращает -1.

// простейшая функция

#include "stdafx.h"

#include "stdio.h"

#include "conio.h"

int mod5(int k, int m);//объявление функции

int _tmain(int argc, _TCHAR* argv[])

{ int a,b;

printf("wwedite a i b\n");

scanf("%d%d",&a,&b);

printf("\n a=%4d b=%4d",a,b);

printf("\nperwoe kratnoe pjati = %4d",mod5(a,b));//1

printf("\nperwoe kratnoe pjati = %4d",mod5(a+9,b+2));//2

printf("\nperwoe kratnoe pjati = %4d",mod5(a+7,b+3));//3

getch();

return 0;

}

int mod5(int k, int m)//определение функции

// k,m - формальные параметры

{

if (k%5==0)

return k;

else

if(m%5==0)

return m;

else

return -1;

  1. }

Рассмотрим для конкретных значений переменных a=1 и b=2, что будет выведено на экран приведенной программой:

1) будет выведено значение -1, т.к. ни 1, ни 2 не делятся на 5 без остатка;

2) будет выведено значение 10,т.к. 1+9=10 и это число делится без остатка на 5, возвращаемое значение параметра k получает именно значение 10;

3) будет выведено значение 5, т.к. первое значение (1+7) на 5 не делится без остатка, а второе значение (2+3) делится без остатка на 5, возвращаемое значение параметра m как раз получает значение 5.

Все переменные, объявленные внутри функции, являются локальными: областью их видимости (действия) является тело функции. То же самое можно фактически сказать и о формальных параметрах функции. При вызове функции выделяется память (в стеке) для хранения значений фактических параметров и локальных переменных. При завершении работы функции соответствующий участок памяти освобождается, таким образом, значения локальных переменных и передаваемых значений между вызовами одной и той же функции не сохраняются. Как видно, с помощью оператора return можно возвратить только одно значение. Однако во многих случаях функция должна передавать несколько результатов вычислений в вызывающую функцию, для чего должна использовать и другие (помимо return) способы, некоторые из которых рассмотрены далее.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]