C 无法按预期解除多维数组的引用
声明2D数组的变量保存指向第一个数组中第一个元素的指针。arr5定义为每行有3列。通过将1添加到arr5,我们可以得到第二行中第一个元素的地址,通过将2添加到arr5,我们可以得到第三行中第一个元素的地址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; 我们可以使用[]取消对这些行中
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