Проблема понимания указателя на массив указателей - PullRequest
4 голосов
/ 05 сентября 2010

Это, наверное, глупый вопрос, но я не понимаю, почему это работает:

 int** test = new int*[7];

 int x = 7;
 *(test+1) = &x;

 cout << (**(test+1));

test - это указатель на указатель, верно?Второй указатель указывает на массив, верно?В моем понимании мне нужно сначала разыменовать указатель «test», чтобы получить указатель, который имеет массив.

(*test) // Now I have int*
*((*test) + 1) // to access the first element.

Где мое ошибочное мышление?

Ответы [ 4 ]

12 голосов
/ 05 сентября 2010

int ** test = new int * [7];

+------++------++------++------++------++------++------+
| int* || int* || int* || int* || int* || int* || int* |
+------++------++------++------++------++------++------+

является эквивалентом массива с указателями int:

int* test[0] 
int* test[1] 
...
int* test[6] 

this

int x = 7;
 *(test+1) = &x;

+------++------++------++------++------++------++------+
| int* || &x   || int* || int* || int* || int* || int* |
+------++------++------++------++------++------++------+

совпадает с

int x = 7;
test[1] = &x

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

 cout << (**(test+1));

совпадает с

cout << *test[1] 

, который является значением x (== 7) и на который указывают оба теста [1] и & x.

9 голосов
/ 05 сентября 2010

Является ли ваше недопонимание тем, что вы думаете, что создали указатель на массив 7 int?У вас нетВы на самом деле создали массив 7 указателей на int.Так что здесь нет «второго указателя», который бы указывал на массив.Есть только один указатель, который указывает на первый из 7 указателей (test).

И с *test вы получите тот первый указатель, который вы еще не инициализировали.Если вы добавите 1 к , что , вы добавите 1 к некоторому случайному адресу.Но если вы добавите 1 к test, вы получите указатель, который указывает на второй указатель массива.И разыскивая , что вы получите тот второй указатель, который вы сделали инициализировали.


То, что вы описываете, будет достигнуто с помощью другого синтаксиса

typedef int array[7];
array* test = new int[1][7];

// Note: "test" is a pointer to an array of int. 
// There are already 7 integers! You cannot make it
// point to an int somehow. 
*(*test + 1) = 7;

int *p1 = *test
int i1 = *(p1 + 1); // i1 is 7, second element of the int[7]

delete[] test;

Без использования typedef это выглядит следующим образом:

int(*test)[7] = new int[1][7];

То естьВы создали одноэлементный массив, где типом элемента является массив из 7 элементов типа int.new возвращает указатель на этот массив.Обратите внимание, что скобки важны: * имеет меньший приоритет, чем [7], так что в противном случае это было бы принято как массив из 7 указателей на целые числа.

1 голос
/ 05 сентября 2010

Предположим, что

test[0] = 0x12345678;   // some pointer value
test[1] = 0x23456789;   // some pointer value

* test = 0x12345678;

* test + 1 теперь 0x12345678 + 1 = 0x12345679;

* or dereference operator has higher precedence than binary +).Таким образом, выражение вычисляется в таком порядке.

Однако вы хотели бы получить test [0] = 0x23456789;

Таким образом, правильное выражение, чтобы добраться до test[1] = (*(test + 1))

В целом arr[i] - это *(arr + i)

РЕДАКТИРОВАТЬ 2:

учитывая

int buf[10] = {0, 1, 2};
int *p = buf;

buf [0] == p [0]== * (p + 0) равно 0.

Обратите внимание, что вполне нормально использовать синтаксис доступа к массиву с выражением lvalue p, даже если это не тип массива.Фактически, выражение buf[0] также внутренне переводится компилятором в *(buf + 0).

0 голосов
/ 05 сентября 2010

Выражение *(test + 1) эквивалентно test[1], поэтому ваш код можно переписать следующим образом:

int** test = new int*[7];

int x = 7;
test[1] = &x;

cout << *test[1];

Поскольку test[1] явно указывает на x, *test[1] равно 7.

Для ясности, выражение **(test + 1) просто эквивалентно *(*(test + 1)), что, в свою очередь, эквивалентно *test[1].

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