C ++ Почему для вызова strcpy () не нужен вызов по ссылке - PullRequest
3 голосов
/ 11 мая 2010

У меня есть домашнее задание с несколькими вопросами. Спрашивается, почему функция strcpy () не нуждается в операторе вызова по ссылке для CStrings Я много раз просматривал книгу и не могу найти ответ на этот вопрос. Может ли кто-нибудь помочь мне объяснить это?

Это своего рода массив, поэтому я думаю, что вам понадобится вызов по ссылке.

Ответы [ 7 ]

3 голосов
/ 11 мая 2010

strcpy() принимает указатель до char .

Таким образом, вы не передаете «строку» как параметр, а только адрес ее первого символа.

Так что в основном у вас есть что-то вроде этого:

void func(const char* str);

const char* str = "abc";
func(str); // Here str isn't passed by reference but since str is a pointer to the first character ('a' here), you don't need a reference.

Быстрая передача указателя. В 32-битной архитектуре указатель занимает 32 бита независимо от длины указанной строки.

2 голосов
/ 11 мая 2010

Это проблема терминологии, в основном.

«Объект» (я использую этот термин для обозначения «порции оперативной памяти») передается значением , когда вызываемая функция получает копию порции. Он передается ссылкой , когда вызываемая функция получает доступ к единственному фрагменту.

Учтите это:

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 ++ «ссылка» (первое значение) - это синтаксический способ передачи «по ссылке» (второе значение) переменной.

2 голосов
/ 11 мая 2010

Если вы имеете в виду class CString, то другими словами вам задается вопрос:

Почему эта компиляция?

CString sExample;
char buffer[LARGE_ENOUGH];

strcpy(buffer, sExample);

Ответ таков: class CString определяет оператор const char * и поэтому может быть преобразован в тип второго аргумента strcpy.

Я не уверен, что это то, что вы имеете в виду.

1 голос
/ 11 мая 2010

Хорошо, если вы имеете в виду c-strings (char *), вам не нужен вызов по ссылке, потому что сама строка является указателем. Таким образом, копирование строки знает, куда / откуда копировать строку.

0 голосов
/ 28 сентября 2011

автоматическое преобразование типов, это ответ, который, я думаю, они ищут. Глядя на это, вы можете помочь.

0 голосов
/ 11 мая 2010

Потому что в C при вызове функций массивы передаются как адрес первого элемента, что эквивалентно вызову по ссылке.

См. «Эксперт по программированию Питера Ван Дер Линдена», книга «Глубокие секреты».

0 голосов
/ 11 мая 2010

Потому что strcpy работает с char *, которые являются указателями. Указатель передается по значению, и strcpy использует этот указатель для доступа к отдельным символам в целевой строке и их изменения. Сравните это с передачей целого числа по значению - функция не может изменить исходное целое число.

Понимание того, что строки char * не похожи на целые числа, жизненно важно для того, чтобы вы не сходили с ума во время курса C ++. Хорошо сделано для вашего профессора, заставляя вас с этим сталкиваться.

...