Если C не поддерживает передачу переменной ссылкой, почему это работает?
#include <stdio.h>
void f(int *j) {
(*j)++;
}
int main() {
int i = 20;
int *p = &i;
f(p);
printf("i = %d\n", i);
return 0;
}
$ gcc -std=c99 test.c
$ a.exe
i = 21
Потому что передается значение указателя на метод, а затем происходит его разыменование, чтобы получить целое число, на которое он указывает.
«Передавать по ссылке» (с использованием указателей) было в C с самого начала. Как вы думаете, почему это не так?
В C для передачи по ссылке вы используете оператор адреса &
, который следует использовать против переменной, но в вашем случае, поскольку вы использовали переменную-указатель p
, вам не нужно добавлять к ней префикс оператора адреса. Это было бы верно, если бы вы использовали & i
в качестве параметра: f (& i)
.
Вы также можете добавить это к разыменованию p
и посмотреть, как это значение соответствует i
:
printf("p=%d \n",*p);
Потому что вы передаете указатель (адрес памяти) переменной p в функцию f. Другими словами, вы передаете указатель, а не ссылку.
-121--621929-Вы передаете указатель (адресное расположение) по значению .
Это как сказать «вот место с данными, которые я хочу, чтобы вы обновили»
. -121--621932-Вы не передаете int по ссылке, вы передаете указатель на int по значению. Другой синтаксис, одно и то же значение.
Потому что вы передаете указатель (адрес памяти) на переменную p в функцию f. Другими словами, вы передаете указатель, а не ссылку.
В C нет передачи по ссылке, но p "ссылается" на i, и вы передаете p по значению.
p - переменная-указатель. Его значение - это адрес i. Когда вы вызываете f, вы передаете значение p, которое является адресом i.
Вы передаете указатель (расположение адреса) по значению .
Это все равно, что сказать: «Вот место с данными, которые я хочу, чтобы вы обновили».
Ваш пример работает, потому что вы передаете адрес своей переменной функции, которая манипулирует ее значением с помощью оператора разыменования .
Хотя C не поддерживает ссылочных типов данных , вы все равно можете имитировать передачу по ссылке, явно передавая значения указателя, как в вашем примере.
Ссылочный тип данных C ++ менее мощный, но считается более безопасным, чем тип указателя, унаследованный от C. Это будет ваш пример, адаптированный для использования ссылок C ++ :
void f(int &j) {
j++;
}
int main() {
int i = 20;
f(i);
printf("i = %d\n", i);
return 0;
}
Потому что в приведенном выше коде нет передачи по ссылке. Использование указателей (например, void func (int * p)
) - это передача по адресу.
Это передача по ссылке в C ++ (не будет работать в C):
void func(int& ref) {ref = 4;}
...
int a;
func(a);
// a is 4 now
В языке C передача по ссылке моделируется путем передачи адреса переменной (указатель) и разыменованием этого адрес внутри функции для чтения или записи фактической переменной. Это будет будет называться "стиль Си pass-by-reference."