Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/6: Рейтинг темы: голосов - 6, средняя оценка - 5.00
Unifan
0 / 0 / 0
Регистрация: 11.08.2014
Сообщений: 40
1

Ступор в возврате указателей и ссылок

15.08.2014, 17:22. Просмотров 1067. Ответов 19
Метки нет (Все метки)

Изучаю С++ базовый курс от Шилтда, все проходил на твердую четверку, и на предпоследней теме про системы ввода-вывода абсолютно запоролся про указатели и ссылки. И дело то не в том, что я не понимаю как использовать их (т.е. в качестве параметров функций и т.х), а в том, что я не понимаю, как работает функция, вовращающая их тип...
Товарищи программисты, прошу вас раз и навсегда объяснить мне в подробностях про функции, возвращающие указатели и ссылки.

Заранее спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.08.2014, 17:22
Ответы с готовыми решениями:

Особенности использования указателей и ссылок в C++ при возврате из функции
Пусть у нас есть некий класс CBase и есть функция, которая создает и...

Касательно указателей и ссылок.
Цитирую фразу из популярной ныне книги Айвора Хортона. "Никогда не возвращайте...

Сравнение указателей и ссылок.
Не совсем так для них компилятор вырабатывает разный ассемблерный код int...

Использование ссылок и указателей
Добрый вечер Помогите разобраться и понять «Использование ссылок и указателей»...

Совместное использование указателей и ссылок
int *ptr; int &ref = *ptr; ref = 1; Вот и весь вопрос. Ничего плохого в...

