Измените указатель на массив, чтобы получить определенный элемент массива

StackOverflow https://stackoverflow.com/questions/107294

  •  01-07-2019
  •  | 
  •  

Вопрос

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

Мой вопрос заключается в следующем:

Если бы я использовал cout << &p, он отобразит «местоположение виртуальной памяти» p.Есть ли способ манипулировать этой «виртуальной памятью»?

Например, следующий код показывает массив intс.

Если бы я хотел показать ценность p[1] и я знал «локацию виртуальной памяти» p, мог бы я как-нибудь сделать"&p + 1" и получить значение p[1] с cout << *p, который теперь будет указывать на второй элемент массива?

int *p;
p = new int[3];

p[0] = 13;
p[1] = 54;
p[2] = 42;
Это было полезно?

Решение

Конечно, вы можете манипулировать указателем для доступа к различным элементам массива, но вам нужно будет манипулировать содержимым указателя (т.адрес того, на что указывает p), а не адрес самого указателя.

int *p = new int[3];
p[0] = 13;
p[1] = 54;
p[2] = 42;

cout << *p << ' ' << *(p+1) << ' ' << *(p+2);

Каждое сложение (или вычитание) означает последующий (предыдущий) элемент массива.Если p указывает на 4-байтовую переменную (например. интервал на типичных 32-битных ПК) по адресу, скажем, 12345, p+1 будет указывать на 12349, а не на 12346.Обратите внимание, что вы хотите изменить значение того, что содержит p, прежде чем разыменовывать его, чтобы получить доступ к тому, на что он указывает.

Другие советы

Не совсем. &p это адрес указателя p. &p+1 будет ссылаться на адрес, который является одним int* дальше.То, что вы хотите сделать, это

p=p+1; /* or ++p or p++ */

Теперь, когда ты это делаешь

cout << *p;

Вы получите 54.Разница в том, p содержит адрес начала массива целых чисел, пока &p это адрес п.Чтобы переместить один элемент вперед, вам нужно указать дальше в целочисленный массив, а не дальше по вашему стеку, где p жизни.

Если бы у тебя был только &p тогда вам нужно будет сделать следующее:

int **q = &p; /* q now points to p */
*q = *q+1;
cout << *p;

Это также выведет 54, если я не ошибаюсь.

Прошло много времени (много лет) с тех пор, как я работал с указателями, но я знаю, что если p указывает на начало массива (т.е.p[0]), и вы увеличили его (т.е.p++), то p теперь будет указывать на p[1].

Я думаю, что вам нужно отменить ссылку на p, чтобы получить значение.Вы разыменовываете указатель, помещая перед ним *.

Итак, *p = 33 с заменой p[0] на 33.

Я предполагаю, что для получения второго элемента вы должны использовать *(p+1), поэтому синтаксис вам понадобится:

cout << *(p+1)

или

cout << *(++p)

Мне нравится делать это:

&p[1]

По мне так аккуратнее выглядит.

Думайте о «типах указателей» в C и C++ как о очень длинном и логическом описании. ряд ячеек накладывается на байты в пространстве памяти ЦП, начиная с байта 0.Ширина каждой ячейки в байтах зависит от «типа» указателя.Каждый тип указателя устанавливает строку с разной шириной ячеек.А "int *" Указатель размещает строку из 4-байтовых ячеек, поскольку ширина хранения целого числа составляет 4 байта.А "double *" устанавливает 8-байтовую строку на ячейку;а "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.)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top