Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Text_lektsy_Si-dlya_studentov.pdf
Скачиваний:
6
Добавлен:
08.05.2015
Размер:
1.22 Mб
Скачать

Существует два вида процедур: ПОДПРОГРАММЫ и ФУНКЦИИ. Отличие подпрограмм от функций – первые не возвращают значения в основную программу.

ПОБОЧНЫЙ ЭФФЕКТ. В Си формально определены только ФУНКЦИИ.

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

Схема обмена данными между процедурами

Возвращаемое значение

 

 

Входные аргументы

 

 

 

 

 

 

Вызываемая

Вызывающая

 

 

 

 

Фактические

 

Формальные параметры

 

 

параметры

 

 

 

Результаты

Возвращаемое значение функции разумно считать специфическим выходным параметром.

Формат ОПИСАНИЯ функции

[<тип_функции>] <имя_функции> ( [<описания_формальных_параметров>] ) <блок>

Если <тип_функции> отсутствует, то компилятор по умолчанию подставляет int. ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ. Если возвращаемое значение имеет тип не int, то указание типа в заголовке функции ОБЯЗАТЕЛЬНО.

Оператор return: Остановимся поподробнее на зарезервированном слове return. После него функция перестает выполняться и возвращает управление вызвавшей ее функции, передав значение, указанное после return, как результат. Слов return в функции может быть несколько, но хотя бы одно должно присутствовать обязательно. Исключение – когда функция имеет тип возвращаемого значения VOID. В этом случае слово return в функции может и отсутствовать, если оно есть, то оно не должно передавать что-либо в качестве результата. В этом случае слово записывается так: return ;

floatmin_fun (float x[], int n) {

int i, j;

// Локальные переменные функции

float min_value;

 

................

 

return (min_value)

}

Да, и еще: локальные переменные функции существуют только во время выполнения этой функции. Они создаются всякий раз при входе в функцию и уничтожаются всякий раз при выходе из нее.

ПОДПРОГРАММА – это функция, не возвращающая значения. Ключевое слово <типа_функции> void.

void <имя_функции> ([<описания_формальных_параметров>]) <блок>

39

Тип void: Ключевое слово void используется для нейтрализации значения объекта, например, для определения функции не возвращающей никаких значений.

Пример:

void putmsg ( void ) { printf("Hello, world!\n");

}/* End putmsg */

Для ОБРАЩЕНИЯ к функции используется выражение с операцией “круглые

скобки”:

Обозначение_функции ( список_фактических_параметров ) ;

Операндами

операции

()

служат

Обозначение_функции

и

спи-

 

сок_фактических_параметров.

 

 

 

 

 

 

Наиболее естественное и понятное Обозначение_функции – это ее имя. Кроме того,

 

функцию можно обозначить, разыменовав указатель на нее.

 

 

 

Сторонники Паскаля! Обратите внимание на разницу между mufunc и myfunc().

my

myfunc ;

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

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

Между формальными и фактическими параметрами должно быть соответствие по типам. Лучше всего, когда тип фактического параметра совпадает с типом формального параметра. В противном случае компилятор автоматически добавляет команды преобразования типов, что возможно только в том случае, если такое приведение типов допустимо.

В языке Си нет предопределенных функций. Каждая используемая функция должна быть где-то ОПРЕДЕЛЕНА (ОБЪЯВЛЕНА) до ее использования. Поскольку все функции могут транслироваться автономно, то в вызывающей процедуре необходимо ОПРЕДЕЛЕНИЕ вида (прототип функции):

(<тип_возвращаемого_значения>)<имя_функции>

( [ описание_параметров] ); Без него возвращаемое значение функции будет интерпретироваться как типа int и

возможна ошибка. Поэтому подпрограмма не описывается. Здесь возможны два варианта:

1. Если Вы используете встроенные функции среды Си, то самому писать многие требуемые функции (ввод-вывод, подключение файлов, математические функции и т.д.) каждый раз несколько скучно К счастью, Си снабжен библиотекой, содержащей в себе множество разнообразных функций. Для того, чтобы использовать ее, подключите к вашей программе требуемый ЗАГЛОВОЧНЫЙ ФАЙЛ (он имеет расширение .h) к вашей программе следующей строкой:

40

#include <Имя_заголовочного_файла>

На место этой строки в программу при компиляции будет подставлено содержание указанного файла.

2. Если Вы создали личную функцию, отличную от стандартных функций языка Си, то перед ее вызовом она обязательно должна быть объявлена:

Например, пусть определена функция с прототипом: int g ( int x, long y );

Далее в программе использован вызов : double m;

rez = g ( 3.0+m, 6.4e+2 );

Оба фактических параметра в этом вызове имеют тип double. Компилятор, ориентируясь на прототип функции, автоматически предусмотрит такие преобразования:

(int) rez = g ( (int)(3.0+m), (long)(6.4e+2) )

Пример (функция):

 

void main( ) {

 

double max (double, double )

// Прототип функции

 

max_value = max (cos(x), sin(x));

// Обращение к функции

… }

 

double max (double a, double b ) // Описание функции

{double y;

if ( a > b )

y = a;

else

y=b;

return y;

}

Пример (подпрограмма):

/* Умножение матрицы на вектор */ matrix(a, b, c, m, n);

void matrix ( double p[10][10], /* Исходная матрица */

double q[10],

/* Исходный вектор */

double s[10],

/* Вектор–результат */

int l,

/* Число строк */

int k)

/* Число столбцов */

{ int i, j;

 

for ( i=0; i<l; i++ ) { for ( s[i]=j=0; j<k; j++ ) { s[i] += p[i][j]*q[j]; } }

}/* End matrix */

В каждой программе должна быть процедура, которой передает управление ОС и которая остается активной в течение всей работы программы. Эта процедура называется ГЛАВНОЙ и имеет заголовок вида

int main([<параметры>]) <блок>

О параметрах пока умолчим, поэтому обычно имеем

41

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