Назначение указателя на С++
Почему 90
выходное значение y
и q
? Я просто делаю p=q
. Как изменилось значение q
?
int main()
{
int x;
int y;
int *p = &x;
int *q = &y;
x = 35;
y = 46;
p = q;
*p = 90;
cout << x << " " << y << endl;
cout << *p << " " << *q << endl;
cout << "Address of p = " << p << endl;
cout << "Address of q = " << q << endl;
return 0;
}
Вывод:
35 90
90 90
Address of p = 0xbffa83c0
Address of q = 0xbffa83c0
Ответы
Ответ 1
Я хотел бы поделиться общей техникой, которую я использовал, чтобы узнать, как работают указатели, когда я начинаю. Если вы примените его к своей проблеме, вы увидите ответ как простой, как день.
Получите большой лист графической бумаги и положите его вдоль стола перед собой. Это ваша память компьютера. Каждый ящик представляет собой один байт. Выберите строку и поместите номер "100" под полем слева. Это "самый низкий адрес" памяти. (Я выбрал 100 как произвольное число, которое не равно 0, вы можете выбрать другое.) Поместите поля в порядке возрастания слева направо.
+---+---+---+---+---+--
| | | | | | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
Теперь, на данный момент, сделайте вид, что int - один байт. Вы восьмибитовый компьютер. Напишите int a
в один из полей. Номер под полем - его адрес. Теперь выберите другой блок, содержащий int *b = &a
. int *b
также является переменной, хранящейся где-то в памяти, и это указатель, содержащий &a
, который произносится как "адрес".
int a = 5;
int *b = &a;
a b
+---+---+---+---+---+--
| 5 | |100| | | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
Теперь вы можете использовать эту модель для визуальной работы с любыми другими комбинациями значений и указателей, которые вы видите. Это упрощение (потому что, как говорят слова педанты, указатель не обязательно является адресом, а память не обязательно последовательна, а там стек, куча и регистры и т.д.), Но это довольно хорошая аналогия для 99% компьютеров и микроконтроллеров.
Итак, в вашем случае
int x = 35;
int y = 46;
x y
+---+---+---+---+---+--
| 35| 46| | | | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
int *p = &x;
int *q = &y;
x y p q
+---+---+---+---+---+--
| 35| 46|100|101| | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
p = q;
x y p q
+---+---+---+---+---+--
| 35| 46|101|101| | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
*p = 90;
x y p q
+---+---+---+---+---+--
| 35| 90|101|101| | ...
+---+---+---+---+---+--
100 101 102 103 104 ...
Теперь что такое *p
? Что такое *q
?
Ответ 2
Потому что q
- адрес y
. А после p=q
, p также становится адресом y
. Вот почему p
и q
печатают один и тот же адрес при печати с помощью cout
.
Другими словами, оба p
и q
указывают на одну и ту же переменную y
. Поэтому, если вы измените значение любого из y
, *p
или *q
, тогда изменение произойдет во всех, потому что все они одинаковы!
Ответ 3
Значение q
не изменилось, q
все еще указывает на y
. Тем не менее, p
указывает на y
тоже после p = q
, поэтому *p
по существу y
, а *p = 90
присваивается y
.
Обратите внимание, что cout << "Address of p = " << p << endl;
вводит в заблуждение: p
и адрес p
являются двумя разными животными.
Итак, ваш код работает следующим образом:
int main() {
int x;
int y;
int *p = &x; // now p points to x
int *q = &y; // now q points to y
x = 35;
y = 46;
p = q; // now p is the same as q, i.e., points to y
*p = 90; // p points to y, so *p is y.
// so we assign 90 to y
cout << x << " " << y << endl;
cout << *p << " " << *q << endl; // both *p and *q are y
cout << "Address of p = " << p << endl;
cout << "Address of q = " << q << endl;
return 0;
}
Ответ 4
Хорошо посмотрим на это после каждого шага:
int x;
int y;
Теперь у нас есть две переменные x
и y
:
int *p = &x;
int *q = &y;
Объявлены еще две переменные, указатель p
, который указывает на переменную x
и содержит ее адрес и указатель q
, который указывает на переменную y
и содержит ее адрес:
x = 35;
y = 46;
Здесь вы присваиваете значения переменным, это ясно:
p = q;
Теперь вы назначаете адрес, хранящийся в q
, переменной p
, поэтому обе переменные указывают на адрес в q
, что является адресом y
:
*p = 90;
Здесь вы разыскиваете p
, который является переменной по адресу в p
, и это y
, и вы присваиваете значение 90
переменной y
.
Ответ 5
после выполнения 'p = q;' оператор, два указателя указывают на один и тот же вариант 'y'. Поэтому при выполнении '* p = 90;' изменяется значение варианта 'y'.
Ответ 6
int x;int y;int *p = &x;int *q = &y;x = 35;y = 46;
I.e p указывает на x (35), а q указывает на y (46)
p = q;
Теперь p указывает на y (46)
*p = 90;
Теперь содержимое p (aka y) = 90
Теперь x = 35, y = 90, p и q указывают на y
cout << x << " " << y << endl;
Печать x, y, т.е. 35 и 90
cout << *p << " " << *q << endl;
p и q указывают на одно и то же: y - значение 90, следовательно, 90 и 90 выводятся
cout << "Address of p = " << p << endl;cout << "Address of q = " << q << endl;
Так как p и q - один и тот же адрес, выдается то же значение.
Ответ 7
См. анотации:
int main()
{
int x;
int y;
int *p = &x;
int *q = &y;
x = 35;
y = 46;
p = q; // at this point p is now pointing to the same memory address
// as q, both of them are pointing to the memory allocated to y
*p = 90; // this will also change the values in *q and y
cout << x << " " << y << endl;
cout << *p << " " << *q << endl;
cout << "Address of p = " << p << endl;
cout << "Address of q = " << q << endl;
return 0;
}
Ответ 8
Когда вы устанавливаете p=q
, они оба ссылаются на одну и ту же ячейку памяти. Поэтому, если вы измените значение, на которое указывает p
, оно также изменит значение, на которое указывает q
, который является адресом y
. Следовательно, выходные данные y
, *p
и *q
совпадают.
Ответ 9
Сначала вы определяете p как указатель, который указывает на x. А затем определите q как указатель, указывающий y.
Затем вы написали p = q, так что теперь p и q оба будут указывать на y.
ОК, изменение * p означает изменение y. то вы назначаете 90 на y по строке * p = 90;
Теперь у вас есть следующее:
- y: 90
- p указывает на y
- q указывает на y
- * p: 90
- * q: 90