Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Указатели / 25 сообщений из 50, страница 1 из 2
20.01.2014, 07:43
    #38531362
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Здравствуйте.
Классический пример :
Код: plaintext
1.
2.
3.
4.
5.
6.
void swap(int &x, int &y)
{
int temp=x;
x=y;
y=temp;
}



Прокомментируйте пожалуйста, почему строчка temp=x отработает корректно, ведь x должен быть адресом, я ведь не пишу
int *temp=x;

Как я понял в x уже хранится конкретное значение. Но как я его извлёк из адреса, если операция извлечения выглядит как *x. Тогда по идее строка должна выглядеть так :
int temp=*x.

Прокомментируйте пожалуйста где я ошибаюсь, и если можно сделайте комментарий к каждой строчке функции swap. Вот например, функция принимает два дареса, или в процессе приёма данных берёт операцию адреса переменных ?Ведь вызывать я буду её как
swap(a,b) а не swap(&a,&b)

Спасибо
...
Рейтинг: 0 / 0
20.01.2014, 11:49
    #38531579
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
SashaMercury,

ссылка -- это не указатель. Это всегда разименованный константный указатель.
При работе со ссылками у переменной сохраняется семантика самой переменной, а не указателя на переменную, но эффективно при инициализации ссылки производится как бы "передача указателя".
...
Рейтинг: 0 / 0
20.01.2014, 11:58
    #38531600
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Код: plaintext
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.
// Аналогичный код на указателях:

void swap(int *x, int *y)
{
int temp=*x;
*x=*y;
*y=temp;
}

// код на ссылках, с проставленными явно операциями, выполняемыми неявно компилятором. (в лишних скобках)

void swap(int &x, int &y) // тут как бы неявно (int *x, int *y)
{
int temp =  (*x);
(*x) = (*y);
(*y) = temp;
}

// код с комментариями
void swap(int &x, int &y)  // реально на физическом уровне передаются указатели на две переменные
// но в функции ты не можешь поменять эти адреса или использовать их как массивы, т.е. реализовать с ними адресную арифметику.
{
int temp=x; // эффективно выполняется код int temp = *x , т.е. в temp заносится значение, располагающееся по адресу x.
x=y; // эффективно выполняется код *x = *y , по адресу x заносится значение, лежащее по адресу y.
y=temp; // эффективно выполняется  *y = temp, по адресу y заносится значение temp.
}
...
Рейтинг: 0 / 0
20.01.2014, 15:46
    #38532003
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
MasterZiv, можно попробовать сделать #define swap ...
...
Рейтинг: 0 / 0
20.01.2014, 18:14
    #38532245
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
maytonMasterZiv, можно попробовать сделать #define swap ...
Ага, и сломать весь STL :)
...
Рейтинг: 0 / 0
20.01.2014, 18:20
    #38532255
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Вспомнился анекдот

Код: plaintext
1.
#define TRUE FALSE
...
Рейтинг: 0 / 0
21.01.2014, 02:27
    #38532622
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
MasterZiv , спасибо за ответ. Вероятно я получил много ценной информации, но не всё мне понятно.

А1
"ссылка -- это не указатель. Это всегда разименованный константный указатель." Мне не очень понятно это выражение.

Как я это понимаю: согласно K&R, "Указатель - это переменная содержащая адрес другой переменной". То есть например я объявил
int *px; Так, вот элемент x-может хранить значение адреса другой переменной. Далее, адрес переменной.
int x;//объявил переменную типа int, которая имеет свой сегмент в ОП, и свой адрес в памяти, например 0x123
px=&x; //теперь в px хранится значение 0x123.

Причём тут я не провожу дифференциации на то, константный ли указатель, или нет. Константный указатель это неизменяемый адрес памяти, если я правильно понимаю.
то есть если я напишу
int *const px2;
px2=&x;//адрес x это и есть ссылка ? и это есть в данном случае разименнованный константный указатель ? а в примере выше, px ведь можно менять, и потому в том случае это не ссылка ?

