В этом случае в качестве аргументов при вызове функции передаются не копии переменных, а копии адресов переменных. Формальный и фактический параметр, используя один и тот же адрес (указатель), получают доступ к общему участку памяти (переменной). После применения операции разадресации (* – обращения по адресу) в функции можно изменить значение фактического параметра и использовать его как один из результатов функции.
Пример. Составить функцию 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) изменили свои значения после вызова функции.
Пример. Составить функцию обмена значениями между переменными 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, поскольку функция при этом способе работает с копиями аргументов.
Вызов функции с передачей адресов аргументов позволяет разрабатывать функции, имеющие доступ к массивам и другим протяженным объектам данных. Если в список параметров включено имя массива, то в функцию передается только адрес начала массива.
Пример. Разработать функции копирования строки из одного места памяти в другое. Возможны разные варианты функций, решающих эту задачу на основе алгоритмов рассмотренных выше.
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++); } /* цикл по указателям */
3. Использование указателей и элементов массива:
void copystring (char *st1; char *st2) /* параметры – указатели */
{ int i;
for (i=0; st2[i] = st1[i]; i++); } /* цикл по элементам массива */