Я постараюсь объяснить как с кодом, так и с простым английским :).Объяснение может быть длинным, но оно того стоит.
Предположим, у нас есть программа, выполняющая ее функцию main (), и мы вызываем другую функцию, которая принимает параметр int
.
Концептуально, когда вы передаете переменную в качестве параметра функции, вы можете сделать это (грубо говоря) двумя способами: по значению или по ссылке.
«По значению» означает предоставлениефункция копия вашей переменной.Функция получит свое «содержимое» (значение), но не сможет изменить фактическую переменную вне собственного тела кода, потому что ей была дана только копия.
«По ссылке»,с другой стороны, означает предоставление функции фактического адреса памяти нашей переменной.Используя это, функция может узнать значение переменной, но она также может перейти по указанному адресу и изменить содержимое переменной.
В нашей программе на C «по значению» означает передачу копии int
(просто принимая int
в качестве аргумента), а «по ссылке» означает передачу на него указателя.
Давайте рассмотрим небольшой пример кода:
void foo(int n) {
n = 10;
printf("%d\n", n);
}
int main() {
int n = 5;
foo(n);
printf("%d\n", n);
return 0;
}
Что будет выводомэта программа будет?10 10
?Нету.10 5
!Поскольку мы передали копию int
по значению, а не по ссылке, foo()
изменил только номер, сохраненный в ее копии, и не смог получить копию main()
.
Теперь, если мысделайте это следующим образом:
void foo(int* n) {
*n = 10;
printf("%d\n", *n);
}
int main() {
int n = 5;
foo(&n);
printf("%d\n", n);
return 0;
}
На этот раз мы дали foo()
наше целое число по ссылке: это фактический адрес памяти.foo()
обладает всеми возможностями для его изменения путем доступа к его положению в памяти, foo()
и main()
работают с одной и той же копией, и поэтому на выходе будет 10 10
.
Как видите,указатель - это ссылка, ... , но также числовая позиция в памяти .Это похоже на int
, только число, содержащееся внутри, интерпретируется по-разному.Подумайте об этом так: когда мы передаем наш int по ссылке, мы передаем указатель int по значению! .Таким образом, та же логика по значению / по ссылке может применяться к указателям, даже если они уже являются ссылками.
Если наша действительная переменная была не int, а ссылкой int (указатель), и мы хотели main()
и foo()
, чтобы поделиться той же копией этой ссылки, чтобы foo()
мог ее изменить, что бы мы делали?Почему, конечно, нам нужна ссылка на нашу ссылку!Указатель на указатель.То есть:
int n; /* integer */
int* n; /* integer reference(pointer). Stores an int's position in memory */
int** n; /* reference to integer reference, or double pointer.
Stores int*'s memory address so we can pass int*s by reference. */
Надеюсь, это было полезно.