Я самостоятельно изучаю С++ и нашел себя в разделе Указатели на С++.
Насколько я понимаю, указатель выделяет значение переменной в память.
Но я столкнулся с этой проблемой, ответ которой 588.
И я не могу понять, как появилось это число.
Может кто-нибудь объяснить мне шаг за шагом, как появился 588?
Заранее спасибо.
#include <iostream>
int main() {
int *p, *q, *t;
// Allocate memory and initialize pointers and values
p = new int;
q = new int;
t = new int;
*p = 17;
*q = 7;
*t = 42;
p = t; // Make pointer p point to the same location as pointer t
t = q; // Make pointer t point to the same location as pointer q
*t = *p * *q;
*q = *q + *t;
std::cout << *t << std::endl;
return 0;
}
@DrewDormann часть `*q = *q + *t;` меня смущает
t и q указывают на одно и то же int, которое содержит 294. Что такое 294 + 294?
@DrewDormann `*t = *p * *q;` означает 42*7=294, а поскольку t и q указывают на одну и ту же память, q также становится 294. Так что ... хорошо
Извиняться не надо, но "я не понимаю" - это не четкий и целенаправленный вопрос. Кажется, вам не помешал бы репетитор или хорошая книга.
@DrewDormann спасибо спасибо
Указатели не выделяют память. Указатели указывают на места в памяти. Оператор new выделяет память.
Главный вывод из того, что вы узнали в этом вопросе, должен состоять в том, чтобы проверять каждый шаг каждой операции в программе, либо распечатывая переменные, используемые на этом шаге, либо наблюдая за ними с помощью отладчика. Часто отладчик является более эффективным выбором.





В комментариях к программе написано
p = t; // Make pointer p point to the same location as pointer t
t = q; // Make pointer t point to the same location as pointer q
То есть после этих утверждений *p равно 42 и *t равно 7 так же, как *q равно 7, потому что теперь оба указателя t и q указывают на одну и ту же память.
В результате у вас есть это утверждение
*t = *p * *q;
эквивалентен
*t = 42 * 7;
Это объект, на который указывают указатели t, а q теперь содержит 294.
Это утверждение
*q = *q + *t;
это то же самое, что
*t = *q + *t;
потому что оба указателя t и q указывают на один и тот же объект, а также совпадают с
*t = *t + *t;
или
*q = *q + *q;
Так что 294 plust 294 уступает 588.
Вы можете легко понять, что происходит, если выводить все три указателя и их значения после каждого их изменения или с помощью отладчика. Вот что происходит:
*p = 17;
*q = 7;
*t = 42;
// p points to an int with value 17
// q points to an int with value 7
// t points to an int with value 42
p = t; // Make pointer p point to the same location as pointer t
// p points to an int with value 42 (the same as t)
// q points to an int with value 7
// t points to an int with value 42 (the same as p)
t = q; // Make pointer t point to the same location as pointer q
// p points to an int with value 42 (now different than t)
// q points to an int with value 7 (the same as t)
// t points to an int with value 7 (the same as q)
*t = *p * *q; // *t = (*p) * (*q) = 42 * 7 = 294
// p points to an int with value 42
// q points to an int with value 294 (still the same as t)
// t points to an int with value 294 (still the same as q)
*q = *q + *t; // *q = (*q) + (*t) = 294 + 294 = 588
// p points to an int with value 42
// q points to an int with value 588 (still the same as t)
// t points to an int with value 588 (still the same as q)
std::cout << *t << std::endl; // prints 588 (the same as q)
Однако обратите внимание, что что-то вроде p = t перезаписывает адрес, на который указывал p, поэтому вы больше не можете освобождать выделенную память.
Если вы сомневаетесь, вы должны нарисовать его! Например...
int *p, *q, *t;
Вы объявляете 3 указателя, которые еще никуда не указывают, таким образом:
p -> ?
q -> ?
t -> ?
p = new int; q = new int; t = new int;
Вы выделяете 3 целых числа (с неопределенными начальными значениями) и указываете на них 3 указателя, таким образом:
p -> [ ... ]
q -> [ ... ]
t -> [ ... ]
*p = 17; *q = 7; *t = 42;
Вы разыменовываете указатели и устанавливаете значения целых чисел, на которые они указывают, таким образом:
p -> [ 17 ]
q -> [ 7 ]
t -> [ 42 ]
p = t;
Вы указываете p на то же целое число, на которое указывает t, таким образом:
p -+ [ 17 ]
|
q -|-> [ 7 ]
|
t -+-> [ 42 ]
т = д;
Вы указываете t на то же целое число, на которое указывает q, таким образом:
p -+ [ 17 ]
|
q -|-+-> [ 7 ]
| |
t -|-+
|
+---> [ 42 ]
*t = *p * *q;
Вы умножаете значения целых чисел, на которые указывают p и q (42 * 7), и присваиваете результат (294) целому числу, на которое указывает t, таким образом:
p -+ [ 17 ]
|
q -|-+-> [ 294 ]
| |
t -|-+
|
+---> [ 42 ]
*q = *q + *t;
Вы добавляете значение целого числа, на которое указывают q и t (294 + 294), и присваиваете результат (588) целому числу, на которое указывает q, таким образом:
p -+ [ 17 ]
|
q -|-+-> [ 588 ]
| |
t -|-+
|
+---> [ 42 ]
std::cout << *t << std::endl;
Вы печатаете значение целого числа, на которое указывает t, таким образом:
588
Какая строка кода делает что-то, чего вы не ожидаете? Посыпание
std::cout<<*p<<' '<<*q<<' '<<*t<<'\n';после каждой строки объяснило бы все, не так ли?