Измените указатель на массив, чтобы получить определенный элемент массива
Я понимаю общий смысл указателей и ссылок(или, по крайней мере, я думаю, что знаю), я также понимаю, что когда я использую новая Я динамически выделяю память.
мой вопрос заключается в следующем:
если бы я использовал cout << &p
, он отобразит "местоположение виртуальной памяти"p
.
Есть ли способ, которым я мог бы манипулировать этим "местоположением виртуальной памяти"?"
например, следующий код показывает массив int
s.
если бы я хотел показать значение p[1]
и я знал "местоположение виртуальной памяти"p
, мог бы я как-нибудь сделать "&p + 1
" и получить значение p[1]
С cout << *p
, который теперь будет указывать на второй элемент массива?
int *p;
p = new int[3];
p[0] = 13;
p[1] = 54;
p[2] = 42;
5 ответов
конечно, вы можете манипулировать указателем для доступа к различным элементам массива, но вам нужно будет манипулировать содержимым указателя (т. е. адресом того, на что указывает p), а не адресом самого указателя.
int *p = new int[3];
p[0] = 13;
p[1] = 54;
p[2] = 42;
cout << *p << ' ' << *(p+1) << ' ' << *(p+2);
каждое сложение (или вычитание) означает последующий (предыдущий) элемент в массиве. Если p указывает на переменную 4 байта (например,int на типичных 32-битных ПК) по адресу скажем 12345, p+1 будет указывать на 12349, а не 12346. Примечание. Вы хотите изменить значение того, что содержит p, прежде чем разыменовать его для доступа к тому, на что он указывает.
не совсем. &p
адрес указатель p
. &p+1
будет ссылаться на адрес, который является одним int*
дальше. Что вы хотите сделать, это
p=p+1; /* or ++p or p++ */
теперь, когда ты
cout << *p;
вы получите 54. Разница в том,p
содержит адрес начала массива ints, а &p
- это адрес p. Чтобы переместить один элемент, вам нужно указать дальше в int array, не дальше по стеку, где p
жизнь.
если бы вы только &p
тогда вам нужно будет сделать следующее:
int **q = &p; /* q now points to p */
*q = *q+1;
cout << *p;
, что также выведет 54 если я не ошибаюсь.
прошло некоторое время (много лет) с тех пор, как я работал с указателями, но я знаю, что если p указывает на начало массива (т. е. p[0]), и вы увеличили его (т. е. p++), то p теперь будет указывать на p[1].
Я думаю, что вам нужно удалить ссылку p, чтобы добраться до значения. Вы разыменовываете указатель, помещая перед ним*.
So *p = 33 с изменением p[0] на 33.
Я предполагаю, что для получения второго элемента вы будете использовать *(p+1), поэтому синтаксис вам нужно было бы:
cout << *(p+1)
или
cout << *(++p)
подумайте о "типах указателей" в C и C++ как о закладке очень длинного, логического строки ячеек накладывается на байта в пространстве памяти процессора, начиная с байта 0. Ширина каждой ячейки в байтах зависит от "типа" указатель. Каждый тип указателя откладывает строку с различной шириной ячеек. А "int *"
указатель кладет ряд 4-байтовых ячеек, так как ширина хранения int составляет 4 байта. А "double *"
кладет 8-байтовую строку на ячейку; a "struct foo *"
указатель кладет строка с каждой ячейкой шириной одного "struct foo"
, что бы это ни было. "Адрес" любой "вещи" - это смещение байта, начинающееся с 0, ячейки в строке, содержащей"вещь".
арифметика указателя основана на ячейках в строке, а не на байтах. "*(p+10)
" является ссылкой на 10-ю ячейку после "p", где размер ячейки определяется типом p. Если тип " p " - "int", адрес "p+10" - 40 байт после p; если P-указатель на структуру длиной 1000 байт, " p+10" 10,000 байт после p. (Обратите внимание, что компилятор выбирает оптимальный размер для структуры, которая может быть больше, чем вы думаете; это связано с "заполнением" и "выравниванием". Обсуждаемая структура 1000 байт может занимать 1024 байта на ячейку, например, поэтому" p+10 " на самом деле будет 10,240 байта после p.)