За исключением случаев, когда это операнд оператора sizeof
, _Alignof
оператор, или унарный оператор '&'
, или используется строковый литерал
чтобы инициализировать массив, выражение, которое имеет тип «массив типа»
преобразуется в выражение с типом «указатель на тип» , которое
указывает на начальный элемент объекта массива и не является
именующий. C11 Standard - 6.3.2.1 Другие операнды - L-значения, массивы и
функция
десигнаторами (p3)
Поэтому, когда вы получаете доступ к arr5
, вы эффективно используете указатель на массив int [3] . При попытке присвоить:
int *row1 = arr5;
Вы пытаетесь присвоить arr5
типа int(*)[3]
row1
, что составляет int*
, что приводит к предупреждению:
"initialization from incompatible pointer type"
Чтобы устранить предупреждение, вам нужно разыменовать arr5
, в результате чего получается тип int[3]
(который при обращении преобразуется в указатель на первый элемент в строке), который совместим с int*
. Например, немного переставив ваш пример, вы можете сделать:
#include <stdio.h>
int main (void) {
int arr5[][3] = {{1,2,3}, {4,5,6}, {7,8,9}},
*row1 = *arr5,
*row2 = *(arr5 + 1),
*row3 = *(arr5 + 2);
size_t nrow = sizeof arr5 / sizeof *arr5,
ncol = sizeof *arr5 / sizeof **arr5;
puts ("By row:");
for (size_t j = 0; j < ncol; j++) /* output row1 */
printf ("%3d", *(row1 + j));
putchar ('\n');
for (size_t j = 0; j < ncol; j++) /* output row2 */
printf ("%3d", *(row2 + j));
putchar ('\n');
for (size_t j = 0; j < ncol; j++) /* output row3 */
printf ("%3d", *(row3 + j));
putchar ('\n');
puts ("\nBy array:");
for (size_t i = 0; i < nrow; i++) { /* output arr5 */
for (size_t j = 0; j < ncol; j++)
printf ("%3d", *(*(arr5 + i) + j));
putchar ('\n');
}
}
( примечание: row1[j]
и arr5[i][j]
обычно более читабельны, чем их эквиваленты для обозначения указателя)
Пример использования / Вывод
$ ./bin/ptr2arrayauto
By row:
1 2 3
4 5 6
7 8 9
By array:
1 2 3
4 5 6
7 8 9
Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.