Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 36, средняя оценка - 4.69
The_Immortal
1553 / 489 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
#1

Понимание адреса, ссылки и указателя - C++

30.05.2012, 11:31. Просмотров 5038. Ответов 103
Метки нет (Все метки)

Гм... Конечно, стремно создавать подобную тему, однако, уж очень захотелось понять все это дело. Правда сколько раз ни пытался - не удавалось ни разу, возможно, потому что пытался разобраться самостоятельно (хотя, наверное, многие это постигают именно так). Но вот моя очередная попытка, которую решил так сказать обнародовать Поэтому очень рассчитываю на вашу помощь и поддержку.

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

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
// расположение переменных в памяти
#include <cstdio.h>
#include <cstlib.h>
#include <iostream.h>
 
using namespace std;
 
int main(int intArgc, char* pszArgs[])
{
int end;
int n;
long l;
float f;
double d;
 
// Вывод в шестнадцатеричном виде
cout.setf (ios::hex);
cout.unsetf (ios::hex);
 
// выводить адреса переменных
// по очереди, чтобы показать размер
// каждой переменной
cout << "--- = " << &end << "\n";
cout << "&n = " << &n << "\n";
cout << "&l = " << &l << "\n";
cout << "&f = " << &f << "\n";
cout << "&d = " << &d << "\n";
 
system ("PAUSE");
return 0;
}
Результат:

C++
1
2
3
4
5
--- = 0x22ff6c
&n  = 0x22ff68
&l  = 0x22ff64
&f  = 0x22ff60
&d  = 0x22ff58
А теперь цитата из книги:
Обратите внимание на то, что переменная n располагается ровно в 4 байтах от переменной end (---). Переменная l располагается еще на 4 байта ниже, а переменная типа double занимает 8 байт. Для каждой переменной выделяется память, необходимая для ее типа.
Для каждой переменной выделяется память, необходимая для ее типа.
Это мне известно. Но вот что меня занесло в тупик:

Разница, скажем, между 0x22ff6c и 0x22ff68 действительно 4. Но 4 чего - байта? А разве 4 в десятичной системе не 4? А в двоичной это разве не 100? Откуда тут 4 байта? Я понимаю, что там должно быть 4 байта, но не получается осознать, что 1 hex-единица у нас вдруг байт. Или это не так?

В общем, на таком банальном я запутался

Спасайте...
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.05.2012, 11:31
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Понимание адреса, ссылки и указателя (C++):

Изменение адреса указателя - C++
Здравствуйте. Обращаюсь к форуму по следующему вопросу: как можно изменить значение указателя? То есть, есть следующий код: ...

Динамическое указание адреса указателя - C++
мне нужно сделать int * a=(int*)0x123ff; cout&lt;&lt;a; динамически. Кто нибудь знает как это сделать?

Использование ссылки и указателя - C++
Доброго времени суток! Возник такой вопрос, есть код: #include &lt;iostream&gt; #include &lt;cmath&gt; using namespace std; int main() ...

Получение адреса объекта после обнуления указателя на этот объект - C++
Добрый вечер уважаемые программисты. Интересует следующий вопрос. Есть ли способ получить адрес объекта, после того, как указатель на него...

Передача ссылки и указателя в функцию - C++
передал ссылку в одну функцию - нормально, передал в другую - выводит неверное значение, тоже самое с указателем. Как можно это исправить?

Возвращение ссылки или указателя на закрытый элемент класса. - C++
Всех уважаемых форуман. поздравляю с наступившим новым годом и прошу ответить на такой вопрос. Почему до сих пор современный C++ не...

103
Лжец
31 / 31 / 3
Регистрация: 13.12.2011
Сообщений: 106
31.05.2012, 12:15 #16
Интересует почему объявление начинается на "22ff"?
Потому что именно этот диапазон адресов в данный момент доступен для работы. Например, у меня адреса сейчас начинаются с 012.

Я правильно понял?
Просто представь, что это тарелки, которые кладутся друг на друга и тогда все должно стать достаточно очевидно Переменная получает адрес, следующая переменная получает адрес "выше" предыдущей, т.е. как бы "накладывается поверх".
1
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 12:17 #17
Цитата Сообщение от Лжец Посмотреть сообщение
следующая переменная получает адрес выше предыдущей
С тем лишь исключением, что тарелки подкладываются снизу.
2
Лжец
31 / 31 / 3
Регистрация: 13.12.2011
Сообщений: 106
31.05.2012, 12:20 #18
Цитата Сообщение от Deviaphan Посмотреть сообщение
С тем лишь исключением, что тарелки подкладываются снизу.
Точно
1
The_Immortal
1553 / 489 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 12:29  [ТС] #19
Бррр... Пошел на обдумку, что-то конкретно запутался теперь )))
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 12:43 #20
Я тут учусь работать в дизайнерской программе MS Paint, поэтому разработал для тебя небольшую схемку, которая поможет разобраться.
Или окончательно запутает...

Понимание адреса, ссылки и указателя
1
The_Immortal
1553 / 489 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 12:54  [ТС] #21
Так, с этими тарельками


Цитата Сообщение от Deviaphan Посмотреть сообщение
С тем лишь исключением, что тарелки подкладываются снизу.
А почему так? Первая тарелка у нас - первая переменная (end), так? Мы берем ее и просто кладем. Далее берем следующую тарелку (переменная n) и... Подкладываем ее под предыдущую или все-таки ставим сверху?

Добавлено через 2 минуты
Цитата Сообщение от Deviaphan Посмотреть сообщение
Я тут учусь работать в дизайнерской программе MS Paint, поэтому разработал для тебя небольшую схемку
=)))) Здорово! Большое спасибо!

