C 无法按预期解除多维数组的引用

C 无法按预期解除多维数组的引用,c,arrays,pointers,multidimensional-array,C,Arrays,Pointers,Multidimensional Array,声明2D数组的变量保存指向第一个数组中第一个元素的指针。arr5定义为每行有3列。通过将1添加到arr5,我们可以得到第二行中第一个元素的地址,通过将2添加到arr5,我们可以得到第三行中第一个元素的地址 int arr5[][3] = {{1,2,3}, {4,5,6}, {7,8,9}}; 取消对数组指针的引用将获取数组中的第一个元素 int *row1 = arr5; int *row2 = arr5 + 1; int *row3 = arr5 + 2; 我们可以使用[]取消对这些行中

声明2D数组的变量保存指向第一个数组中第一个元素的指针。arr5定义为每行有3列。通过将1添加到arr5,我们可以得到第二行中第一个元素的地址,通过将2添加到arr5,我们可以得到第三行中第一个元素的地址

int arr5[][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
取消对数组指针的引用将获取数组中的第一个元素

int *row1 = arr5;
int *row2 = arr5 + 1;
int *row3 = arr5 + 2;
我们可以使用[]取消对这些行中的元素的引用

printf("%d\n", *row1);  // prints 1
printf("%d\n", *row2);  // prints 4
printf("%d\n", *row3);  // prints 7
(j=0;j<3;j++)的
{
printf(“%d%c”,第1行[j],(j==2)?“\n”:”;
}//打印1 2 3
我们可以不使用括号打印第二行。第2行现在保存第二行中第一个元素的地址

for (j = 0; j < 3; j++) {
  printf("%d%c", row1[j], (j==2)?'\n':' ');
} // prints 1 2 3
(j=0;j<3;j++)的
{
printf(“%d%c”,*(第2行+j),(j==2)?”\n':“”);
}//打印4 5 6
在上面的示例中,为什么我们不能用arr5+1代替row2?第2行保存地址arr5+1

for (j = 0; j < 3; j++) {
  printf("%d%c", *(row2+j), (j==2)?'\n':' ');
}  // prints 4 5 6
(j=0;j<3;j++)的
{
printf(“%d%c”,*((arr5+1)+j),(j==2)?“\n”:”;
}//打印看起来是地址的内容

注意编译器警告
*((arr5+1)+j)
不是
int
,而是
int*

警告:格式“%d”要求参数类型为“int”,但参数2的类型为“int*”[-Wformat=]

注:
(arr5+1)+j
(arr5+1+j)
相同。我怀疑这里需要OP
*(arr5+1)+j

for (j = 0; j < 3; j++) {
  printf("%d%c", *((arr5+1)+j), (j==2)?'\n':' ');
}  // prints what looks to be addresses
除非它是
sizeof
运算符的操作数,否则
\u Alignof
运算符,或一元
“&”
运算符,或是使用的字符串文字 要初始化数组,请使用类型为“array of type”的表达式 转换为类型为“指针指向类型”的表达式 指向数组对象的初始元素,而不是 左值

因此,当您访问
arr5
时,实际上是在使用指向int[3]数组的指针。尝试分配时:

-13412 -13400 -13388  UB UB UB
4 5 6                 OK OK OK
您正试图将类型为
int(*)[3]
arr5
分配给类型为
int*
row1
,从而导致警告:

int *row1 = arr5;
要消除此警告,您需要取消对
arr5
的引用,从而生成与
int*
兼容的
int[3]
(在访问时转换为指向行中第一个元素的指针)。例如,重新安排您的示例,您可以执行以下操作:

"initialization from incompatible pointer type"

仔细检查一下,如果您还有其他问题,请告诉我。

int*row1=arr5是一个问题<代码>行1
int*
arr5
为非<代码>arr5是
(int*)[3]
<代码>int*row1=*arr5
int*row2=*(arr5+1)一样正常整数*行1=arr5;这没有问题。printf(“%d\n”,*row1);按预期打印第一行中的第一个元素。这仅限于高兴的情况。打开编译器警告,例如gcc/clang的
-Wall-Wextra-pedantic
,VS的
/W3
。“警告:从不兼容指针类型初始化”2D数组问题在示例数组不是方形数组时更清晰。考虑一个3x4数组,第一个句子是错误的。没有指针。数组是9个连续的
int
对象。对
=*arr5
部分有很好的观察力。只是因为我多次偶然发现类似的东西而变得尖锐…同意,
int[3]
int*
的兼容性是解释等价性的松散方式。通过取消对2D数组的引用来访问行数组本身将导致指向行的第一个元素的指针。非常好地说明了这一点。非常感谢。
"initialization from incompatible pointer type"
#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');
    }
}
$ ./bin/ptr2arrayauto
By row:
  1  2  3
  4  5  6
  7  8  9

By array:
  1  2  3
  4  5  6
  7  8  9