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

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

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

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

30.05.2012, 11:31. Просмотров 5012. Ответов 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, 16:27  [ТС] #61
Deviaphan,
alkagolik,

Цитата Сообщение от Deviaphan Посмотреть сообщение
Так же, как и присвоить ему значение. cout << *у.
Боюсь, вы меня не поняли... Таким образом я получу содержимое переменной по адресу, который хранит в себе указатель.

Т.е. в данном случае:

C++
1
2
3
4
5
6
7
8
9
int main() {
 
    int *p , x = 2;
    p = &x;
 
    cout << "p = " << *p << endl;
    
    return 0;
}
Я получу:
p = 2
.
А мне надо получить:
p = 0x22ff56
, где 0x22ff56 - адрес переменной x.
0
alkagolik
Заблокирован
31.05.2012, 16:28 #62
Цитата Сообщение от The_Immortal Посмотреть сообщение
А мне надо получить:
C++
1
2
3
4
5
6
7
8
9
int main() {
 
    uint32 *p , x = 2;
    p = &x;
 
    cout << p << ' ' << *p << endl;
    
    return 0;
}
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 16:38 #63
Цитата Сообщение от The_Immortal Посмотреть сообщение
Боюсь, вы меня не поняли...
int x;
int * p = &x;

cout << &p; // адрес указателя p
cout << p; //адрес переменной, на которую указывает p. Равен &x
cout << *p; // Значение х

Добавлено через 47 секунд
Цитата Сообщение от alkagolik Посмотреть сообщение
разве? а не так?
int &x == int* const point;
Прям вот вообще не так.

Добавлено через 22 секунды
Цитата Сообщение от alkagolik Посмотреть сообщение
разве? а не так?
int &x == int* const point;
Прям вот вообще не так.
0
The_Immortal
1552 / 488 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 16:39  [ТС] #64
alkagolik, прошу простить, ступил дважды Значит надо просто выводить без всего.

Хм, а вот таким образом:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() {
 
 //   uint32 *p , x = 2;
  //  p = &x;
 
 int x=2;
 int *p;
 
  cout << p << endl;
    
    system ("pause");
    return 0;
    
}
Сейчас p хранит какой-то рандомный адрес из памяти, так?

Хм, а вот так вот:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int main() {
 
 //   uint32 *p , x = 2;
  //  p = &x;
 
 int x=2;
 int *p;
 
    cout << &x << endl;
  //  cout << p << ' ' << *p << endl;
        cout << p << ' ' << *p << endl;
    
    system ("pause");
    return 0;
    
}
Вылетает ошибка. Это потому, что по тому рандомному адресу не существует никакого значения или как это понять?
0
alkagolik
Заблокирован
31.05.2012, 16:44 #65
Цитата Сообщение от The_Immortal Посмотреть сообщение
Вылетает ошибка. Это потому, что по тому рандомному адресу не существует никакого значения или как это понять?
это понимай так что твоя программа пытается получить доступ к памяти, которая ей запрещена.
Цитата Сообщение от Deviaphan Посмотреть сообщение
Прям вот вообще не так.
но постой, а как же?
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 16:55 #66
Цитата Сообщение от alkagolik Посмотреть сообщение
но постой, а как же?
Читай манул. У ссылки и указателя вообще ничего общего нет.
int &x = v;;
int* const point = &v;
&x == point
но не
int &x == int* const point;
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 17:07 #67
Цитата Сообщение от The_Immortal Посмотреть сообщение
C++
1
2
3
4
int main() {
int x=2;
int *p;
cout << p << endl;
Так ты выведешь значение самого указателя, оно же адрес переменной, на которую он указывает.

Добавлено через 1 минуту
Цитата Сообщение от The_Immortal Посмотреть сообщение
Сейчас p хранит какой-то рандомный адрес из памяти, так?
Да. Вполне возможно, что не валидный, то есть переменная по такому адресу может и не существовать.

Добавлено через 1 минуту
Цитата Сообщение от The_Immortal Посмотреть сообщение
Вылетает ошибка. Это потому, что по тому рандомному адресу не существует никакого значения или как это понять?
Значение там может и валяться, такое же мусорное, а нет права доступа по такому адресу.
0
The_Immortal
1552 / 488 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:11  [ТС] #68
taras atavin, ой, Вы вернулись!

Спасибо большое, я все понял.

Но очень сильно хотел у Вас узнать, что все-таки имелось в виду под
Цитата Сообщение от taras atavin Посмотреть сообщение
Ссылка может быть пустой
Не могли бы пояснить, пожалуйста?
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 17:15 #69
Цитата Сообщение от alkagolik Посмотреть сообщение
но постой, а как же?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int x; // Переменная
int &s=x; // Ссылка
int *const p=&x; // Указатель
/*Следующие строки эквивалентны:*/
x=2;
s=2;
*p=2;
/*А теперь выводим адреса и ничему не удивляемся*/
cout<<&x<<endl; // Адрес, по которому валяется сама переменная
cout<<&s<<endl; // Адрес, по которому валяется ссылка
cout<<&p<<endl; // Адрес, по которому валяется указатель
/*Указатель валяется по отдельному адресу. А ссылка и переменная?*/
/*Теперь выводим значения*/
cout<<x<<endl; // Значение переменной
cout<<s<<endl; // Значение ссылки
cout<<p<<endl; // Значение указателя
/*А теперь значение по адресу, равному значению указателю*/
cout<<*p<<endl; // Значение переменной
Добавлено через 1 минуту
Цитата Сообщение от The_Immortal Посмотреть сообщение
Не могли бы пояснить, пожалуйста?
Пустая ссылка ни куда не ссылается, она вообще не валидна, но существовать может.
0
The_Immortal
1552 / 488 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:39  [ТС] #70
Сейчас пытаюсь разобрать пример от alkagolik:


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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 <<  endl; // вот тут застрял.
    //если честно, то ожидал увидеть: "5 5 5 5", а увидел "5 2293672 5 2293672 "
    s = y;
    cout << *p << ' ' << s << ' ' << y << x <<  endl;
 
    return 0;
}
Так вот, не могу понять почему:
//если честно, то ожидал увидеть: "5 5 5 5", а увидел "5 2293672 5 2293672 "


