Подтвердить что ты не робот

Использование оператора & в сигнатурах функций С++

Я сейчас читаю Accelerated С++, и я понял, что я действительно не понимаю, как и работает в подписях функций.

int* ptr=#

означает, что ptr теперь содержит адрес num, но что это значит?

void DoSomething(string& str)

из того, что я понимаю, это пропуск по ссылке переменной (что означает передачу адреса), но когда я делаю

void DoSomething(string& str)
{
  string copy=str;
}

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

Что здесь происходит? И в чем смысл использования вызовов * и и в функциях?

4b9b3361

Ответ 1

Ссылка не указатель, они разные, хотя они служат схожим назначением. Вы можете рассматривать ссылку как псевдоним другой переменной, то есть вторую переменную, имеющую тот же адрес. Он не содержит самого адреса, он просто ссылается на ту же часть памяти, что и переменная, из которой она была инициализирована.

So

string s = "Hello, wordl";
string* p = &s; // Here you get an address of s
string& r = s; // Here, r is a reference to s    

s = "Hello, world"; // corrected
assert( s == *p ); // this should be familiar to you, dereferencing a pointer
assert( s == r ); // this will always be true, they are twins, or the same thing rather

string copy1 = *p; // this is to make a copy using a pointer
string copy = r; // this is what you saw, hope now you understand it better.

Ответ 2

Символ & в С++ - это двойное назначение. Это может означать (по крайней мере)

  • Возьмите адрес значения
  • Объявить ссылку на тип

Использование, которое вы имеете в виду в сигнатуре функции, является экземпляром # 2. Параметр string& str является ссылкой на экземпляр string. Это не ограничивается только сигнатурами функций, это может происходить и в телах методов.

void Example() {
  string s1 = "example";
  string& s2 = s1;  // s2 is now a reference to s1
}

Я бы порекомендовал проверить запись в С++ FAQ по ссылкам, поскольку это хорошее введение в них.

Ответ 3

Вы не должны знать ничего о указателях, пока не попадете в главу 10 ускоренного С++!

Ссылка создает другое имя, псевдоним, для чего-то, что существует в другом месте. Это. Нет скрытых указателей или адресов. Не смотрите за занавеской!

Подумайте о парне по имени Роберт

guy   Robert;

Иногда вы можете позвонить ему Bob

guy& Bob = Robert;

Теперь Боб и Роберт оба относятся к тому же парню. Вы не получаете его адрес (или номер телефона), просто другое имя для одного и того же.

В вашей функции

void DoSomething(string& str)
{
  string copy=str;
}

он работает точно так же, str - это другое имя для некоторой строки, которая существует где-то еще.

Не беспокойтесь, как это происходит, просто подумайте о ссылке как имени для какого-либо объекта. Компилятор должен выяснить, как соединить имена, вам не нужно.

Ответ 4

В случае назначения переменных (т.е. int* ptr = &value) использование амперсанда вернет адрес вашей переменной (в данном случае адрес value).

В параметрах функции использование амперсанда означает, что вы передаете доступ или ссылку на одну и ту же физическую область в памяти переменной (если вы ее не используете, вместо нее отправляется копия). Если вы используете звездочку как часть параметра, вы указываете, что вы передаете указатель переменной, который достигнет почти того же. Разница здесь в том, что с амперсандом у вас будет прямой доступ к переменной через имя, но если вы передадите указатель, вы должны будете deference указатель на получение и управление фактическим значением

void increase1(int &value) {
   value++;
}

void increase2(int *value) {
   (*value)++;
} 

void increase3(int value) {
   value++;
}

Обратите внимание, что increase3 ничего не делает с исходным значением, которое вы передаете, потому что отправляется только копия:

int main() {
   int number = 5;
   increase1(number);
   increase2(&number);
   increase3(number);
   return 0;
}

Значение number в конце 3 вызовов функции равно 7, а не 8.

Ответ 5

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

Вы часто увидите параметр типа const string & который выполняется для служебных целей, поскольку внутренняя ссылка не создает копию строки.

Ответ 6

int* ptr=#

1-й случай: поскольку ptr является памятью и хранит адрес переменной. Оператор и возвращает адрес num в памяти.

void DoSomething(string& str)

Второй случай: оператор амперсанда используется, чтобы показать, что переменная передается по ссылке и может быть изменена функцией.

Итак, в основном оператор и имеет 2 функции в зависимости от контекста.

Ответ 7

В то время как передача по ссылке может быть реализована компилятором, передавая адрес как указатель, семантически это не имеет никакого отношения к адресам или указателям. в простых терминах это просто псевдоним переменной.

В С++ много случаев, когда синтаксис повторно используется в разных контекстах с другой семантикой, и это один из таких случаев.

Ответ 8

В случае:

int* ptr=#

вы объявляете переменную с именем ptr с типом int * (int pointer) и устанавливаете ее значение в "адрес переменной num" (&num). Оператор "addressof" (&) возвращает указатель.

В случае:

void DoSomething(string& str)

вы объявляете первый параметр метода DoSomething() для типа "ссылка на строку". Эффективно это С++ способ определения "pass-by-reference".

Обратите внимание, что хотя оператор & работает в аналогично в этих случаях, он не действует точно так же. В частности, при использовании в качестве оператора вы говорите компилятору, что он должен указывать адрес указанной переменной; при использовании в сигнатуре метода вы сообщаете компилятору, что аргумент является ссылкой. И обратите внимание также, что бит "аргумент как ссылка" отличается от аргумента, который является указателем; ссылочный аргумент (&) автоматически разыменовывается и никогда не подвергается воздействию способа относительно того, где хранятся базовые данные; с аргументом указателя, вы все еще передаете по ссылке, но вы подвергаетесь методу, в котором хранится переменная, и потенциально подвергая проблемы, если метод не выполняет разыменования (что происходит чаще, чем вы думаете).

Ответ 9

Вы неявно создаете копию copy из str. Да, str является ссылкой, но это не значит, что вы не можете построить из него другой объект. В С++ оператор & означает одну из трех вещей -

  • Когда вы определяете нормальную ссылку , вы создаете псевдоним для объекта.
  • Когда вы используете его в функции paramater, он передается по ссылке. Вы также создаете псевдоним объекта, как и для копии. Вы не замечаете никакой разницы в этом случае, потому что в основном есть объект, который вы ему передали. Это делает, когда те объекты, которые вы передаете, содержат указатели и т.д.
  • Последним (и в основном не имеющим значения для вашего случая) значением & является побитовое И.

Еще один способ подумать о ссылке (хотя и немного некорректной) - это синтаксический сахар для разыменованного указателя.