Указатель C ++ - PullRequest
       2

Указатель C ++

29 голосов
/ 15 августа 2011

Почему 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

Ответы [ 9 ]

101 голосов
/ 15 августа 2011

Я хотел бы поделиться общей техникой, которую я использовал, чтобы узнать, как работают указатели, когда я только начинал.Если вы примените его к своей проблеме, вы увидите, что ответ прост, как день.

Возьмите большой лист миллиметровки и положите его вдоль стола перед собой.Это память вашего компьютера.Каждый блок представляет один байт.Выберите строку и поместите число «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?

8 голосов
/ 15 августа 2011

Поскольку q является адресом y.И после p=q p также становится адресом y.Вот почему p и q печатают один и тот же адрес, когда вы печатаете их, используя cout.

Другими словами, и p, и q указывают на одну и ту же переменную y.Так что если вы измените значение любого из y, *p или *q, то изменение произойдет во всех, потому что все они одинаковы!

5 голосов
/ 15 августа 2011

Хорошо, давайте посмотрим на это после каждого шага:

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.

4 голосов
/ 15 августа 2011

Значение из 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;
}
3 голосов
/ 15 августа 2011

см. Аннотации:

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;
}
2 голосов
/ 15 августа 2011
int x;int y;int *p = &x;int *q = &y;x = 35;y = 46;

Т.е. p указывает на x (35), а q указывает на y (46)

p = q;

Теперь p указывает на y (46)

*p = 90;

Теперьсодержимое p (иначе 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 - один и тот же адрес, будет выводить одно и то же значение.

2 голосов
/ 15 августа 2011

после выполнения 'p = q;'оператор, два указателя указывают на один и тот же вариант «у».Таким образом, при выполнении '* p = 90;' значение варианта 'y' изменяется.

1 голос
/ 15 августа 2011

Сначала вы определяете p как указатель, который указывает на x. А затем определите q как указатель, указывающий на y. Тогда вы написали p = q, так что теперь p и q оба будут указывать на y.

OK, изменение * p означает изменение y. затем вы назначаете 90 для y по строке * p = 90;

Теперь у вас есть это:

  • y: 90
  • p указывает на y
  • q указывает на y
  • * р: 90
  • * q: 90
1 голос
/ 15 августа 2011

Когда вы устанавливаете p=q, они оба ссылаются на одну и ту же ячейку памяти.Поэтому, если вы измените значение, на которое указывает p, оно также изменит значение, на которое указывает q, который является адресом y.Следовательно, выходные данные y, *p и *q совпадают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...