y не проинициализирована
Согласен. На тот момент да. Но после этого:
C++
1
*p = 5;
инициализация произошла и y=5, разве нет? Соответственно s (как и x) тоже должны быть равны значению y, а не ее адресу... А получилось не так

И только после повторного присвоения
C++
1
    s = y;
Все стало нормально...

Вот этого не понимаю

Добавлено через 9 минут
Соответственно s (как и x) тоже должны быть равны значению y, а не ее адресу...
Ммм... Адрес переменной y тут не причем. Ступил здесь. Просто какое-то рандомное значение выделенное при присвоении.
0
alkagolik
Заблокирован
31.05.2012, 17:42 #71
taras atavin, в твоем примере 11 строка некорректна. верно так
C++
1
cout << &(*p) << endl;
это все частности. Конечно "int &x == int* const p" это "грубый" пример, фактически х есть дубликат, а *р - оригинал.
0
Toshkarik
1143 / 860 / 51
Регистрация: 03.08.2011
Сообщений: 2,390
Завершенные тесты: 1
31.05.2012, 17:43 #72
Вы 'y' присваиваете ссылке 's' до того как присваиваете ей значение 5. То есть вы сначала присваиваете мусор из 'y' переменной 'x'. И только потом переменной 'y' присваиваете значение 5.
0
alkagolik
Заблокирован
31.05.2012, 17:45 #73
The_Immortal, просто s указывает на х и в строке 12 мы присваиваем х = y, но т.к. y = мусор, то и в х записывается мусор.
0
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 17:50 #74
Цитата Сообщение от alkagolik Посмотреть сообщение
cout << &(*p) << endl;
Нет, адреса значения не существует.
0
The_Immortal
1552 / 488 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:51  [ТС] #75
Toshkarik,
alkagolik,
То, что х = y, т.к. s = y - я понимаю.
Также понимаю, что т.к. y - содержит мусор и соответственно x и s содержат этот мусор я также осознаю.

НО я же
Цитата Сообщение от Toshkarik Посмотреть сообщение
потом переменной 'y' присваиваете значение 5.
правильно? Так почему мусор этот не перезаписывается?
0
31.05.2012, 17:51
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.05.2012, 17:51
Привет! Вот еще темы с ответами:

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


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

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

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