Вот пример, который я использовал ранее. Примут следующие две функций:
void foo(T *p) // where T is an arbitrary data type
{
*p = new_value(); // write new value to the thing p points to
}
void bar(void)
{
T var;
foo(&var); // write new value to var
}
Для функции foo
обновить содержимое var
(объекта типа T
) мы должны передать указатель на var
(типа T *
).
Если заменить T
с типом указателя P *
, то приведенный выше код становится
void foo(P **p)
{
*p = new_value(); // write new value to the thing p points to
}
void bar(void)
{
P *var;
foo(&var); // write new value to var
}
Семантика точно так же; мы хотим, чтобы foo
, чтобы написать новое значение var
, поэтому мы передаем указатель на var
. Это просто, что в этом случае var
уже является типом указателя, поэтому мы завершаем передачу указателя на указатель.
В принципе, для foo
обновить содержимое var
, вы должны пройти выражение&var
в качестве аргумента, то есть тип формального параметра p
всегда будет иметь еще один уровень косвенности, чем тип var
.
Type of var Type of &var Type of p
----------- ------------ ---------
T T * T *
T * T ** T **
T ** T *** T ***
т.д.
Технически C не ничего, кроме пройти по стоимости поддержки. –
@JoachimPileborg: «Технически»? В каком аспекте он поддерживает передачу по ссылке больше, чем любой другой язык, дополняющий формулировку? – Olaf
C, C++, Java и любой язык, который я когда-либо слышал о том, что использует pass by value. Но вы можете передавать ссылки (или указатели) по значению, что делает его несколько запутанным. – alain