А2
"При работе со ссылками у переменной сохраняется семантика самой переменной, а не указателя на переменную, но эффективно при инициализации ссылки производится как бы "передача указателя" при работе подобной этой ?
int *px=&x; //и да, я ведь не могу написать int x=&x;
Объясните пожалуйста эту фразу побробнее.

Б1
// код на ссылках, с проставленными явно операциями, выполняемыми неявно компилятором. (в лишних скобках)

void swap(int &x, int &y) // тут как бы неявно (int *x, int *y)
{
int temp = (*x);
(*x) = (*y);
(*y) = temp;
}

Вот!! Вот этот код мне полностью понятен, для меня он полностью логичен ! Действительно в скобках как бы неявно указатели, я это понимаю. Но эти адреса берутся в процессе вызова функции ?

Б2
// код с комментариями
void swap(int &x, int &y) // реально на физическом уровне передаются указатели на две переменные
// но в функции ты не можешь поменять эти адреса или использовать их как массивы, т.е. реализовать с ними адресную арифметику.
{
int temp=x; // эффективно выполняется код int temp = *x , т.е. в temp заносится значение, располагающееся по адресу x.
x=y; // эффективно выполняется код *x = *y , по адресу x заносится значение, лежащее по адресу y.
y=temp; // эффективно выполняется *y = temp, по адресу y заносится значение temp.
}

Тогда зачем этот код ??Тот выше намного логичнее, что значит фраза эфективнее ? Быстрее сделать в этом примере, чем в примере выше Б1?

Прокомментируйте пожалуйста.
...
Рейтинг: 0 / 0
21.01.2014, 02:35
    #38532623
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
mayton, это шутка ?)

"MasterZiv, можно попробовать сделать #define swap ... "

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

define sqr(x) x*x
...
int x=5,y;
y=sqr(x+1);

Известно что препроцессор сделает.
Мне кажется, что если define где и используется, то только в тех программах которые работают со своим кодом. то есть программы который меняют свой программный код. Где то я про такое слышал.

Или это не шутка ?
Тогда define swap(x,y) а дальше как ? не {int temp; temp=x;x=y;y=temp;} ?
и то, тут вероятно ошибка
...
Рейтинг: 0 / 0
21.01.2014, 02:59
    #38532629
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
SashaMercury,

K&R ничего не знают про int &x , потому что это С++, а они пишут про С, в котором ссылок нет вообще :)
Читайте книги по С++, если хотите разобраться.

SashaMercuryчто значит фраза эфективнее
Не "эфективнее", а "эфективно" - в данном контексте имеется в виду "в конечном итоге"

SashaMercuryvoid swap(int &x, int &y) // тут как бы неявно (int *x, int *y)
{
int temp = (*x);
(*x) = (*y);
(*y) = temp;
}

Вот!! Вот этот код мне полностью понятен, для меня он полностью логичен ! Действительно в скобках как бы неявно указатели, я это понимаю. Но эти адреса берутся в процессе вызова функции ?
Это не код, а объяснение что происходит.
Когда у вас ссылка то вы ее не разыменовываете через *. Это за вас делает компилятор С++.
...
Рейтинг: 0 / 0
21.01.2014, 03:02
    #38532632
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Anatoly MoskovskyКогда у вас ссылка то вы ее не разыменовываете через *. Это за вас делает компилятор С++.
Ну и присвоение в ссылку тоже происходит без явного взятия адреса (без оператора &) - адрес присваиваемого выражения автоматически вычисляет компилятор.
...
Рейтинг: 0 / 0
21.01.2014, 03:36
    #38532633
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Anatoly Moskovsky, вы правы.

K&R не говорят о типе переменных как
int &x; я понял!
У нас есть , f e:
int x=100;// &x=0x123
int &rx=x;// &rx=0x123 То есть эта переменная имеет тип данных ссылка ? Это ссылочный тип данных которого нет в Си, и он появился в C++ ?
и как я понял операция взятий значения по адресу ссылки в данном случае выглядит как rx; f e: int temp=rx ??