19
St1f1er
2 / 2 / 0
Регистрация: 08.08.2014
Сообщений: 14
15.08.2014, 17:53 2
Судя по вопросу нужно =) заново штудировать. И еще почитать про память чтоб понимать указатели. Обычная функция просто вернет указатель ( адресс в памяти)
0
Unifan
0 / 0 / 0
Регистрация: 11.08.2014
Сообщений: 40
15.08.2014, 18:03  [ТС] 3
Так на то это и ступор, ибо про указатели, да ссылки я знаю практически все ( то что в книге преполается ) и действие этих указателей, ровно также как и ссылок понимаю. Проблема в том, что до меня не доходит то, что именно возвращает в вызываемый код, посредством предложения return.
C++
1
2
3
4
5
6
7
8
return *a; // возвращает значение по адресу
return a; // возвращает адрес 
//-------------------------
int &func(//...) {
 //...
return &a; // что делает?
return a; // что делает?
}
Добавлено через 3 минуты
Пока сообщение писал, нервный ступор, заставлявший грызть ногти, начал утихать. Про указатели вроде бы сам понял, но про ссылки, особенно после таких предложений ( ostream &operator<<(ostream &stream_left, class_name obj_right ) понять не могу. То есть зачем поток должен возвращаться как ссылка? На что это вообще ссылка указывает?
0
A_Kamolins
4 / 4 / 5
Регистрация: 15.08.2014
Сообщений: 30
15.08.2014, 18:20 4
Лучший ответ Сообщение было отмечено Unifan как решение

Решение

Если a - это обычная переменная, то:
return &a; //Возвращает адрес этой переменной
return a; //Возвращает значение переменной

Если работаем с указателем
return *a; //Разыменование, т.е. возвращается значение, которое находится по адресу,который содержит указатель
return a; //Возвращается адрес, который содержит указатель

Добавлено через 3 минуты
По идее - тебе надо просто вникнуть в 2 вещи. Указатель, это как обычная переменная, которая может содержать адреса ячеек. Когда мы объявляем указатель, то перед его названием ставим звездочку.

C++
1
2
3
4
5
int *a; //объявляем указатель a, который может содержать адреса целочисленных переменных
int b = 30; //обычная целочисленная переменная, которой присвоили значение 30
a = &b; // &b - взятие адреса и присваивание его указателю a
 
cout << *a; //разыменовываем указатель, тоесть теперь он должен вывести то, что находится по адресу &b
0
Lynatik001
38 / 32 / 13
Регистрация: 28.09.2012
Сообщений: 626
15.08.2014, 18:24 5
Допустим у нас есть обьект окно проекта. Его нужно передать в функцию что бы она вывела через етот обьект на окно что-то. Но передавая не как ссылку мы создаем временный аналог окна который только существовал бы в функции, и при выходе с ее окно то бы уничтожалось. А то окно где надо было нарисовать- нечего бы не было. А когда мы передаем ссылку то мы передаем все то окно в котором надо нарисовать то-то, и оно изменяется.
тоже самое и указатель с ссылкой. Указатель передает только значение- не поменяется переменная если менять ее в функции, а с ссылкой поменяется

Добавлено через 1 минуту
A_Kamolins
ну да правильно
1
Unifan
0 / 0 / 0
Регистрация: 11.08.2014
Сообщений: 40
15.08.2014, 18:33  [ТС] 6
Спасибо, спасибо большое. Да, я понимаю зачем нужны параметры-ссылки или параметры указатели, но зачем нужны функции, коотрые предворены амперсандом(&), т. е. Почему мы не можем вернуть (return &переменная) без вышеперечисленного действия?
0
Lynatik001
38 / 32 / 13
Регистрация: 28.09.2012
Сообщений: 626
15.08.2014, 18:35 7
Цитата Сообщение от Unifan Посмотреть сообщение
Спасибо, спасибо большое. Да, я понимаю зачем нужны параметры-ссылки или параметры указатели, но зачем нужны функции, коотрые предворены амперсандом(&), т. е. Почему мы не можем вернуть (return &переменная) без вышеперечисленного действия?
Впервые вижу что бы перед функцией была ссылка.
0
A_Kamolins
4 / 4 / 5
Регистрация: 15.08.2014
Сообщений: 30
15.08.2014, 18:36 8
Не совсем понял ваш вопрос. Напишите какой-нибудь пример кодом и задайте по нему вопрос, думаю так будет проще понять вас
0
Unifan
0 / 0 / 0
Регистрация: 11.08.2014
Сообщений: 40
15.08.2014, 18:36  [ТС] 9
int &func (//...) {//...}
0
Lynatik001
38 / 32 / 13
Регистрация: 28.09.2012
Сообщений: 626
15.08.2014, 18:37 10
Цитата Сообщение от Unifan Посмотреть сообщение
Почему мы не можем вернуть (return &переменная) без вышеперечисленного действия?
во 1 покажите код функции, во 2 есть кнопочка С++ ложите код туда в эти теги написав на форуме
C++
1
вот пример
[ CPP ][ /CPP ] - без пропусков
0
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
15.08.2014, 18:39 11
В общем случае если функция принимает ссылку на обычную переменную или объект то вы работаете с этой переменной или объектом напрямую. То есть формальный параметер функции выступает псевдонимом настоящей переменной и не выполняется лишнего копирования как в случае передачи по значению(то есть без ссылки). Если говорить о возвращении:
C++
1
ostream& operator<<(ostream &stream_left, class_name obj_right )
в этом случае возвращается ссылка на объект так как он существует вне функции и это делается что бы лишний раз не происходило копирование во временный объект. Нужно помнить что возвращать ссылку на временный объект созданый в функцие нельзя, так как переменная на которую вы будете ссылатся будет уничтожена после завершения работы функции.

В случае указателя копирование выполняется всегда, т.к. указатель это обычная переменная типа "указатель на тип". Но в случае указателя копируется адрес переменной и если передать адрес например перемнной int x=77 в функцию которая принимает указатель на int то вы так же будете работать напрямую с этой переменной, но ссылки безпопаснее и удобнее в этом случае.
1
A_Kamolins
4 / 4 / 5
Регистрация: 15.08.2014
Сообщений: 30
15.08.2014, 18:40 12
этот & значит, что функция должна возвращать адрес переменной типа int всего навсего
0
Unifan
0 / 0 / 0
Регистрация: 11.08.2014
Сообщений: 40
15.08.2014, 18:43  [ТС] 13
Допустим у нас есть такой код.
Почему operator объявлен с амперсандом, как поток может возвращаться?
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
using namespace std;
 
class ThreeD {
public:
    int x, y, z;
    ThreeD(int a, int b, int c) { x = a; y = b; z = c; }
};
 
ostream &operator<<(ostream &stream, ThreeD obj)
{
    stream << obj.x << endl;
    stream << obj.y << endl;
    stream << obj.z << endl;
 
    return stream;
}
 
int main()
{
    ThreeD a(1, 2, 3);
    cout << a;
 
 
    system("pause");
    return 0;
}
0
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
15.08.2014, 18:47 14
Цитата Сообщение от Unifan Посмотреть сообщение
Почему operator объявлен с амперсандом, как поток может возвращаться?
C++
1
ostream& operator<<(ostream &stream, ThreeD obj)
Вот так думаю понятнее. Здесь возвращается ссылка на объект типа ostream.
1
Blueeyer
12 / 12 / 7
Регистрация: 09.10.2013
Сообщений: 222
15.08.2014, 18:49 15
Gwini, ну это до вас уже было сказано выше
0
Gwini
10 / 10 / 3
Регистрация: 08.03.2014
Сообщений: 70
15.08.2014, 18:58 16
Цитата Сообщение от Unifan Посмотреть сообщение
как поток может возвращаться?
он и не возвращается. Возвращается принятый функцией объект, например cout, cerr, clog. Этот обьект создан в файле iostream, то есть он существует еще до начала работы функции и возвращается ссылка на него что бы не было лишнего копирования.

Добавлено через 5 минут
Поток вообще здесь ни при чем. Он никуда не двигается, а открывается в случае работы с ним (например ты вводишь значение) и закрывается по ее завершению. А класы ostream и istream а также их наследники и базовый клас ios_base предоставляют методы для управления этим потоком.
0
Unifan
0 / 0 / 0
Регистрация: 11.08.2014
Сообщений: 40
15.08.2014, 19:15  [ТС] 17
Благодарю. Спасибо всем
0
St1f1er
2 / 2 / 0
Регистрация: 08.08.2014
Сообщений: 14
15.08.2014, 20:27 18
Цитата Сообщение от Unifan Посмотреть сообщение
Допустим у нас есть такой код.
Почему operator объявлен с амперсандом, как поток может возвращаться?
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
using namespace std;
 
class ThreeD {
public:
    int x, y, z;
    ThreeD(int a, int b, int c) { x = a; y = b; z = c; }
};
 
ostream &operator<<(ostream &stream, ThreeD obj)
{
    stream << obj.x << endl;
    stream << obj.y << endl;
    stream << obj.z << endl;
 
    return stream;
}
 
int main()
{
    ThreeD a(1, 2, 3);
    cout << a;
 
 
    system("pause");
    return 0;
}
Мне кажется вы еще не учили перегрузку операторов.
1
sourcerer
Модератор
Эксперт CЭксперт С++
4868 / 2053 / 325
Регистрация: 20.02.2013
Сообщений: 5,556
Записей в блоге: 24
Завершенные тесты: 1
15.08.2014, 22:33 19
Лучший ответ Сообщение было отмечено Unifan как решение

Решение

Тут понимание складывается, на мой взгляд, из нескольких нюансов:
  1. трактовка символа
    Кликните здесь для просмотра всего текста
    Так называемая перегрузка операторов (operator overloading).
    В некоторых случаях & трактуется как оператор взятия адреса (address-of operator), а в других, как ссылка (reference). Так же и символ * иногда трактуется операция умножения, а иногда как указатель.

  2. особенности синтаксиса (разные варианты записи)
    Кликните здесь для просмотра всего текста

    Дополнительную путаницу могут вносить разные варианты записи указателей и ссылок:
    C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    int *ptr;    // указатель на тип int - один из вариантов записи
    int* ptr;    // указатель на тип int - другой вариант записи
    int * ptr;   // указатель на тип int - третий вариант записи
     
    int var;           // переменная с именем "var" типа int
    int &refvar = var; // refvar - ссылка на переменную var
    // иначе говоря, задано альтернативное имя (refvar) для переменной var
    int& refvar = var;  // вариант записи
    int & refvar = var; // вариант записи
    Кроме того, новичка могут смущать названия классов из стандартной библиотеки. Например, такая запись может быть вполне понятной:
    C++
    1
    
    double &rdvar = dvar; // ссылка на переменную типа double
    а вот такое уже вгоняет в ступор:
    C++
    1
    
    ostream &stream // ссылка на объект типа ostream

  3. разные синонимы в терминологии
    Кликните здесь для просмотра всего текста

    Иногда то же самое, объяснённое другими словами способно как внести ясность, так и запутать. Например, мне при изучении темы указателей оказался более понятен термин операция взятия значения, чем разыменование. А в теме про функции обилие синонимов прототип (объявление), определение (реализация) поначалу только запутало.

  4. пошаговая проработка коротких и простых практических примеров
    Кликните здесь для просмотра всего текста

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

  5. объяснение одних и те же тем у разных авторов
    Кликните здесь для просмотра всего текста

    Иногда полезно прочитать что-то, что доходит с трудом, у другого автора.
1
sourcerer
Модератор
Эксперт CЭксперт С++
4868 / 2053 / 325
Регистрация: 20.02.2013
Сообщений: 5,556
Записей в блоге: 24
Завершенные тесты: 1
16.08.2014, 22:40 20
del
0
16.08.2014, 22:40
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.08.2014, 22:40

Реализация программы с использованием ссылок и указателей
Добрые люди! Подскажите, есть ли тут использованные ссылки и указатели? Препод...

Объясните суть ссылок и указателей в коде
Всем добрый день! В общем, есть код (не судите, что примера попроще я не...

Демонстрация работы ссылок, указателей или дескрипторов
Нужна помощь. Есть у кого готовый код, который демонстрирует работу указателей,...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru