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

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

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

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

30.05.2012, 11:31. Просмотров 4950. Ответов 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
The_Immortal
1552 / 488 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 13:59  [ТС] #31
Deviaphan,

Цитата Сообщение от Deviaphan Посмотреть сообщение
Не совсем. Это переменной p, адрес которой хранился в m было присвоено значение 5.
Т.е. после пятой строки, р равно 5.
Как бы я это и имел в виду

Небольшое резюме:

C++
1
2
3
int *p; //объявление указателя
p = &что-либо;
*p = значение //разыменование указателя (или как правильно это звучит) - присвоение переменной (или чему-либо), адрес которой содержится в p, значения
C++
1
int & r = переменная; // объявление ссылки
Только вот с ссылкой не очень понимаю... Ссылка (как и указатель) может только при объявлении создаваться? Это тип?
Просто я читал, что "указатель" - это тип. По аналогии ссылка это тоже должен быть тип.
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 14:02 #32
Цитата Сообщение от Deviaphan Посмотреть сообщение
if( p != r )
* abort();// шо-то случилось!
Если синоним не аутентичен? Однако! Если б такое было true, то что то бы очень случилось.
1
The_Immortal
1552 / 488 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 14:02  [ТС] #33
Toshkarik,
Цитата Сообщение от Toshkarik Посмотреть сообщение
просто понимаете, операция объявления ссылки и операция взятия адреса имеют общий символ амперсанда. Но по сути это две разные операции.
Да-да, я это понимаю и пытаюсь как раз в этом разобраться.
1
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 14:04 #34
Цитата Сообщение от The_Immortal Посмотреть сообщение
Только вот с ссылкой не очень понимаю... Ссылка (как и указатель) может только при объявлении создаваться? Это тип?
Ссылка - это второе имя переменной. Вот тебя как в реале зовут? А здесь тебя зовут The_Immortal. Так сколько у тебя имён? Два уже детектед: то, которое дали при рождении и ещё The_Immortal. У человека второе имя - ник, у переменной - ссылка.
1
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1305 / 1220 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 14:05 #35
Цитата Сообщение от taras atavin Посмотреть сообщение
Если синоним не аутентичен? Однако!
Потому я и говорю ШО ТО СЛУЧИЛОСЬ!!!! Нибиру летит, конец света грядёт, ссылка и оригинал не равны! Адъ на Земле!


Цитата Сообщение от The_Immortal Посмотреть сообщение
Ссылка (как и указатель) может только при объявлении создаваться?
Всё создаётся при объявлении. Но ссылка ещё и обязана инициализироваться при создании.
2
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
31.05.2012, 14:06 #36
Ссылку можно назвать разыменованным константным указателем. После объявления ссылку нельзя изменить, так же при объявлении, как и все константные данные, она должна быть инициализированна каким либо значением.
1
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 14:08 #37
Цитата Сообщение от Deviaphan Посмотреть сообщение
Всё создаётся при объявлении. Но ссылка ещё и обязана инициализироваться при создании.
Ссылка может быть пустой, но привязать её к реальной переменной всё равно придётся и сделать это можно ровно один раз.

Добавлено через 1 минуту
Цитата Сообщение от Toshkarik Посмотреть сообщение
Ссылку можно назвать разыменованным константным указателем. После объявления ссылку нельзя изменить, так же при объявлении, как и все константные данные, она должна быть инициализированна каким либо значением.
Ведёт себя, как разыменованный константный указатель, но нет ни какой гарантии стандарта, что именно так она и реализована.
1
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
31.05.2012, 14:09 #38
Цитата Сообщение от taras atavin Посмотреть сообщение
Ведёт себя, как разыменованный константный указатель, но нет ни какой гарантии стандарта, что именно так она и реализована.
Так где ж я сказал, что она должна быть также реализована то?
2
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 14:14 #39
Не сказал, но закон Мёрфи:
всё, что может быть не правильно понято, именно так и будет понято
.
1
alkagolik
Заблокирован
31.05.2012, 14:17 #40
Цитата Сообщение от The_Immortal Посмотреть сообщение
Только вот с ссылкой не очень понимаю... Ссылка (как и указатель) может только при объявлении создаваться? Это тип?
Просто я читал, что "указатель" - это тип. По аналогии ссылка это тоже должен быть тип.
Цитата Сообщение от taras atavin Посмотреть сообщение
а ссылка - это синоним другой переменной.
Цитата Сообщение от Toshkarik Посмотреть сообщение
Ссылку можно назвать разыменованным константным указателем. После объявления ссылку нельзя изменить, так же при объявлении, как и все константные данные, она должна быть инициализированна каким либо значением.
ссылка это разыменованный указатель. удобная плюшка плюсов.
Цитата Сообщение от The_Immortal Посмотреть сообщение
Моя формулировка верна?
да с поправкой "переменная - указатель НА тип int ,а не типа int" потому что сам указатель имеет тип int*, что вероятно есть unsigned.
Цитата Сообщение от taras atavin Посмотреть сообщение
Ссылка может быть пустой, но привязать её к реальной переменной всё равно придётся и сделать это можно ровно один раз
не совсем понял, но если так
C++
1
2
3
...
int &x;
...
то это не прокатит.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
31.05.2012, 14:20 #41
Да человек вообще чаще всего понимает по своему, что бы там ни было написано.
0
The_Immortal
1552 / 488 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 15:12  [ТС] #42
Ух, мужики, ну Вы тут и заварили

В общем, из всего, что я прочел я так и не понял, что такое ссылка.
В смысле вот это
Цитата Сообщение от taras atavin Посмотреть сообщение
Ссылка - это второе имя переменной. Вот тебя как в реале зовут? А здесь тебя зовут The_Immortal. Так сколько у тебя имён? Два уже детектед: то, которое дали при рождении и ещё The_Immortal. У человека второе имя - ник, у переменной - ссылка.
я понимаю. И, кстати, огромное спасибо, что пытаетесь донести подобными примерами - очень ценю это, т.к. действительно помогает.
Но все же без формализации в итоге никак.

У меня просто в голове не укладывается, как две переменные могут сидеть по одному адресу... Или это чисто логический прием?


Цитата Сообщение от taras atavin Посмотреть сообщение
Ссылка может быть пустой
И это также непонятно. Разве может ссылка (по своему назначению должна на что-то ссылаться) указывать на ничто?
Хотя вот указатель же необязательно инициализровать, так? Соответственно он может быть пустым почему-то...

Просто насколько я понимаю, то указатель также имеет свой адрес, правильно? Имею в виду сам по себе указатель, как переменная. И он, разумеется, не совпадает с адресом, на который этот указатель указывает.
Но вот что с ссылкой... Она своего адреса не имеет что ли... Имею в виду саму по себе ссылку.



Добавлено через 7 минут
Цитата Сообщение от taras atavin Посмотреть сообщение
Ведёт себя, как разыменованный константный указатель
Цитата Сообщение от alkagolik Посмотреть сообщение
ссылка это разыменованный указатель
А это я тоже с трудом понял, примерно вот так (задача корявая, т.к. формулировал сам):
Задача: передать переменной x значение через переменную y, используя:
а) указатель
б) ссылку
а)
C++
1
2
3
4
5
int x;
int *y;
 
y=&x;
*y=5;
б)
C++
1
2
3
4
int x;
int &y=x;
 
y=5;
Вы это имели в виду?
0
Borkot
4 / 4 / 0
Регистрация: 05.05.2012
Сообщений: 184
Записей в блоге: 1
31.05.2012, 15:18 #43
Ссылка как только объявляется сразу инициализируется
типа
C
1
int &p=m;
то есть адрес взятия находится в левом краю,
а вот указатель можно присвоить потом или вообще в (NULL) то есть в ноль.В книгах так написано.
типа
int *p;
C
1
2
3
*p=NULL;
//или просто
*p=0;
0
alkagolik
Заблокирован
31.05.2012, 15:24 #44
Цитата Сообщение от The_Immortal Посмотреть сообщение
Вы это имели в виду?
да, лишь забыл уточнить что ссылка есть константный разыменованный указатель. Всегда привязан к одной области (переменной) вот пример
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
 
using namespace std;
 
int main() {
 
    int *p, x, y;
    int &s = x;
    p = &x;
 
    *p = 3; // *p - разыменовывание указателя
    cout << *p << ' ' << s << ' ' << x << endl;
    s = 4;
    cout << *p << ' ' << s << ' ' << x << endl;
    p = &y;
    s = y; // y не проинициализирована, теперь x = y т.к. s всегда указывает на x  и только
    *p = 5;
    cout << *p << ' ' << s << ' ' << y << " x = " << x <<  endl;
    s = y;
    cout << *p << ' ' << s << ' ' << y << " x = " << x <<  endl;
 
    return 0;
}
1
The_Immortal
1552 / 488 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 15:24  [ТС] #45
Borkot, да, спасибо (жаль "спасибо" мои закончились).

C++
1
*p=0;
Но таким образом сам-то указатель не обнуляется, верно? Это обычное разыменование - т.е. по адресу переменной, на которой указывает этот указатель, записывается 0.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.05.2012, 15:24
Привет! Вот еще темы с ответами:

Ссылки и адреса - 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; }


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

Или воспользуйтесь поиском по форуму:
45
Yandex
Объявления
31.05.2012, 15:24
Закрытая тема Создать тему
Опции темы

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