Поиск по сайту:

Учебник по программированию на C для Linux, часть 8. Вызов по значению и вызов по указателю/адресу


В нашей первой части этой продолжающейся серии руководств мы кратко обсудили функции, включая их объявление и тело. Чего мы тогда не обсуждали, так это множественных способов вызова функций. Здесь, в этом руководстве, мы быстро обсудим существующие способы. div-gpt-ad-howtoforge_com-box-3-0;var ffid=1;var alS=1002%1000;var container=document.getElementById(slotId);container.style.width=100%;var ins=document. createElement(ins);ins.id=slotId+-asloaded;ins.className=adsbygoogle ezasloaded;ins.dataset.adClient=pid;ins.dataset.adChannel=cid;if(ffid==2){ins.dataset.fullWidthResponsive= истинный;}

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

Допустим, вы хотите написать программу, которая меняет местами два значения. Вот как вы можете это сделать:

#include <stdio.h>

int main()
{
int a=0, b=0, c=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

c = a;
a = b;
b = c;

printf("\nSwapped values are: %d and %d", a,b);



return 0;
}

Вот вывод этого кода с введенными значениями 5 и 9:

Enter two integer values
5 9

Entered values are: 5 and 9
Swapped values are: 9 and 5

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

#include <stdio.h>

void swap (int val1, int val2)
{
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\nSwapped values are: %d and %d", val1,val2);

}

int main()
{
int a=0, b=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(a,b);

return 0;
}

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

Способ вызова свопа здесь известен как вызов по значению. Причина в том, что при вызове только значения, хранящиеся в a и b, передаются функции подкачки в качестве аргументов. Эти значения получают аргументы val1 и val2, и именно эти переменные, над которыми выполняется процесс подкачки.

Это означает, что переменные a и b в основной функции продолжают хранить исходные значения даже после выполнения операции замены. Но что, если требуется поменять местами значения a и b после вызова функции swap? Ну, вот тут-то и появляется изображение вызова по методу указателя/адреса.

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

Теперь, в предыдущем абзаце, мы сказали, что функция «оснащена для получения адресов в качестве аргументов». Что ж, под «оснащена» мы подразумеваем, что она имеет особый тип аргументов, которые могут принимать адреса. Эти аргументы являются переменными типа указателя. Мы подробно обсудим указатели в следующем уроке, а пока просто имейте в виду, что переменные-указатели хранят адреса памяти как значения.

Вот как объявляется/определяется указатель на целое число:

int *x;

Таким образом, x — это переменная-указатель, которую можно использовать для хранения адреса памяти целочисленной переменной. Предположим, что i — целочисленная переменная, и вот как вы можете заставить x хранить адрес i:

x = &i;

И всякий раз, когда вы хотите получить доступ к значению от i до x, вы пишете *x. Например, вот как вы можете изменить значение i, скажем, на 10:

*x = 10;

Итак, имея все это в виду, вот как вы можете вызвать своп, используя метод вызова по адресу или методу указателя:

#include <stdio.h>

void swap (int *val1, int *val2)
{
int temp = 0;

temp = *val1;
*val1 = *val2;
*val2 = temp;

}

int main()
{
int a=0, b=0, c=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(&a,&b);

printf("\nSwapped values are: %d and %d", a,b);


return 0;
}

Итак, на этот раз вместо передачи значений a и b в качестве аргументов мы передали адреса этих переменных. В функции подкачки адреса получаются в двух переменных указателях (val1 и val2). А используя две переменные-указатели, логика напрямую меняет местами значения a и b.

Вот результат:

Enter two integer values 
6 8
Entered values are: 6 and 8
Swapped values are: 8 and 6

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