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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 36, средняя оценка - 4.69
The_Immortal
1548 / 484 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
30.05.2012, 11:31     Понимание адреса, ссылки и указателя #1
Гм... Конечно, стремно создавать подобную тему, однако, уж очень захотелось понять все это дело. Правда сколько раз ни пытался - не удавалось ни разу, возможно, потому что пытался разобраться самостоятельно (хотя, наверное, многие это постигают именно так). Но вот моя очередная попытка, которую решил так сказать обнародовать Поэтому очень рассчитываю на вашу помощь и поддержку.

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

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-единица у нас вдруг байт. Или это не так?

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

Спасайте...
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.05.2012, 11:31     Понимание адреса, ссылки и указателя
Посмотрите здесь:

Ссылки и адреса C++
C++ Возвращение ссылки или указателя на закрытый элемент класса.
Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... C++
При передачи указателя на обьект ошибка,а при передаче ссылки на указатель нет. Почему? C++
Функция с возвратом указателя и возвратом ссылки C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
The_Immortal
1548 / 484 / 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.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
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;
}
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 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;
Прям вот вообще не так.
The_Immortal
1548 / 484 / 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;
    
}
Вылетает ошибка. Это потому, что по тому рандомному адресу не существует никакого значения или как это понять?
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
31.05.2012, 16:44     Понимание адреса, ссылки и указателя #65
Цитата Сообщение от The_Immortal Посмотреть сообщение
Вылетает ошибка. Это потому, что по тому рандомному адресу не существует никакого значения или как это понять?
это понимай так что твоя программа пытается получить доступ к памяти, которая ей запрещена.
Цитата Сообщение от Deviaphan Посмотреть сообщение
Прям вот вообще не так.
но постой, а как же?
Deviaphan
Делаю внезапно и красиво
Эксперт C++
 Аватар для Deviaphan
1283 / 1217 / 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;
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 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 Посмотреть сообщение
Вылетает ошибка. Это потому, что по тому рандомному адресу не существует никакого значения или как это понять?
Значение там может и валяться, такое же мусорное, а нет права доступа по такому адресу.
The_Immortal
1548 / 484 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:11  [ТС]     Понимание адреса, ссылки и указателя #68
taras atavin, ой, Вы вернулись!

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

Но очень сильно хотел у Вас узнать, что все-таки имелось в виду под
Цитата Сообщение от taras atavin Посмотреть сообщение
Ссылка может быть пустой
Не могли бы пояснить, пожалуйста?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 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 Посмотреть сообщение
Не могли бы пояснить, пожалуйста?
Пустая ссылка ни куда не ссылается, она вообще не валидна, но существовать может.
The_Immortal
1548 / 484 / 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 тут не причем. Ступил здесь. Просто какое-то рандомное значение выделенное при присвоении.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
31.05.2012, 17:42     Понимание адреса, ссылки и указателя #71
taras atavin, в твоем примере 11 строка некорректна. верно так
C++
1
cout << &(*p) << endl;
это все частности. Конечно "int &x == int* const p" это "грубый" пример, фактически х есть дубликат, а *р - оригинал.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
31.05.2012, 17:43     Понимание адреса, ссылки и указателя #72
Вы 'y' присваиваете ссылке 's' до того как присваиваете ей значение 5. То есть вы сначала присваиваете мусор из 'y' переменной 'x'. И только потом переменной 'y' присваиваете значение 5.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
31.05.2012, 17:45     Понимание адреса, ссылки и указателя #73
The_Immortal, просто s указывает на х и в строке 12 мы присваиваем х = y, но т.к. y = мусор, то и в х записывается мусор.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 17:50     Понимание адреса, ссылки и указателя #74
Цитата Сообщение от alkagolik Посмотреть сообщение
cout << &(*p) << endl;
Нет, адреса значения не существует.
The_Immortal
1548 / 484 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:51  [ТС]     Понимание адреса, ссылки и указателя #75
Toshkarik,
alkagolik,
То, что х = y, т.к. s = y - я понимаю.
Также понимаю, что т.к. y - содержит мусор и соответственно x и s содержат этот мусор я также осознаю.

НО я же
Цитата Сообщение от Toshkarik Посмотреть сообщение
потом переменной 'y' присваиваете значение 5.
правильно? Так почему мусор этот не перезаписывается?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 17:51     Понимание адреса, ссылки и указателя #76
И читай:
Цитата Сообщение от taras atavin Посмотреть сообщение
Адрес, по которому валяется указатель
. Сам указатель, а не переменная x.
The_Immortal
1548 / 484 / 8
Регистрация: 04.04.2009
Сообщений: 1,891
31.05.2012, 17:53  [ТС]     Понимание адреса, ссылки и указателя #77
Цитата Сообщение от The_Immortal Посмотреть сообщение
Так почему мусор этот не перезаписывается?
Вот блин, уже на ерунде какой-то застреваю. Все понял, спасибо ребят!


Цитата Сообщение от taras atavin Посмотреть сообщение
Нет, адреса значения не существует.
Хм... А вот это интересно.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 17:56     Понимание адреса, ссылки и указателя #78
Как двойному указателю будешь присваивать значение?
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 адреса не имеет.
alkagolik
 Аватар для alkagolik
1510 / 616 / 79
Регистрация: 15.07.2011
Сообщений: 3,552
31.05.2012, 17:58     Понимание адреса, ссылки и указателя #79
Цитата Сообщение от 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:~$
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.05.2012, 17:58     Понимание адреса, ссылки и указателя
Еще ссылки по теме:

Изменение адреса указателя C++
C++ Передача как указателя и как ссылки
Передача ссылки и указателя в функцию C++

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

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
31.05.2012, 17:58     Понимание адреса, ссылки и указателя #80
Значения не имеют индивидуальности, а значит и адресов.
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";
}
Yandex
Объявления
31.05.2012, 17:58     Понимание адреса, ссылки и указателя
Закрытая тема Создать тему
Опции темы

Текущее время: 12:24. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru