Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 21, средняя оценка - 4.67
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
#1

Передача в функцию - ссылки, указатели, константы - C++

16.06.2013, 23:18. Просмотров 2877. Ответов 37
Метки нет (Все метки)

Вот программа:

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream> 
 
 void fun(int &rhs) 
{
rhs++;
}
 
int main()
{
int var = 2;
        
fun(var);
 
std::cout << var << "\n";
    
system("pause");
return 0;
}


В строке 10 я создаю переменную var и присваиваю ей значение 2, т.е. допустим по адресу 0001 у меня располагается значение 2
В строке 12 я передаю var в виде ссылке в функцию, где она получает новое имя (временное имя, псевдоним) - rhs, значение rhs располагается по тому же адресу что и var - 0001.
В строке 5 я прибавляю 1 к rhs и по адресу 0001 меняется значение с 2 на 3.

по этому в строке 14 мне выведет на экран 3, а не 2.

Вопрос, а что происходит, как работает следующая программа:

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream> 
 
 int & fun(int rhs) 
{
rhs++;
 
return rhs;
}
 
int main()
{
int varOne = 2;
int varTwo;
        
varTwo = fun(varOne);
 
std::cout << varTwo << "\n";
    
system("pause");
return 0;
}


В частности меня интересует какую роль выполняет оператор & в строке 3 и чем отличается такая же программа без &.

Распишите по возможности так, как я описывал первую программу, что бы не оставалось вопрос, что бы не пришлось переспрашивать.

Это первый вопрос в этой теме, дальше я буду добавлять вопросы, про указатели константы и т.д. так что если что, смотрите последние сообщения, а не первое.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.06.2013, 23:18     Передача в функцию - ссылки, указатели, константы
Посмотрите здесь:
C++ Передача в функцию константы вместо указателя
Ссылки и указатели на функцию C++
Как лучше передавать значения в функцию? Ссылки vs указатели C++
C++ Передача массива в функцию (указатели)
Передача в функцию через указатели C++
Указатели и массивы. Передача массива в функцию по указателю C++
Передача двумерного массива в функцию через указатели C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 831
16.06.2013, 23:31     Передача в функцию - ссылки, указатели, константы #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
 
int & fun(int rhs)
{
    rhs++;
 
    return rhs;
}
 
int main()
{
    int varOne = 2; 
    int varTwo;
 
    varTwo = fun(varOne);
 
    std::cout << varTwo << "\n";
 
    system("pause");
    return 0;
}
Когда мы вызываем int& fun(int rhs), то переданный аргумент передается по значению, то есть копируется, то есть создается временный объект rhs (копия переданного) в зоне видимости функции fun. Потом вы увеличиваете значение rhs. Но самое интересное кроется в возвращаемом значении.

C++
1
2
3
4
    int varOne = 2; //переменная, не ссылка
    int varTwo; //переменная, не ссылка
 
    varTwo = fun(varOne); //функция возвращает ссылку, но vatTwo не ссылка, поэтому происходит копирование
Если было бы так:
C++
1
int &vatTwo = fun(vatOne); //ошибка, функция возвращает ссылку на временный объект
В общем случае возвращать ссылку - плохая примета.
xtorne21st
интересующийся
303 / 274 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
16.06.2013, 23:32     Передача в функцию - ссылки, указатели, константы #3
Всё зависит от конкретного компилятора. В стандарте написано, что возврат ссылки на локальный объект приводит к UB.
Кудаив
329 / 406 / 24
Регистрация: 27.05.2012
Сообщений: 1,165
Завершенные тесты: 2
16.06.2013, 23:34     Передача в функцию - ссылки, указатели, константы #4
Цитата Сообщение от VLK Посмотреть сообщение
& в строке 3
означает что функция возвращает ссылку на переменную

Цитата Сообщение от VLK Посмотреть сообщение
чем отличается такая же программа без &.
если бы не было & то функция производила манипуляции с переменной, делала её копию и возвращала к месту вызова
Jupiter
Каратель
Эксперт С++
6553 / 3973 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
16.06.2013, 23:36     Передача в функцию - ссылки, указатели, константы #5
В строке 12 я создаю переменную var и присваиваю ей значение 2, т.е. допустим по адресу 0001 у меня располагается значение 2
В строке 15 я передаю копию var в виде ссылке в функцию, где она получает новое имя (временное имя, псевдоним) - rhs, значение rhs которая (копия) располагается по тому же адресу что 0002.
В строке 5 я прибавляю 1 к rhs (копии var) и по адресу 0002 меняется значение с 2 на 3.
В строке 7 я стреляю себе в ногу возвращаю ссылку на копию var, которая будет уничтожена после выхода из вункции
по этому в строке 15 происходит неопределенное поведение, так как ссылка ссылается на не существующую переменную.
что происходит дальше - на совести разработчиков компилятор, возможно все!
вот и сказочке конец...
Кудаив
329 / 406 / 24
Регистрация: 27.05.2012
Сообщений: 1,165
Завершенные тесты: 2
16.06.2013, 23:38     Передача в функцию - ссылки, указатели, константы #6
Цитата Сообщение от Olivеr Посмотреть сообщение
int &vatTwo = fun(vatOne); //ошибка, функция возвращает ссылку на временный объект

Цитата Сообщение от xtorne21st Посмотреть сообщение
Всё зависит от конкретного компилятора
MinGW - прожевал
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
16.06.2013, 23:40  [ТС]     Передача в функцию - ссылки, указатели, константы #7
Olivеr, т.е. правильно я понимаю что во второй программе грубо говоря происходит не return 3, а return ссылка на rhs (при этом rhs уже нет, т.к. это был временная переменная) ? а уже из этой ссылки varTwo берет значение 3?

извините за колхозное описание ситуации, мне так проще понять.
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 831
16.06.2013, 23:43     Передача в функцию - ссылки, указатели, константы #8
VLK, если записано
C++
1
int & fun(int rhs)
и
C++
1
varTwo = fun(varOne);
то происходит копирование rhs в переменную varTwo

По крайней мере так в
Цитата Сообщение от Кудаив Посмотреть сообщение
MinGW
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
16.06.2013, 23:44  [ТС]     Передача в функцию - ссылки, указатели, константы #9
Цитата Сообщение от Olivеr Посмотреть сообщение
VLK, если записано
C++
1
int & fun(int rhs)
и
C++
1
varTwo = fun(varOne);
то происходит копирование rhs в переменную varTwo

По крайней мере так в
но rhs при этом уже не существует т.к. функция (fun) закончила свою работу?
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 831
16.06.2013, 23:50     Передача в функцию - ссылки, указатели, константы #10
VLK, пишу по пунктам как я это вижу:
1. Передаем копию varOne в функцию fun, создается переменная с именем rhs (аналогичная varOne), но они никак не связаны!
2. увеличиваем значение rhs на 1
3. Возвращаем копию rhs и присваиваем ее varTwo, уничтожаем rhs

Добавлено через 1 минуту
Совет: напишите простенькую структуру со всеми конструкторами и деструктором. В их телах выведите на экран сообщение о том, что вызван такой то конструктор/деструктор. И проделайте ту же программу с этой структурой.
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
17.06.2013, 00:02  [ТС]     Передача в функцию - ссылки, указатели, константы #11
Все равно не вижу, не понимаю разницу между
C++
1
int & fun(int rhs)
и
C++
1
int fun(int rhs)
Ладно, завтра продолжу изучение.
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 831
17.06.2013, 00:10     Передача в функцию - ссылки, указатели, константы #12
Вот код. Запустите и разберетесь.
Кликните здесь для просмотра всего текста
C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <iostream>
 
#define DEBUG
struct Foo
{
    int x;
    explicit Foo(int val = 0): x(val)
    {
        #ifdef DEBUG
        std::cout << "Стандартный/по значению конструктор\n";
        #endif
    }
    Foo(const Foo &obj): x(obj.x)
    {
        #ifdef DEBUG
        std::cout << "Конструктор копирования\n";
        #endif
    }
    Foo& operator = (const Foo &obj)
    {
        if (this == &obj) return *this;
        x = obj.x;
        #ifdef DEBUG
        std::cout << "Оператор присвоения\n";
        #endif
        return *this;
    }
 
    ~Foo()
    {
        #ifdef DEBUG
        std::cout << "Деструктор, x = " << this->x << std::endl;
        #endif
    }
};
 
Foo& GetFoo(Foo f)
{
    ++f.x;
    return f;
}
 
