Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/47: Рейтинг темы: голосов - 47, средняя оценка - 4.85
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891

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

30.05.2012, 11:31. Показов 10062. Ответов 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
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.05.2012, 11:31
Ответы с готовыми решениями:

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

Вывод адреса указателя
Здравствуйте , ни как не могу вывести адрес указателя Вот прога program Project19; {$APPTYPE CONSOLE} {$R *.res} ...

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

103
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 16:27  [ТС]
Студворк — интернет-сервис помощи студентам
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
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
31.05.2012, 16:28
Цитата Сообщение от 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
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 16:38
Цитата Сообщение от 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
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 16:39  [ТС]
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
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
31.05.2012, 16:44
Цитата Сообщение от The_Immortal Посмотреть сообщение
Вылетает ошибка. Это потому, что по тому рандомному адресу не существует никакого значения или как это понять?
это понимай так что твоя программа пытается получить доступ к памяти, которая ей запрещена.
Цитата Сообщение от Deviaphan Посмотреть сообщение
Прям вот вообще не так.
но постой, а как же?
0
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
31.05.2012, 16:55
Цитата Сообщение от alkagolik Посмотреть сообщение
но постой, а как же?
Читай манул. У ссылки и указателя вообще ничего общего нет.
int &x = v;;
int* const point = &v;
&x == point
но не
int &x == int* const point;
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
31.05.2012, 17:07
Цитата Сообщение от 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
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:11  [ТС]
taras atavin, ой, Вы вернулись!

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

Но очень сильно хотел у Вас узнать, что все-таки имелось в виду под
Цитата Сообщение от taras atavin Посмотреть сообщение
Ссылка может быть пустой
Не могли бы пояснить, пожалуйста?
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
31.05.2012, 17:15
Цитата Сообщение от 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
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:39  [ТС]
Сейчас пытаюсь разобрать пример от 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
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
31.05.2012, 17:42
taras atavin, в твоем примере 11 строка некорректна. верно так
C++
1
cout << &(*p) << endl;
это все частности. Конечно "int &x == int* const p" это "грубый" пример, фактически х есть дубликат, а *р - оригинал.
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
31.05.2012, 17:43
Вы 'y' присваиваете ссылке 's' до того как присваиваете ей значение 5. То есть вы сначала присваиваете мусор из 'y' переменной 'x'. И только потом переменной 'y' присваиваете значение 5.
0
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
31.05.2012, 17:45
The_Immortal, просто s указывает на х и в строке 12 мы присваиваем х = y, но т.к. y = мусор, то и в х записывается мусор.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
31.05.2012, 17:50
Цитата Сообщение от alkagolik Посмотреть сообщение
cout << &(*p) << endl;
Нет, адреса значения не существует.
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:51  [ТС]
Toshkarik,
alkagolik,
То, что х = y, т.к. s = y - я понимаю.
Также понимаю, что т.к. y - содержит мусор и соответственно x и s содержат этот мусор я также осознаю.

НО я же
Цитата Сообщение от Toshkarik Посмотреть сообщение
потом переменной 'y' присваиваете значение 5.
правильно? Так почему мусор этот не перезаписывается?
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
31.05.2012, 17:51
И читай:
Цитата Сообщение от taras atavin Посмотреть сообщение
Адрес, по которому валяется указатель
. Сам указатель, а не переменная x.
0
1569 / 505 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:53  [ТС]
Цитата Сообщение от The_Immortal Посмотреть сообщение
Так почему мусор этот не перезаписывается?
Вот блин, уже на ерунде какой-то застреваю. Все понял, спасибо ребят!


Цитата Сообщение от taras atavin Посмотреть сообщение
Нет, адреса значения не существует.
Хм... А вот это интересно.
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
31.05.2012, 17:56
Как двойному указателю будешь присваивать значение?
C++
1
2
3
int x=2;
int *p=&x;
int **pp=&(*p);
? Не правильно. Правильно просто
C++
1
2
3
int x=2;
int *p=&x;
int **pp=&p;
. А значение указателя - это адрес.

Добавлено через 1 минуту
Цитата Сообщение от The_Immortal Посмотреть сообщение
Хм... А вот это интересно.
C++
1
2
3
4
5
int x;
int *p;
x=5; // x и равен 5
p=&x; // правильно
p=&5; // не правильно: хоть x и равно 5, но 5 адреса не имеет.
0
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
31.05.2012, 17:58
Цитата Сообщение от The_Immortal Посмотреть сообщение
Хм... А вот это интересно.
не ведись, он сам не понял что написал. Ссылка есть разыменованный константный указатель, т.е. сам указатель и хранить в программе не надо пойми. Создается просто дубликат переменной.

Добавлено через 2 минуты
taras atavin, разбирай
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
indicator@indicator:~$ cat test.cc
#include <iostream>
 
using namespace std;
typedef unsigned uint32;
 
int main() {
 
    int x = 9;
    int* const p = &x;
    int &s = x;
 
    cout << &(*p) << '\n' << &x << '\n' << &s << endl;
 
    return 0;
}
indicator@indicator:~$ g++ test.cc
indicator@indicator:~$ ./a.out 
0xbf921dd4
0xbf921dd4
0xbf921dd4
indicator@indicator:~$
0
 Аватар для taras atavin
4226 / 1796 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
31.05.2012, 17:58
Значения не имеют индивидуальности, а значит и адресов.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int x;
int y;
int *p;
x=5;
y=5;
p=&5; // адрес какой из пятёрок надо поместить в указатель?
/*То есть какая из переменных должна удвоиться следующей сточкой?*/
*p=*p*2;
if (x<y) // Какой символ надо вывести?
{
 cout<<"x";
}
else
{
 cout<<"y";
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.05.2012, 17:58
Помогаю со студенческими работами здесь

Как сохранить значение адреса указателя в обычную переменную?
Всем привет. Пишу лабиринт на C++. С языком знаком мало. В общем, я в курсе, что можно в функцию передавать аргументы как pointer и как...

Передача указателя в функцию, присвоение адреса переменной и возврат
Добрый день, подскажите, почему в отладке в функции указателю адрес переменной присваивается корректно, но при возврате указатель смотрит...

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

выделение памяти при увеличении адреса указателя на размерность int
добрый день, форум изучаю указатели и столкнулся с достаточно странной, для меня проблемой int в c++, как я учил, имеет стандартную...

Отличие ссылки от указателя
Здравствуйте. Не совсем понимаю отличие ссылки от указателя. В частности, при передаче результата в функции. Например, попытаюсь...


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

Или воспользуйтесь поиском по форуму:
80
Закрытая тема Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru