Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ПЯВУ - С-С++методичка и титул.doc
Скачиваний:
12
Добавлен:
08.11.2019
Размер:
789.5 Кб
Скачать

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

Обращение к функции имеет вид

имя_функции (список аргументов), где

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

Возможны два способа вызова функции:

  1. Вызов функции – операнд.

В этом случае значение, возвращаемое функцией, используется в выражении, где функция участвует как операнд; например:

int fun1(int k) // заголовок функции

m = fun1(n) * p; // вызов функции-операнда

  1. Вызов функции – оператор.

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

void fun2 (int mas[]) // заголовок функции

fun2 (ar[10]); // вызов функции-оператора

Передача параметров функции

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

Передача данных по значению

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

Пример 35.

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

Программа:

int Sum (int a, int b) // описание функции Sum

{ a++; b++; return (a+b); }

void main ( ) // главная функция

{ int m, k=5, l=4; // фактические параметры

m = Sum(k, l); // передача аргументов по значению

printf (“m=%d k=%d l=%d “, m, k, l ”);

}

Результаты программы: m=11 k=5 l=4,

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

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

Передача данных по адресу

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

Пример 36.

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

Программа.

int Sum (int *a , int *b) // функция Sum с указателями

{(*a)++; (*b)++; return (*a + *b); }

void main () // главная функция

{ int m, k=5, l=4; // фактические параметры

m = Sum (&k, &l); // передача адресов аргументов

printf(“m=%d k=%d l=%d”, m, k, l);

}

Результаты программы: m=11 k=6 l=5 ,

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

Пример 37.

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

Программа:

void Obmen (int *px, int *py) // список указателей

{ int r = *px; // перестановка

*px = *py; // значений

*py = r ; // переменных

}

void main ( ) // главная функция

{ int x=20; y=30; // исходные данные

Obmen (&x , &y); // передача адресов аргументов

printf (“x=%d y=%d” , x, y); // вывод результатов

}

Результаты программы: x=30 y=20

Использование способа передачи значений при вызове функции Obmen не изменяет значений переменных x и y, поскольку функция при этом способе работает с копиями аргументов.

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

Пример 38.

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

  1. Использование массива:

void copystring (char st1[ ], char st2[ ]) // параметры – массивы

{ int i;

for (i=0 ; st2[i] = st1[i]; i++); // цикл по элементам массива

}

2. Использование указателей:

void copystring (char *st1, char *st2) // параметры – указатели

{ while( *st2++ = *st1++); // цикл по указателям

}

  1. Использование указателей и элементов массива:

void copystring (char *st1; char *st2) // параметры – указатели

{ int i;

for (i=0; st2[i] = st1[i]; i++); // цикл по элементам массива

}