int main()
{
    setlocale(LC_CTYPE, "");
    Foo h(5);
    std::cout << "~Вызов функции...\n";
    Foo g = GetFoo(h);
    std::cout << "~Конец функции...\n";
    std::cout << g.x << std::endl;
    return 0;
}
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
17.06.2013, 17:14  [ТС]     Передача в функцию - ссылки, указатели, константы #13
Кликните здесь для просмотра всего текста
C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <iostream> 
 
class mat
{
public:
mat(): zn(0) { setlocale(LC_ALL,""); std::cout << "Конструктор без значения (по умолчанию 0) \n"; }
mat(int rhs): zn(rhs) { setlocale(LC_ALL,""); std::cout << "Конструктор со значением: " << get_zn() << " \n"; }
~mat() { setlocale(LC_ALL,""); std::cout << "Деструктор со значением: " << get_zn() << " \n"; }
mat(const mat & rhs ) { zn = rhs.get_zn(); setlocale(LC_ALL,""); std::cout << "Конструктор копирования со значением: " << get_zn() << " \n";  }
 
void set_zn(int rhs) { zn = rhs; }
int get_zn() const { return zn; }
void show_zn() { std::cout << zn << "\n"; }
 
mat operator= (const mat &rhs)
{
if (this == &rhs)
{ return *this; }
else
{
zn = rhs.get_zn();
return *this;
}
}
 
mat operator+ (const mat &rhs)
{
return (zn + rhs.get_zn());
}
 
mat operator- (const mat &rhs)
{
return (zn - rhs.get_zn());
}
 
private:
int zn;
};
 
mat fun(mat a, mat b)
{
std::cout << "В функции без &..\n";
return a+b;
}
 
mat & link(mat a, mat b)
{
std::cout << "В функции с &..\n";
return a+b;
}
 
 
int main()
{
setlocale(LC_ALL,"");
 
mat var2 = 2;
mat var3 = 3;
mat var5 = 0; 
 
std::cout << "Переходим в функцию без &..\n";
var5 = fun(var2, var3);
std::cout << "Вышли из функции без &..\n";
 
var5.show_zn();
std::cout << "\n *********************************** \n\n";
 
 
mat var7 = 7;
mat var8 = 8;
mat var15 = 0;
 
std::cout << "Переходим в функцию с &..\n";
var15 = link(var7, var8);
std::cout << "Вышли из функции с &..\n";
 
var15.show_zn();
 
system("pause");
return 0;
}


Вот я сделал программу, но все равно до конца не понимаю почему они (функции fun и link) работают по разному.
Olivеr
412 / 408 / 13
Регистрация: 06.10.2011
Сообщений: 831
17.06.2013, 17:46     Передача в функцию - ссылки, указатели, константы #14
VLK, еще раз говорю, что в этой функции ошибка:
C++
1
2
3
4
5
mat & link(mat a, mat b)
{
    std::cout << "В функции с &..\n";
    return a+b; //возвращается ссылка на временный объект. после выхода из функции временный объект уничтожится и ссылка будет указывать на непонятно что
}
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.06.2013, 19:08     Передача в функцию - ссылки, указатели, константы
Еще ссылки по теме:
Передача ссылки и указателя в функцию C++
Передача ссылки на массив в функцию C++
C++ Передача ссылки на обьект класса в функцию
Ссылки или указатели (Написать функцию , которая вычисляет гипотенузу, площадь и периметр прямоугольного треугольника) C++
C++ Указатели на константы

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

Или воспользуйтесь поиском по форуму:
VLK
193 / 162 / 12
Регистрация: 05.05.2013
Сообщений: 1,225
17.06.2013, 19:08  [ТС]     Передача в функцию - ссылки, указатели, константы #15
Это я понимаю, получается что такая запись изначально ошибочная и не должна использоваться вообще, НО - Использование класса String

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

PS кстати данную программу я хотел повторить, половина работает, но не работает строчка1 = строчк2 + строчка3 и я думаю проблема как раз кроется в этих строчках 17 и 21, но я их не понимаю по этому не могу толком найти проблему.
Yandex
Объявления
17.06.2013, 19:08     Передача в функцию - ссылки, указатели, константы
Ответ Создать тему
Опции темы

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