2013-04-09 1 views
0

Извините, но я все еще довольно новичок в C++ - следуя следующему из предыдущего вопроса Aliasing vector correctly, как (*M)[i][j] и *(M[i][j]) разные (где M - указатель на массив целых указателей)?указатель на синтаксис матрицы 2 d

Из того, что я могу сказать, кажется, что первая эквивалентна *(*((*MPtr) + i) + j)), а последняя такая же, как *(*(*(MPtr + i) + j)) (где MPtr - указатель на M). Однако я не уверен в значении (MPtr + i) - как мне это интерпретировать?

+0

Вы имеете в виду '(* M) [i] [j]' для первого? –

+0

Да, это то, что я имел в виду, извините! – UserUnspecified

ответ

1
(M*)(i][j] 

Это синтаксическая ошибка (фактически, две). Если вы имели в виду

T (*M)[i][j] 

вместо этого, то это объявление указателя на i x j массив элементов типа T. В противоположность этому,

(*M)[i][j] 

сам по себе, это выражение, в котором M либо указатель на, по меньшей мере 2 одномерный массив или указатель на указатель на указатель. Затем M разыменовывается, и результирующий массив или двойной указатель индексируется соответственно.

Аналогично, выражение

*(M[i][j]) 

действует только тогда, когда M представляет собой массив массива указателей (или любой класс, который перегружает operator*), и это означает, что «разыменование указателя, который является [i][j] я элемента массив M ".

Edit: причина, почему индексация кажется это неверно (при условии, что M является указателем на двумерный массив):

(*M)[i][j] = M[0][i][j] 

так это [i][j] й элемент массива (как и ожидалось). В отличие от этого,

*(M[i][j]) = M[i][j][0] 

что неправильно, когда M является указателем только один массив (чтение прошлых границ массива вызывает неопределенное поведение).

+0

Я думаю, что они означали '(* M) [i] [j]' как выражение (так разыменовывая «M»). –

+0

@sftrabbit Я добавил объяснение этому значению, спасибо. – 2013-04-09 20:22:46

+0

О, извинения, но да, (* M) [i] [j] - это то, что я имел в виду.M - указатель на массив указателей на целые числа. Поэтому я не совсем понимаю, почему (* M) [i] [j] дал бы другой результат от * (M [i] [j]) - почему последний дал [j] [i] th элемент матрицы вместо [i] [j] th (с какой проблемой я сталкиваюсь)? – UserUnspecified

1

Когда у вас есть массив, компьютер сохраняет указатель на начало массива. Это Mptr. Если вы пишете Mptr + i, который является goint для перевода, как адрес памяти Mptr + размера вашего типа Mptr * i.

Sintax, который вы написали, ошибочен, поскольку вы разыскиваете M [i] [j] то, что не является адресом памяти, кроме этого, если вы пишете * (M [i]) вместо * M [i], I считайте, что у * есть более высокий приоритет, так что в первом случае M + i получает разыменованное и повторно переопределенное на втором месте M сначала разыменовывается, а затем добавляется i и снова разыгрывается * ((* M) + i), этот обратный порядок вызовет ваш i должен вести себя как j. напишите свой код так, как вы думаете, это более читаемо, поэтому не нравится это * (* (* (MPtr + i) + j)).

+0

Спасибо за ответ, но я попытался использовать обозначение смещения указателя, чтобы понять, почему * (M [i] [j]) ведет себя как (* M) [j] [i] - вы правы, что существует некоторая реверсия но я не совсем понимаю ваше объяснение. Что вы подразумеваете под «обратным порядком, вы будете вести себя как j»? Код выполняет желаемый путь в первом случае (* M) [i] [j], но в неправильном порядке в * (M [i] [j]) - поведение, подобное i и j, отменено – UserUnspecified

+0

@ user1922001 I означает, что вы пишете * M [i], который будет переведен в M [0] [i], потому что сначала будет выполнено M. Если вы говорите * (M [i]), вы говорите, что comuter не выполняет сначала M, так что это будет M [i] [0], потому что M [i] будет выполнен первым. Он очень сложный и связанный с материалом, называемым таблицей приоритетов, который я бы сказал вам, что * имеет приоритет над оператором [], если вы не указали иначе с помощью скобок, но, по общему мнению, они будут выполняться слева направо. – user2230168

Смежные вопросы