2015-03-13 5 views
1

Я немного застрял на этом, и мне нужно было уточнить, что именно происходит. Я был бы очень признателен, если бы кто-нибудь мог мне помочь.C++ Pointer ПОЧЕМУ?

int i[][3] = { 
{ 1, 2, 3 }, 
{ 4, 5, 6 } 
}; 

int* pointy = &i[1][1]; 
int* copyPointy = pointy; 

*pointy = 100; 
pointy = &i[0][2]; 

cout << *pointy << endl; 
cout << *copyPointy << endl; 

Я хочу знать, что представляет собой следующую строку/означает:

int* copyPointy = pointy; 

Я пытаюсь выяснить, почему *copyPointy возвращается 100, а не 3? Если pointy указывает на copyPointy, а если адрес pointy изменяется при выполнении инструкции pointy = &i[0][2];, то не следует ли изменять адрес copyPointy, и, следовательно, содержимое по этому адресу?

+0

'pointy' указывает сначала на' & i [1] [1] ', а затем на' & i [0] [2] '. 'pointy' никогда не может указывать на' copyPointy', поскольку это не 'int **'. – user657267

+0

Извините, я имел в виду, что не * если copyPointy указывает на pointy, то если адрес pointy изменяется, когда pointy = & [0] [2], не должен также меняться адрес copyPointy, и, следовательно, содержимое по этому адресу ? – halapgos1

+0

Это ничего не меняет, ни точки, ни «copyPointy» не указывают друг на друга в любой точке (!). Тип указателя на указатель на 'int' будет' int ** ', это оба' int * '. – user657267

ответ

6

Важно помнить, что значение указателя - это адрес - адрес предмета, на который он указывает. Какова ценность указателя и что он указывает на две отдельные вещи.

метка Давайте ваши строки:

int i[][3] = { 
{ 1, 2, 3 }, 
{ 4, 5, 6 } 
}; 

int* pointy = &i[1][1]; 
int* copyPointy = pointy; // (1) 

*pointy = 100;   // (2) 
    pointy = &i[0][2];  // (3) 

    cout << *pointy << endl; 
    cout << *copyPointy << endl; 

После (1) трассы, pointy и copyPointy «ы значения одинаковы: оба по тому же адресу, а именно адрес второго элемента второго массива (где 5 есть).

После (2) выполняет элемент по указанному адресу получает изменено на 100. pointy и copyPointy оба все еще имеют один и тот же адрес, и поэтому они указывают на то же самое, что теперь стало целое 100.

После (3) выполняется, значение pointy теперь что-то другое, а именно - адрес 3-го элемента 1-го массива (где 3 есть). Значение copyPointy не изменилось - оно не было назначено ни на что другое, поэтому оно все еще указывает на тот же элемент, что и раньше, а именно 100.

Таким образом, при печати содержимого значений по их соответствующим адресам вы ожидаете 3 и 100, что и есть то, что вы получаете.

+1

Большое вам спасибо! Теперь это имеет гораздо больше смысла! – halapgos1

2

Указатель - это переменная, значение которой является адресом.

Помните об этом, давайте пройдемся по вашему делу:

int* pointy = &i[1][1]; 

pointy теперь держит адрес i[1][1], т.е. pointy -> Адрес A

int* copyPointy = pointy; 

Теперь присвоенным copyPointy значение pointy, который является адресом i[1][1], например Теперь copyPointy -> Адрес A и pointy -> Адрес A.

*pointy = 100; 
pointy = &i[0][2]; 

Эти заявления присваивают содержание в адресной А, 100, а затем изменить pointy в адрес B.

Похоже copyPointy -> Адрес A, который содержит 100 и pointy -> Адрес B. copyPointy не меняется с pointy, потому что вы только скопировать значение при назначении.

А также вы отметите свой вопрос C++, вы можете позволить copyPointy 3 после изменения pointy с помощью

int * &copyPointy = pointy; 

что означает copyPointy является псевдонимом pointy, как только вы измените значение pointy величина copyPointy тоже меняется.

+0

Большое вам спасибо! Это было так ясно! Это делает sooo гораздо больше смысла! – halapgos1

1

Это утверждение относится к вашему первому вопросу:

int* copyPointy = pointy; 

Это означает, что копия значения внутри pointy будет храниться внутри copyPointy. Значение внутри pointy было &i[1][1] (адрес i[1][1]). После выполнения этого оператора внутри copyPointy будет &i[1][1].

Если бы мы сделали *copyPointy прямо сейчас, у нас было бы i[1][1], то есть 5.

Теперь рассмотрим следующее утверждение Int код:

*pointy = 100; 

Здесь *pointy = 100; означает, что целое значение 100 должно заменить значение по адресу внутри pointy. После выполнения этого оператора i[1][1] будет 100.

Адрес внутри copyPointy не изменился, он по-прежнему &i[1][1]. Но значение в i[1][1] изменилось с 5 на 100. Поэтому, когда мы делаем *copyPointy, мы получаем i[1][1], который сейчас 100.

Наконец, посмотрите на это заявление:

pointy = &i[0][2]; 

Когда мы выполним это заявление, pointy будет внутри него новый адрес, а именно адрес i[0][2], который содержит целое число 3. Но адрес copyPointy по-прежнему &i[1][1], так как он просто взял копию предыдущего адреса в pointy.

В результате, когда мы делаем *pointy и *copyPointy в конце, мы получаем значения на двух разных адресах. Соответственно, целое число в i[0][2] и целое число в i[1][1].