Это проблема терминологии, в основном.
«Объект» (я использую этот термин для обозначения «порции оперативной памяти») передается значением , когда вызываемая функция получает копию порции. Он передается ссылкой , когда вызываемая функция получает доступ к единственному фрагменту.
Учтите это:
void f(int x)
{
x = 42;
}
void g()
{
int y = 54;
f(y);
// here "y" still has value 54
}
Здесь функция f()
изменяет x
, но это ее собственная x
, переменная, которая содержит копию содержимого переменной y
g()
. То, что f()
делает со своим x
, не влияет на то, что содержит y
из g()
. Переменная затем передается по значению.
C ++ имеет понятие ссылки, которое выглядит так:
void f(int& x)
{
x = 42;
}
void g()
{
int y = 54;
f(y);
// here "y" now has value 42
}
Здесь специальная конструкция (с "&
") предписывает компилятору C ++ воспроизводить некоторые скрытые трюки, так что x
, известный по f()
, на самом деле является своего рода псевдонимом для используемой переменной y
на g()
. Существует только одна переменная: x
и y
обозначают один и тот же кусок оперативной памяти. Переменная здесь передается по ссылке.
Теперь рассмотрим "C-строку". В C (и C ++) строка - это просто набор char
значений, последнее из которых имеет значение 0 (это обычный терминатор строки). Код не обрабатывает строки напрямую; он использует указатели . Указатель - это значение, которое фактически обозначает размещение в оперативной памяти. Указатель не является строкой; указатель является видом числа (обычно на 32 или 64 бита, это зависит от типа процессора и операционной системы), который указывает, где в ОЗУ находится первый char
строки. Поэтому, когда вы вызываете strcpy()
, вы фактически указываете на него указатели (один для целевого буфера, один для исходной строки). Эти указатели не изменены: исходная строка и целевые буферы не перемещаются в процессе; только содержимое строки копируется в целевой буфер.
Следовательно, strcpy()
не нужно иметь доступ к переменным, которые содержат указатели в коде вызывающей стороны. strcpy()
нужно только знать, где находится буфер назначения и исходные строки в ОЗУ. Достаточно дать копию значений указателя на strcpy()
. Следовательно, эти указатели передаются по значению.
Обратите внимание, что при наличии указателей необходимо учитывать два объекта: переменную, содержащую указатель, и часть ОЗУ, на которую указывает указатель. Сам указатель передается по значению (strcpy()
получает свою собственную копию переменной, которая содержит указатель на буфер назначения). Можно сказать, что указанный в ОЗУ блок (целевой буфер) «передается по ссылке», поскольку он не дублируется в процессе, и вызываемая функция (strcpy()
) может его изменить. Дело в том, что термин «ссылка» имеет два различных значения:
Синтаксис C ++, означающий: «ссылка» обозначает специальную конструкцию с «&
», который я описал выше.
Формальное значение теории языка: «ссылка» обозначает способ косвенного обозначения значения, чтобы вызывающий и вызываемый абоненты могли получить доступ к одному и тому же фрагменту ОЗУ под разными именами. В этом смысле передача по значению указателя на вызываемую функцию эквивалентна передаче по ссылке куска ОЗУ, на который указывает указатель.
C ++ «ссылка» (первое значение) - это синтаксический способ передачи «по ссылке» (второе значение) переменной.