Только по факту же у end получается самый "большой" адрес, а по схемке должно получатья наоборот...
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 13:02 #22
Цитата Сообщение от The_Immortal Посмотреть сообщение
Первая тарелка у нас - первая переменная (end) так?
Первая у нас d, а последняя - end, что вполне логично. Первой в стек кладётся d. end кладётся последней. Но память в стеке используется от старших адресов к младшим, поэтому у первого добавленного адрес больше, чем у последнего.

Возвращаясь к тарелкам. Прикрепляешь тарелку к потолку. Следующую тарелку прикрепляешь к этой тарелке и т.д. Пол это нулевой адрес, потолок - максимальный. Пример с тарелками хорош для понимания принципа работы контейнера "стек", но не для понимания реализации системного стека.)

Добавлено через 2 минуты
Цитата Сообщение от The_Immortal Посмотреть сообщение
Только по факту же у end получается самый "большой" адрес, а по схемке должно получатья наоборот..
Извиняюсь, я код не смотрел, а по тексту и названиям предположил, что код имеет вид:

double d;
float f;
long l;
int n;
int end;

Схемка именно для него.)

Добавлено через 1 минуту
Потому тебя так и запутал.)))))
2
Borkot
4 / 4 / 0
Регистрация: 05.05.2012
Сообщений: 186
Записей в блоге: 1
31.05.2012, 13:20 #23
Всем привет! уважаемые форумчане, а кто подскажет в чем все таки отличие?Заранее спасибо
C
1
2
m=&p;
*m=&p;
0
The_Immortal
1553 / 489 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 13:25  [ТС] #24
Borkot, я пока до этого не дошел (пытаюсь разобраться с этими тарелками для начала), но как я это понимаю:
C++
1
m=&p;
- тут ты указателю говоришь на какой адрес он будет указывать (на адрес переменной p)
C++
1
*m=&p;
- хм, а тут ты по этому адресу (т.е. переменной p) присваиваешь значение этого адреса что ли Так вообще можно?

И кстати, m - должен иметь тип - указатель, иначе
C++
1
m=&p
не получится сделать.

Ну в общем, Отцы сейчас чОтко объяснят, заодно и я послушаю
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 13:27 #25
C++
1
2
3
4
int p;
int * m;
 
m=&p;
C++
1
2
3
int p;
int ** m;
*m=&p;
2
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
31.05.2012, 13:31 #26
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
The_Immortal, адрес - это значение, говорящее о том, где искать функцию, или другое данное, указатель - это переменная, предназначенная для хранения самого адреса, а ссылка - это синоним другой переменной.
3
The_Immortal
1553 / 489 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 13:40  [ТС] #27
Итак,

1)
C++
1
2
3
4
5
int p; // обычная переменная типа int
int * m; // переменная-указатель типа int
 
m=&p; //&p - адрес обычной переменной типа int (p)
//Что в данном случае является ссылкой?
Где там ссылка?

2)
C++
1
2
3
4
5
6
int p;
int * m;
 
m=&p;
*m = 5; // => p=5, т.е. переменной (или чему-либо), располагающейся по адресу &p, 
//присваиваем значение 5.
Моя формулировка верна?
1
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 13:46 #28
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от The_Immortal Посмотреть сообщение
Где там ссылка?
Нету тама ссылки.

Тута ссылка вота:
C++
1
2
3
4
5
6
7
int p = 5;
int & r = p; // r это ссылка
 
p = 3;
 
if( p != r )
  abort();// шо-то случилось!
Добавлено через 1 минуту
Цитата Сообщение от The_Immortal Посмотреть сообщение
Моя формулировка верна?
Не совсем. Это переменной p, адрес которой хранился в m было присвоено значение 5.
Т.е. после пятой строки, р равно 5.
3
taras atavin
3571 / 1755 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
31.05.2012, 13:59 #29
Цитата Сообщение от The_Immortal Посмотреть сообщение
int p; // обычная переменная типа int
int * m; // переменная-указатель типа int
m=&p; //&p - адрес обычной переменной типа int (p)
//Что в данном случае является ссылкой?
Здесь нет ссылки.

Добавлено через 2 минуты
Цитата Сообщение от The_Immortal Посмотреть сообщение
Моя формулировка верна?
Да. &p - конкретное значение (явная константа) указательного типа, то есть адрес, звездочка перед указателем везде, кроме его декларации - доступ к данному по адресу из указателя, после его осуществления туда присвоено 5.
0
Toshkarik
1147 / 864 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
31.05.2012, 13:59 #30
The_Immortal, просто понимаете, операция объявления ссылки и операция взятия адреса имеют общий символ амперсанда. Но по сути это две разные операции.
1
31.05.2012, 13:59
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.05.2012, 13:59
Привет! Вот еще темы с ответами:

Ссылки и адреса - C++
Вот, где лучше всего использовать адреса и ссылки? Просто не много не понятня для чего это все. Вот например эту запись int mas; int*...

Адресное пространство, адреса, ссылки - C++
Добрый вечер. Я новичок в программировании и стал недавно читать туториалы по ссылкам. В общем, прилагаю цитату с одного сайта: ...

Как снять константность ссылки для передачи в функцию адреса - C++
Здравствуйте. Есть функция с сигнатурой: void func(const tm &amp; _tm); В теле функции надо вызвать: time_t _mkgmtime( struct tm*...

При передачи указателя на обьект ошибка,а при передаче ссылки на указатель нет. Почему? - C++
Hi All! class SomeObj { public: int x; }


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

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

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