void swap(int &x, int &y) //функция принимает именно два адреса
{
int temp=x; //в temp записывается значение по адресу x, в temp сейчас хранится конкретное целое число
x=y; //аналогично выше
y=temp; //аналогично
}

То что я написал выше корректно ?

И остался вопрос, я его практически понял подсознательно, но не конца .
используем функцию вызовом
swap(x,y)
Непонятно только это, если всё написанное выше верно
...
Рейтинг: 0 / 0
21.01.2014, 03:50
    #38532635
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
SashaMercuryТо что я написал выше корректно ?
да.

SashaMercuryИ остался вопрос, я его практически понял подсознательно, но не конца .
используем функцию вызовом
swap(x,y)
Непонятно только это
А вопрос-то какой? :)
...
Рейтинг: 0 / 0
21.01.2014, 04:02
    #38532637
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
у нас есть
swap(int &a,int &b) -прототип функции

int x1=5,y=10; //&x=0x123 &y=0x127

Делаю вызов
swap(,y);

Функция принимает две переменных ссылочного типа, две ссылки, то есть в момент вызова
А- функция принимает (0x123 , 0x127 )
Б- как это происходит что берутся как бы псевдонимы этих переменных ??

ааа.стоп
я ведь пишу
int rx=&x;
И именно поэтому функция вызывается таким образом ?))

Итого:
При вызове функции (в прототипе она принимает &a,&b), в значения &a и &b записываются адреса переменных x и y !!!, и далее происходит работа с ними ?)
Я правильно понял ??

PS
"Функция принимает две переменных ссылочного типа, две ссылки, то есть в момент вызова
А- функция принимает (0x123 , 0x127 )
"
Этот мой комментарий верен, но некорректен !! Функция подставляет адреса принимаемых переменных x и у в &a и &b ! Вот это грамотный комментарий ! То есть фактически во время вызова функции происходят две операции:
int &a=x;
int &b=y;

Верно ??
...
Рейтинг: 0 / 0
21.01.2014, 04:05
    #38532638
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Даже не подставляет, а делает так что параметры a и b берут значение из той же области памяти что и x с y
...
Рейтинг: 0 / 0
21.01.2014, 04:12
    #38532640
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
SashaMercuryЭтот мой комментарий верен, но некорректен !!
Это шедевр :)


SashaMercuryФункция подставляет адреса принимаемых переменных x и у в &a и &b ! Вот это грамотный комментарий
Ну что вы себя путаете этими &. Нет там никаких &a. & относится к типу а не к переменной.

Если кратко то при вызове функции с параметром ссылкой происходит следущее:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
void swap(int &x, int &y)
{
    int temp=x;
    x=y;
    y=temp;
}
...

int x=5,y=10;

// при вызове
swap(x, y);
// генерится следущий код
// int& tmp1 = x;
// int& tmp2 = y;
// swap(tmp1, tmp2);
...
Рейтинг: 0 / 0
21.01.2014, 04:37
    #38532641
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Anatoly Moskovsky,

// при вызове
swap(x, y);
// генерится следущий код
// int& tmp1 = x;
// int& tmp2 = y;
// swap(tmp1, tmp2);

Я понял !))) Спасибо!

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

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

м. А указатель это переменная хранящая адрес другой переменной. Интересные комбинации могут получить из указателей и адресов.


Anatoly Moskovsky и MasterZiv, Спасибо за все объяснения! Я понял !
...
Рейтинг: 0 / 0
21.01.2014, 04:43
    #38532642
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Кстати, объявления вида:
Код: plaintext
1.
2.
int& rx;
int ℞



Как я понял аналогичны, но ведь очевидно что первое int& rx; будет более грамотным, разве нет ? Или тут такая-же ситуация как с обратным чтением
const int*- указатель типа int на константу
int *const -константный указатель на целое число

да нет, всё равно int& x; выглядит грамотней, intr& это тип, а rx это имя переменной
...
Рейтинг: 0 / 0
21.01.2014, 04:56
    #38532644
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
SashaMercuryКстати, объявления вида:
Код: plaintext
1.
2.
int& rx;
int ℞



Как я понял аналогичны, но ведь очевидно что первое int& rx; будет более грамотным, разве нет ? Или тут такая-же ситуация как с обратным чтением
const int*- указатель типа int на константу
int *const -константный указатель на целое число

да нет, всё равно int& x; выглядит грамотней, intr& это тип, а rx это имя переменной
Это исключительно вопрос стиля, к чему примыкает &. Есть фанаты и того и того, и ругаются в инете они так же яростно как и фанаты отступов пробелами и табами :)

ЗЫ. Применяйте тег SRC чтобы те было такого: ℞
...
Рейтинг: 0 / 0
21.01.2014, 05:02
    #38532646
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Например,

Фанат1всё равно int& x; выглядит грамотней, intr& это тип, а rx это имя переменной
Фанат2зато int& x, y; выглядит как будто у обех переменных тип int&, а на самом деле - только у первой
Фанат1так нефиг в одной строке объявлять несколько переменных
ну и так далее ... :)
...
Рейтинг: 0 / 0
21.01.2014, 06:09
    #38532653
SashaMercury
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
про SRC понял, окей.

"так нефиг в одной строке объявлять несколько переменных "
...
Рейтинг: 0 / 0
21.01.2014, 10:34
    #38532779
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
SashaMercuryСейчас мне стало казаться что ссылочный тип данных это мощно, то есть я могу именовать одну и ту же часть памяти через различные переменные, и менять значения этой части памяти через различные переменные. Хотя наверное есть и недостатки,
!

можно случайно забыть о связи нескольких переменных, изменить значение одной, и поменяют значения все другие, указывающие изменённый участок памяти.
![/quot]

А ещё можно забыть, как дышать, и случайно задохнуться....

Модель "ссылка -- это другое имя переменной" конечно очень хорошая, но есть один нюанс, который нельзя забывать -- это "другое имя переменной" занимает дополнительную сверх самой переменной память размером с указатель на эту переменную.
Если про это помнить, то аналогия "другое имя переменной" достаточно точна.
Но есть всякие нюансы, когда и эта модель ломается.

SashaMercuryА есть ли какое-либо ограничение на максимальное количество переменных указывающих на именованный участок памяти ?


Нет, ограничений нет.
...
Рейтинг: 0 / 0
21.01.2014, 13:44
    #38533015
Анатолий Широков
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
SashaMercuryДаже придумал у себя в голове ещё один пример, с помощью этих ссылочных переменных мы открываем доступ к значению переменных через другой "порт".


ссылка это другое имя переменной, его алиас (псевдоним) и т.п. поэтому не инициализированных ссылок не бывает в природе. это всегда отсылка на уже существующий объект.
...
Рейтинг: 0 / 0
22.01.2014, 08:25
    #38533893
z
z
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Anatoly MoskovskySashaMercury,

K&R ничего не знают про int &x , потому что это С++, а они пишут про С, в котором ссылок нет вообще :)
Читайте книги по С++, если хотите разобраться.



Читаем:
5.1. Указатели и адреса
http://lib.ru/CTOTOR/kernigan.txt

Кстати, пример со SWAP
именно оттуда...

SWAP(A, B);

определив функцию SWAP при этом следующим образом:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
 SWAP(X, Y)      /* WRONG */
 INT X, Y;
 {
    INT TEMP;

    TEMP = X;
    X = Y;
    Y = TEMP;
 }


Модератор: Отредактировано
...
Рейтинг: 0 / 0
22.01.2014, 10:00
    #38533954
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
z,

вопрос изначально был про ссылки, а не про указатели. ссылок в С нет.
...
Рейтинг: 0 / 0
22.01.2014, 21:00
    #38534910
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Указатели
Огромная просьба ко всем: не кормите троллей.
Флуд удаляется...
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Указатели / 25 сообщений из 50, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]