Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

programmirovanie / ОПиАЯ_№3_6_пп_слайды

.doc
Скачиваний:
34
Добавлен:
03.03.2016
Размер:
67.07 Кб
Скачать

4 Подпрограмма в СИ

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

Обычная функция подобна функции main . Ее объявление имеет вид:

[тип] f ([список формальных параметров])

{[декларативная часть;]

операторы;

}

Предложение объявления является

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

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

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

В заголовке функции слово тип задает тип возвращаемого функцией f значения – основной или типа указатель

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

По умолчанию (тип не написан) результатом будет int-данное.

Каждая функция глобальна

(по умолчанию имени f назначается класс памяти extern).

Внутренних функций в Си нет.

Имя f это особый тип указателя, называемого указателем на функцию. Его значение – адрес точки входа в функцию.

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

тип v,

где тип(i=1,2,…,n) – тип параметра,

v - его имя.

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

Тело функции – блок или

(реже) составной оператор.

Обязательным оператором тела является оператор возврата вида return выражение.

Он прекращает выполнение функции и передает значение выражения и управление в точку вызова.

Вызов функции

f([u, u,…,u])

- это первичное выражение. Операция в нем обозначается круглыми скобками.

Операндами служат имя функции(вычисляется как адрес) и фактические параметры u(i=1,2,…,n).

Здесь любое u -выражение, тип значения которого основной, структура, перечисление, объединение или указатель.

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

Прототип почти полностью совпадает с заголовком функции: первое отличие – присутствие точки и запятой в конце заголовка,

второе – необязательность имен формальных параметров.

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

#include “имя файла.с

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

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

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

1. Подсчитывается значение выражения u (i=1,2,…,n).

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

Если они не совпадают, то либо производится преобразование типа, либо выдается диагностическое сообщение.

2. Компилятор в точке вызова размещает команды загрузки в стек значений фактических параметров, происходит замена формальных параметров на фактические: первый фактический параметр всегда соответствует первому формальному параметру, второй - второму и т.д.

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

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

#include <stdio.h>

float mmm(float x1,

float y1);

main()

{

Z=mmm(X,Y);

getch();

}

float mmm(float x1,float y1)

{

/* */

return(x1*y1);

}

Функция void

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

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

#include <stdio.h>

float mmm1();

int X;

/*глобальные переменные*/

float Y,Z;

main()

{

printf("\n int X floatY");

printf("\n");

scanf("\n %d %f",&X,&Y);

printf("%d %f ",X,Y);

Z=mmm1();

printf("\n Z= %f ",Z);

getch();

}

float mmm1()

{

/* */

return (Y*Y);

}

#include <stdio.h>

void mmm2(int x1,float y1);

main()

{

int X;

/*локальные переменные*/

float Y,Z;

printf("\n ўўҐ¤ЁвҐ 楫 ¤Ґ©бв бЁ¬ў®« ¬ ббЁўЁ§ 3-е");

printf("\n");

scanf("\n %d %f",&X,&Y);

printf("X=%d Y=%f",X,Y);

mmm2(X,Y);

printf("\n Y= %f ",Y);

getch();

}

void mmm2(int x1,float y1)

{

/* */

x1=x1*x1;

y1=y1*y1;

printf("\n fun X=%d Y=%f",x1,y1);

}

#include <stdio.h>

void mmm3(int x1,float *y1,float *z1);

main()

{

int X;

float Y,Z;

printf("\n vvod intX floatY");

printf("\n");

scanf("\n %d %f",&X,&Y);

printf("X=%d Y=%f",X,Y);

mmm3(X,&Y,&Z);

printf("\n Y= %f Z=%f ",Y,Z);

getch();

}

void mmm3(int x1,float *y1,float *z1)

{

/* */

*y1=x1+x1;

*z1=*y1*(*y1);

printf("\n fun Y=%f Z=%f",*y1,*z1);

}

Каковы значения переменных x и у в отмеченных точках.

void silly(int x) /*по значению*/

{int y;

y=x+2;

x=2*x;

}

main()

{int x,y;

x=10; y=11;

silly(x);

silly(y);

}

void silly(int *x) /*по ссылке*/

{int y;

y=*x+2;

x=2**x;

}

main()

{int x,y;

x=10; y=11;

silly(&x);

silly(&y);

}

#include <stdio.h>

void mmm(int x1[2], int *z1, float y[1]);

main()

{

int X[2],Z;

float Y[7];

printf("\n vvod intX floatY");

printf("\n");

X[0]=1;

X[1]=2;

Y[5]=125,5;

mmm(X, Z,&y[5]);

printf("\n Z=%d ",Z);

printf("\n x[1]=%d ",x[1]);

printf("\n y[5]=%f ",y[5]);

getch();

}

void mmm(int x1[2],int *z1, float yx[1])

{

/* */

*z1=x1[0]+x1[1];

printf("\n fun z1=%d",*z1);

printf("\n fun y[5]=%f",yz[0]);

}

Передаем параметр через командную строку

#include <GRAPHICS.h>

#include <conio.h>

#include <string.h>

#include <stdlib.h>

#include <stdio.h>

main(int argc,char *argv[])

{

int i,j,i7;

char a[6],b[6];

if(argc==0) {printf("yk imja bx byx file"); exit(-1);}

printf("\n %s",argv[1]);

printf("\n %s ",argv[2]);

getch();

}

Из командной строки

fff_777.exe S K

Соседние файлы в папке programmirovanie