Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.59/34: Рейтинг темы: голосов - 34, средняя оценка - 4.59
0 / 0 / 0
Регистрация: 11.11.2018
Сообщений: 59

Int& foo() и int foo()

08.02.2019, 02:05. Показов 7272. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
При передаче переменной по ссылке все понятно. Но я не пойму логики возвращения по ссылке. Например:
C++
1
2
3
4
5
6
7
8
9
10
int& foo(int a)
{
   return a;
}
 
 
int main()
{
   int b = foo(); // int = int &   ?
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.02.2019, 02:05
Ответы с готовыми решениями:

Где может быть использована сигнатура int& foo()=7
Друзья, это чисто теоретический вопрос. Подскажите где может быть использована такая функция. Какой в этом практический смысл? ...

int const * const foo(const int* param) const - разъясните значение квалификаторов
int const * const foo(const int* param) const -----1------2----------3----------------4 1: ? 2: делает содержимое массива или...

Напишите функцию f(int& m1, int& m0, int N), которая воз- вращает первую и последнюю цифры двузначного натурального числа N
Напишите функцию f(int& m1, int& m0, int N), которая воз- вращает первую и последнюю цифры двузначного натурального числа N. Решение. ...

20
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
08.02.2019, 02:27
Цитата Сообщение от Евгений323 Посмотреть сообщение
foo()
Тут ошибка в коде: вы ничего не передаёте в функцию.
0
0 / 0 / 0
Регистрация: 11.11.2018
Сообщений: 59
08.02.2019, 02:52  [ТС]
Извиняюсь, ошибка при написании, код вырван из контекста, foo(10); например. Мне бы главное понять суть возвращения int&.

Добавлено через 4 минуты
Исходя из моих знаний int &ref = a допускается, т.к это ссылка, а int b = &a - нет. Как происходит присваивание int = int &?
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
08.02.2019, 03:11
Цитата Сообщение от Евгений323 Посмотреть сообщение
Как происходит присваивание int = int &?
тут происходит просто копирование, как и в int = int

Добавлено через 1 минуту
Цитата Сообщение от Евгений323 Посмотреть сообщение
int b = &a
так как & в этом контексте значит взятие адреса( int * pa = &a; )

Добавлено через 4 минуты
Цитата Сообщение от Евгений323 Посмотреть сообщение
Мне бы главное понять суть возвращения int&.
Функция вернет указатель на параметр. В вашем примере этого ошибка, так как в функции foo параметр a - локальная переменная, и выйдя из функции она уничтожится, значит foo() вернет ссылку на невалидную область.
0
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187
08.02.2019, 03:17
Цитата Сообщение от Евгений323 Посмотреть сообщение
Мне бы главное понять суть возвращения int&.
например:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
int b = 10;
int &foo() {
    return b;
}
int main() {
    cout << b << endl;
    foo() = 12;
    cout << b << endl;
    system("pause");
}
Добавлено через 4 минуты
Цитата Сообщение от Евгений323 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
int& foo(int a)
{
return a;
}
int main()
{
int b = foo(); // int = int & * 
}
C++
1
2
3
4
5
6
7
8
int& foo(int a)
{
return a;
}
int main()
{
int *b = foo(); // так все ок должно быть вы же возвращаете ссылку
}
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
08.02.2019, 03:20
Цитата Сообщение от Pavel250 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
int& foo(int a)
{
return a;
}
int main()
{
int *b = foo(); // так все ок должно быть вы же возвращаете ссылку
}
Это невалидный код, b указывает вникуда
0
51 / 37 / 14
Регистрация: 05.08.2016
Сообщений: 187
08.02.2019, 03:24
Согласен, ошибся, переменную а нужно объявить раньше.
0
-47 / 3 / 0
Регистрация: 31.12.2017
Сообщений: 204
08.02.2019, 04:05
Цитата Сообщение от lArtl Посмотреть сообщение
Функция вернет указатель на параметр. В вашем примере этого ошибка, так как в функции foo параметр a - локальная переменная, и выйдя из функции она уничтожится, значит foo() вернет ссылку на невалидную область.
Да, действительно, a — это локальная переменная, но она не уничтожится сразу при выходе из функции.
Цитата Сообщение от lArtl Посмотреть сообщение
В вашем примере этого ошибка
Ошибка была только в том, что в функцию ничего не передавалось. Эта ошибка уже исправлена. Никакой другой ошибки нет.

Добавлено через 9 минут
Цитата Сообщение от Евгений323 Посмотреть сообщение
int &ref = a допускается
Допускается. Потому что это способ объявления ссылки.
Цитата Сообщение от Евгений323 Посмотреть сообщение
int b = &a - нет
В данном примере амперсанд справа от = используется для взятия адреса области памяти, которую занимает (уже существующий) объект a. То есть сначала вычисляется значение выражения &a (и это значение имеет тип указателя на int). После этого вы пытаетесь присвоить переменной типа int полученный адрес типа указателя на int, что и приводит к ошибке.
0
08.02.2019, 06:07
 Комментарий модератора 
lArtl, первое и последнее предупреждение: Выбирайте выражения, а то Вас крепко заносит.
Jzx, lArtl, разборки и словоблудие прекращаем.
Заранее благодарен за пониманием и сотрудничество с администрацией.
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
08.02.2019, 06:59
Цитата Сообщение от Jzx Посмотреть сообщение
Ошибка была только в том, что в функцию ничего не передавалось. Эта ошибка уже исправлена. Никакой другой ошибки нет.
Это UB. То, что оно каким то чудом компилируется в vc++ и что-то даже вменяемое выведет - просто чудо.

Добавлено через 1 минуту
Цитата Сообщение от Lord_Voodoo Посмотреть сообщение
lArtl, первое и последнее предупреждение: Выбирайте выражения, а то Вас крепко заносит.
Больше не буду.(

Добавлено через 3 минуты
Цитата Сообщение от Jzx Посмотреть сообщение
Да, действительно, a — это локальная переменная, но она не уничтожится сразу при выходе из функции.
Под выходом из функции я также подразумеваю очистку стэка.
0
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
08.02.2019, 10:37
lArtl,
Цитата Сообщение от lArtl Посмотреть сообщение
Функция вернет указатель на параметр. В вашем примере этого ошибка, так как в функции foo параметр a - локальная переменная, и выйдя из функции она уничтожится, значит foo() вернет ссылку на невалидную область.
Локальная переменная хранится действительно в стеке, а вот под возвращаемое значение резервируется память в другом месте, например в x86 возвращаемое значение передается через регистр EAX. То есть передается копия локальной переменной. Именно поэтому в С/С++ функции важно знать явную сигнатуру, чтобы знать сколько памяти резервировать.
Цитата Сообщение от lArtl Посмотреть сообщение
Под выходом из функции я также подразумеваю очистку стэка.
При выходе из функции стек не чистится, просто указатель на позицию в стеке падает вниз. Именно поэтому желатьльно переменные объявляемые локально инициализировать явно иначе они будут иметь значения мусора от предыдущих функций.
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
08.02.2019, 11:23
Цитата Сообщение от _SayHello Посмотреть сообщение
Локальная переменная хранится действительно в стеке, а вот под возвращаемое значение резервируется память в другом месте, например в x86 возвращаемое значение передается через регистр EAX. То есть передается копия локальной переменной. Именно поэтому в С/С++ функции важно знать явную сигнатуру, чтобы знать сколько памяти резервировать.
в EAX будет ссылка на локальную переменную
Цитата Сообщение от _SayHello Посмотреть сообщение
При выходе из функции стек не чистится, просто указатель на позицию в стеке падает вниз. Именно поэтому желатьльно переменные объявляемые локально инициализировать явно иначе они будут иметь значения мусора от предыдущих функций.
Именно это я и имел ввиду.

Добавлено через 21 минуту
ассемблерный выхлоп для
C++
1
2
3
4
5
6
7
8
9
int& foo(int a)
{
   return a;
}
 
int main()
{
   int b = foo(10);
}
и
C++
1
2
3
4
5
6
7
8
9
int* foo(int a)
{
   return &a;
}
 
int main()
{
   int b = *foo(10);
}
будет одинаковым.

Добавлено через 2 минуты
И надеюсь не надо еще кому то пояснять, что это все собирается без оптимизаций...
0
Форумчанин
Эксперт CЭксперт С++
 Аватар для MrGluck
8216 / 5047 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
08.02.2019, 11:31
Вы возвращается ссылку на локальную переменную, что является ошибкой т.к. время жизни локальной переменной ограничено телом функции. То есть не гарантируется, что когда вы попытаетесь работать с данными, полученными из функции, там будет содержаться тот же результат, что и в бывшей локальной переменной внутри функции.
Это UB.
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
08.02.2019, 11:32
Цитата Сообщение от lArtl Посмотреть сообщение
в EAX будет ссылка на локальную переменную
0 — это ссылка на локальную переменную? https://godbolt.org/z/80fy15
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
08.02.2019, 11:45
Цитата Сообщение от rat0r Посмотреть сообщение
0 — это ссылка на локальную переменную? https://godbolt.org/z/80fy15
можешь еще с компиляторами поиграть, vc++ туда что-то положит, gcc 4.9.4 тоже, clang там тоже будет ссылка на локальную переменную и тд

Добавлено через 9 минут
Попробуйте с
C++
1
2
3
4
5
6
7
8
9
int* foo(int a)
{
   return &a;
}
 
int main()
{
   int b = *foo(10);
}
в (e|r)ax по прежнему будет класться 0, хотя как так то... У a точно на тот момент есть адресс
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
08.02.2019, 12:11
Цитата Сообщение от lArtl Посмотреть сообщение
будет класться 0, хотя как так то...
UB же. Компилятор в своем праве реализовать неопределенное поведение так, как ему удобнее.
А ноль передать именно удобнее, т.к. это поможет быстрее обнаружить ошибку.
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
08.02.2019, 12:15
Цитата Сообщение от DrOffset Посмотреть сообщение
UB же.
Про UB упоминалось еще в 10 посте... Просто отвечал на вопрос...
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
08.02.2019, 12:19
Цитата Сообщение от lArtl Посмотреть сообщение
Просто отвечал на вопрос...
Я тоже.
Вопрос "Как так-то возвращается ноль, когда адрес у переменной есть".
Ответ: возвращается ноль, потому что возврат адреса в этом случае был бы ошибкой.
А раз любой возврат адреса в этом случае - ошибка, то лучше вернуть ноль, т.к., в отличие от любого адреса, ноль - можно легко увидеть как отладчиком, так и косвенно по последующему разыменованию с падением.
0
0 / 0 / 0
Регистрация: 13.12.2018
Сообщений: 28
08.02.2019, 12:58
Хорошо, выяснили что бред использовать данную форму записи т.к переменная локальная и мы вернём адрес на локальную переменную которой уже нет. А теперь вопрос вот в чём, почему в cout << Foo(10); выводится не адресс, а переменная?
0
322 / 174 / 78
Регистрация: 09.10.2014
Сообщений: 809
08.02.2019, 13:07
Цитата Сообщение от DoreinLore Посмотреть сообщение
Хорошо, выяснили что бред использовать данную форму записи т.к переменная локальная и мы вернём адрес на локальную переменную которой уже нет. А теперь вопрос вот в чём, почему в cout << Foo(10); выводится не адресс, а переменная?
Потому что это UB!!111

Добавлено через 2 минуты
в случае с
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
int b = 10;
int &foo() {
    return b;
}
int main() {
    cout << b << endl;
    foo() = 12;
    cout << b << endl;
    system("pause");
}
функция возвращает ссылку. Ссылка != Указатель.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
08.02.2019, 13:07
Помогаю со студенческими работами здесь

Foo::foo(): x(dx), y(dy) {}; Зачем
Очень часто видел конструктор типа Foo::foo(): x(dx), y(dy) {}; Сам использовал только в инициализации структур. Какие отличия от...

Пусть объявлена функция void f(int i,int &j){.}. Параметр j является параметром
1)Пусть объявлена функция void f(int i,int &amp;j){...}. Параметр j является параметром a. по адресу b. по ссылке c. по значению ...

Как передать 0 в функцию типа f (int, int&)
Подскажите, почему при повторных вызовах f остается предыдущее значение S? Т.е. не обнуляется в теле f - {...s=0...} и как его обнулить?...

Error LNK2019: unresolved external symbol "public: __thiscall Vector<int>::Vector<int>(int,int,int)" (?0?$Vec
Вот есть заголовочный файл // Заголовочный файл Vector.h #ifndef VECTOR_H #define VECTOR_H #include &lt;iostream&gt; using...

в чем разница между void f(int &n) и void f(int &&n)
:help:


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru