Об召唤е функции по ссылке в C

Здравствуйте, будущие программисты! Сегодня мы отправимся в увлекательное путешествие в мир программирования на языке C,Specifically exploring the concept of "Function Call by Reference." Не волнуйтесь, если вы новички в программировании; я буду вести вас шаг за шагом, как я делал это для countless students over my years of teaching. Так что возьмите любимый напиток, удобно расположитесь и погружайтесь с нами!

C - Function call by reference

Оператор адреса (&) в C

Before we can understand function calls by reference, we need to familiarize ourselves with a very important symbol in C: the ampersand (&). Этот маленький символ известен как "оператор адреса" и resembles a magical wand that reveals the secret location of our variables in the computer's memory.

Давайте посмотрим на простой пример:

#include <stdio.h>

int main() {
int age = 25;
printf("Значение переменной age: %d\n", age);
printf("Адрес переменной age: %p\n", &age);
return 0;
}

В этом коде мы не только выводим значение переменной age (которое равно 25), но и её адрес в памяти. Спецификатор формата %p используется для вывода адресов памяти.

When you run this program, you might see something like:

Значение переменной age: 25
Адрес переменной age: 0x7ffd5e8e9944

Эта странно выглядящая цифра после "Адрес переменной age:" на самом деле является адресом памяти! Это место, где ваш компьютер решил хранить переменную age. Представьте это как домашний адрес переменной в обширном районе памяти вашего компьютера.

Что такое указатель в C?

Теперь, когда мы знаем, как найти адрес переменной, давайте поговорим о указателях. Если адрес resembles a home address, то указатель resembles a GPS navigator, который может направить вас к этому адресу.

В C указатель - это переменная, которая хранит адрес другой переменной. Мы объявляем указатель, используя символ astrisk (*).

Вот пример:

#include <stdio.h>

int main() {
int age = 25;
int *ptr_age = &age;

printf("Значение переменной age: %d\n", age);
printf("Адрес переменной age: %p\n", &age);
printf("Значение переменной ptr_age: %p\n", ptr_age);
printf("Значение, на которое указывает ptr_age: %d\n", *ptr_age);

return 0;
}

В этом коде ptr_age - это указатель, который хранит адрес age. When we use *ptr_age, мы запрашиваем значение, хранящееся по адресу, на который указывает ptr_age.

Вывод может выглядеть так:

Значение переменной age: 25
Адрес переменной age: 0x7ffd5e8e9944
Значение переменной ptr_age: 0x7ffd5e8e9944
Значение, на которое указывает ptr_age: 25

See how the address stored in ptr_age matches the address of age? Это потому, что ptr_age указывает на age!

Как работает вызов функции по ссылке в C?

Теперь, когда мы понимаем указатели, мы можем investigate function calls by reference. When we call a function by reference, we're passing the address of a variable to the function, rather than its value. Это позволяет функции напрямую изменять исходную переменную.

Давайте посмотрим на пример:

#include <stdio.h>

void increment(int *num) {
(*num)++;
}

int main() {
int x = 5;
printf("До инкремента: x = %d\n", x);
increment(&x);
printf("После инкремента: x = %d\n", x);
return 0;
}

В этом коде мы передаем адрес x функции increment. Функция затем использует этот адрес, чтобы напрямую изменить значение x.

Вывод будет следующим:

До инкремента: x = 5
После инкремента: x = 6

Функция increment смогла изменить значение x в функции main, потому что она получила адрес x, а не только копию его значения.

Смешение вызова функции по значению и по ссылке

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

Вот пример:

#include <stdio.h>

void modify(int *a, int b, int *c) {
(*a)++;
b++;
(*c)++;
}

int main() {
int x = 1, y = 2, z = 3;
printf("До изменения: x = %d, y = %d, z = %d\n", x, y, z);
modify(&x, y, &z);
printf("После изменения: x = %d, y = %d, z = %d\n", x, y, z);
return 0;
}

В этом примере x и z передаются по ссылке, а y - по значению.

Вывод будет следующим:

До изменения: x = 1, y = 2, z = 3
После изменения: x = 2, y = 2, z = 4

Обратите внимание, как x и z изменились, а y remained the same? Это потому, что функция получила только копию значения y, а не его адрес.

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

Aspect Вызов по значению Вызов по ссылке
Что передается Кopia значения Адрес переменной
Можно изменять originals Нет Да
Синтаксис function(variable) function(&variable)
Параметр функции Обычная переменная Указатель

И вот и все! Мы рассмотрели основы вызова функции по ссылке в C. Помните, как и при обучении любому новому навыку, практика ключ к успеху. Попробуйте написать свои функции, использующие вызов по ссылке, и экспериментируйте с различными сценариями. Before you know it, вы будете манипулировать адресами памяти, как профессионaл!

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

Credits: Image by storyset