Об召唤е функции по ссылке в C
Здравствуйте, будущие программисты! Сегодня мы отправимся в увлекательное путешествие в мир программирования на языке C,Specifically exploring the concept of "Function Call by Reference." Не волнуйтесь, если вы новички в программировании; я буду вести вас шаг за шагом, как я делал это для countless students over my years of teaching. Так что возьмите любимый напиток, удобно расположитесь и погружайтесь с нами!
Оператор адреса (&) в 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