Функции на языке С. Описание, передача параметров, вызов функции.

Описание функции:

Тип имя (список формальных параметров)
{
тело функции
}

Где

тип – тип результата

имя – имя функции

список формальных параметров – содержит как имена параметров, так и их спецификации

тело функции:

определения переменных

исполняемые операторы

примеры:

//функция возвращает значение целого типа

int max(int x, int y)

{ if (x>y) return x; else return y;}

//функция не возвращает значения

void print(float x)

{

printf (“\n значение аргумента равно %7.2f \n”, x);

}

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

Прототип функции состоит только из заголовка :

Тип имя (список формальных параметров)

n При описании прототипа функции список формальных параметров может содержать только спецификации параметров

n Прототип должен быть обязательноесли описание функции стоит ниже вызывающей ее функции

Пример: верное обращение к функции

int max(int ,int ); // прототип функции

void main()

{ int a,b,c; float m;

scanf(“%d %d %d”, &a,&b,&c);

m=(float)(max(a,b)+max(b,c))/max(a,a); printf(“\n m=%7.2f”,m);

} // main

//описание функции

int max(int x,int y)

{ (if (x>y) return x; else return(y); }

Даны два комплексных числа
z=a+b*i, y=c+d*I

Вычислить
|x|, |y|, |x+y|

Решение:

float mod(float a, float b);// прототип функции

void main()

{

float a,b,c,d,mx,my,mxy;

scanf(“%f %f %f %f”, &a,&b,&c,&d);

mx=mod(a,b); //вызов функции

my=mod(c,d);

mxy=mod(a+c,b+d);

printf(“\n|x|=%f |y|=%f |x+y|=%f “, mx,my,mxy);

}

// описание функции

float mod (float a, float b);

{

float s=sqrt(a*a+b*b);

return s;

}

Здесь:

a и b – формальные параметры

s – локальная переменная

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

При вызове функции формальные параметры заменяются на фактические

Количество, типы и порядок следования фактических параметров должен полностью соответствовать перечню формальных параметров

Пример:

Пусть задана фунция

int max(int x,int y)

{ (if (x>y) return x; else return(y); }

Вызов max(a,b); и max(b,a); для целых значений a и b даст различные результаты.

Если переменная s – типа float, то вызов функции max(s,a); даст сообщение об ошибке

Передача параметров:

Существует два способа передачи параметров:

n По значению
Операторы функции работают только с копиями передаваемых параметров. Возможности изменить сами значения у функции нет

n По адресу
Функция осуществляет доступ к ячейкам памяти по передаваемым адресам и может изменить значения аргументов

Например:

Пусть необходимо написать функцию, которая меняет два значения x и y местами.

#include <stdio.h>

void swap(int x, int y)

{ printf(“начальные значения:%d %d\n”, x,y);

int temp=y; y=x;x=temp;

printf(“измененные значения: %d %d \n конец функции\n”, x,y);

}//swap

void main()

{

int a,b;

printf(“a=“);scanf(“%d”, &a);

printf(“b=“);scanf(“%d”, &b);

swap(a,b);

printf(“новые значения : ”, a,b);

}// main

Результаты выполнения программы

a=10

b=20

начальные значения: 10 20

измененные значения: 20 10

конец функции

новые значения : 10 20

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

Функция работает с копиями параметров

Указатели и основные операции с указателями.

Указатели предназначены для хранения адресов памяти

Указатель не является самостоятельным типом: он всегда связан с каким-либо конкретным типом

Существуют указатели трех типов

n Указатель на объект – в этом случае в указателе хранится адрес области памяти, в которой хранятся данные определенного типа

n Указатель на функцию – содержит адрес в сегменте кода, по которому располагается исполняемый код функции

n Указатель на void – применяется в том случае, когда конкретный тип объекта заранее не определен

Указатель может быть

n Константой

n Переменной

n Указывать на константу

n Указывать на переменную

Примеры:

int I; // целая переменная

const int ci=1;// целая константа

int *pi;//указатель на целую переменную

const int *pci; //указатель на целую константу

int * const cp=&i; //указатель-константа на целую переменную

const int * const cpc=&ci;

//указатель-константа на целую константу

Инициализация указателей:

Присваивание указателю адреса существующего объекта:

int a=5; // инициализируем целую переменную

int *pa=&a; // в указатель записывается адрес а

Операции с указателями:

Разадресация (разыменование) –
используется для получения или изменения значения по заданному адресу
Обозначение: *
int x=10, y;//переменные типа int

int *px=&x; //указателю присваиваем значение адреса переменной х
y=*px; //значение y становится равным 10

int x, y;//переменные типа int

int *px=&x; //указателю присваиваем значение адреса переменной х
*px=10; //значение х становится равным 10

Арифметические операции:

n Инкремент – увеличение указателя на величину sizeof(тип)
Декремент -уменьшение указателя на величину sizeof(тип):

int *p;

float *s;

p++;//увеличивает p на 2

s++;// увеличивает s на 4

Разность двух указателей – это разность их значений, деленная на размер типа в байтах

int x=10,*px, y=20,*py;

px=&x; py=&y;

float *a,*b;

printf(“px=%d, py=%d, px-py=%d\n”,

px,py,px-py);

printf(“a=%d, b=%d, a-b=%d\n”,a,b,a-b);

Результат выполнения:

px=3fff4, py=3fff2, px-py=1

a=4ff26, b=4ffe10, a-b=4

Сумма указателя и константы

int *px; cout<<“px=“<<px<<endl;

px=px+4;

cout<<“px+4=“<<px<<endl;

Результат: px=3fff4

px+4=3fffc

Замечания:

n Арифметические операции используются только для указателей одного типа

Сложение указателей не допускается

Передача параметров по адресу:

Пример:

Void swap(int *a, int *b)

{ int temp=*a;

*a=*b;

*b=temp;

}

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

Void main()

{ int a=10,b=2;

printf(“\n a=%d b=%d”,a,b);

swap(&a,&b);

printf(\n new \n a=%d b=%d”,a,b);

}

Результат: A=10 b=2

New

A=2 b=10

Наши рекомендации