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

Что такое int & mean

Вопрос С++,

Я знаю

int* foo(void)

foo вернет указатель на тип int

как насчет

int &foo(void)

что он возвращает?

Спасибо большое!

4b9b3361

Ответ 1

Возвращает ссылку на int. Ссылки похожи на указатели, но с некоторыми важными отличиями. Я бы рекомендовал вам ознакомиться с различиями между указателями, ссылками, объектами и примитивными типами данных.

"Эффективный С++" и "Более эффективный С++" (как Скотт Мейерс) имеют несколько хороших описаний различий и когда использовать указатели и ссылки.

EDIT: существует ряд ответов, говорящих о том, что "ссылки - это просто синтаксический сахар для упрощения обработки указателей". Они, безусловно, не.

Рассмотрим следующий код:

int a = 3;
int b = 4;
int* pointerToA = &a;
int* pointerToB = &b;
int* p = pointerToA;
p = pointerToB;
printf("%d %d %d\n", a, b, *p); // Prints 3 4 4
int& referenceToA = a;
int& referenceToB = b;
int& r = referenceToA;
r = referenceToB;
printf("%d %d %d\n", a, b, r); // Prints 4 4 4

Строка p = pointerToB изменяет значение p, то есть теперь указывает на другую часть памяти.

r = referenceToB делает что-то совершенно другое: он присваивает значение b, где раньше использовалось значение a. Он не не меняет r вообще. r по-прежнему относится к одной и той же части памяти.

Разница тонкая, но очень важная.

Если вы все еще считаете, что ссылки - это просто синтаксический сахар для обработки указателей, пожалуйста, прочитайте книги Скотта Мейерса. Он может объяснить разницу намного лучше, чем я могу.

Ответ 2

Будьте осторожны здесь... вы идете по линии C/С++. Там довольно четкое различие, но оно не всегда выглядит так:

С++: это часто означает ссылку. Например, рассмотрим:

void func(int &x)
{
   x = 4;
}

void callfunc()
{
    int x = 7;
    func(x);
}

Таким образом, С++ может пройти по значению или перейти по ссылке.

C, однако не имеет такого прохода по ссылочной функциональности. и означает "addressof" и является способом формулировки указателя из переменной. Однако учтите следующее:

void func(int* x)
{
   *x = 4;
}

void callfunc()
{
    int x = 7;
    func(&x);
}

Обманчиво похожи, но принципиально разные. То, что вы делаете в C, передается копия указателя. Теперь эти вещи все еще указывают на одну и ту же область памяти, поэтому эффект похож на проход по ссылке в терминах направленной памяти, но это не ссылочная информация. Это ссылка на точку в памяти.

Попробуйте это (скомпилируйте как C):

#include <stdio.h>

void addptr(int* x)
{
    printf("Add-ptr scope 1:\n");
    printf("Addr: %p\n", x);
    printf("Pointed-to-memory: %d\n", *x);
    *x = *x + 7;
    x++;
    printf("Add-ptr scope 2:\n");
    printf("Addr: %p\n", x);
    printf("Pointed-to-memory: %d\n", *x);
}

int main(int argc, char** argv)
{
    int a = 7;
    int *y = &a;
    printf("Main-Scope 2:\n");
    printf("Addr: %p\n", y);
    printf("Pointed-to-memory: %d\n", *y);
    addptr(y);
    printf("Main-Scope 2:\n");
    printf("Addr: %p\n", y);
    printf("Pointed-to-memory: %d\n", *y);
    return 0;

}

Если C прошел по ссылке, адрес входящего указателя, если он изменен на addptr, должен быть отражен в main, но это не так. Указатели по-прежнему являются значениями.

Итак, C не имеет никакого механизма передачи по ссылке. В С++ это существует, и это то, что и есть в аргументах функции и т.д.

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

Как вы можете переустановить ссылку, чтобы сделать он ссылается на другой объект?

Ни в коем случае.

Вы не можете отделить ссылку от референт.

В отличие от указателя, как только ссылка связанный с объектом, он не может быть "переустановлен" на другой объект. ссылка сама по себе не является объектом (она не имеет идентичности; принимая адрес ссылка дает вам адрес референт; помните: ссылка является его референтом).

В этом смысле ссылка аналогична к указателю const, такому как int * const p (в отличие от указателя на const таких как int const * p). Но, пожалуйста не путайте ссылки с указатели; они сильно отличаются от точка зрения программиста.

По запросу, при возврате ссылок:

#include <iostream>

using namespace std;

int& function(int f)
{
   f=f+3;
   return f;
}

int main(int argc, char** argv)
{
    int x = 7;
    int y;
    y = function(x);
    cout << "Input: " << x << endl;
    cout << "Output:" << y << endl;
    return 0;
}

Любой хороший компилятор должен дать вам это предупреждающее сообщение в той или иной форме:

exp.cpp: 7: 11: warning: ссылка на стекную память, связанную с локальной переменной     'f' возвращен

Что это значит? Ну, мы знаем, что аргументы функции вставляются в стек (обратите внимание: на самом деле не на x64, они попадают в регистры, а затем в стек, но они находятся в стеке буквально на x86), и что это предупреждение говорит о том, что создание ссылки на такие объект не является хорошей идеей, потому что он не гарантированно остается на месте. Дело в том, что это просто удача.

Итак, что дает? Попробуйте эту измененную версию:

#include <iostream>

using namespace std;

int& function(int& f)
{
    f=f+3;
    return f;
}

int main(int argc, char** argv)
{
    int x = 7;
    int y;
    y = function(x);
    cout << "Input: " << x << endl;
    cout << "Output:" << y << endl;
    return 0;
}

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

Ответ 3

Он возвращает ссылку на переменную int.

Ответ 4

Из комментариев Альфреда

Вот что говорит документ: Техасский инструмент TMS320C28x C/С++ компилятор intrinsics, стр. 122, int & __ byte (int, unsigned int), Я думаю, это отличается от ПК - Альфред Чжун

Из руководства:

int & __ byte (int * array, unsigned int byte_index);

MOVB array [byte_index].LSB, src

Самый младший адресный блок в C28x - 16 бит. Поэтому обычно вы не можете получить доступ к 8-битовому MOVB dst, array [byte_index]. Объекты LSB выходят из памяти. Эта встроенная функция позволяет получить доступ к 8-разрядному количеству из памяти и может быть вызвана следующим образом:

__ байт (массив, 5) = 10;
b = __byte (массив, 20);

Это означает, что функция возвращает ссылку на целое число, которое действует как 8-битное количество. Поскольку значение является модификацией ссылки, будет изменен объект в команде назначения (так же как и MOVB), а при назначении b будет копироваться (точно так же, как MOVB) в пункт назначения.

Ответ 5

Этот вопрос вообще не является C/С++, так как C не имеет ссылок, только указатели. Int & является ссылкой на int. Кроме того, вам не нужно void, это может быть просто int& foo();

Ответ 6

просто играя с переменными, чтобы показать вам значение

int i = 5;
int * pI = &i;
int & referenceToI = * pI;
referenceToI = 4; // now i == 4

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