int arr5[][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
声明2D数组的变量包含指向第一个数组中第一个元素的指针。 arr5定义为每行3列。通过将arr5加1,我们获得第二行中第一个元素的地址,通过将2添加到arr5中,我们获得第三行中的第一个元素的地址。
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
我们可以使用[]取消引用这些行中的元素。
for (j = 0; j < 3; j++) {
printf("%d%c", row1[j], (j==2)?'\n':' ');
} // prints 1 2 3
我们可以不使用方括号打印第二行。现在,第2行保存第二行中第一个元素的地址。
for (j = 0; j < 3; j++) {
printf("%d%c", *(row2+j), (j==2)?'\n':' ');
} // prints 4 5 6
在上面的示例中,为什么不能用arr5 + 1代替row2? row2保留地址arr5 + 1。
for (j = 0; j < 3; j++) {
printf("%d%c", *((arr5+1)+j), (j==2)?'\n':' ');
} // prints what looks to be addresses
答案 0 :(得分:4)
除非它是
sizeof
运算符的操作数,否则_Alignof
运算符,或者一元'&'
运算符,或者是字符串文字 初始化数组,该表达式的类型为“数组类型” 转换为类型为“类型的指针” 的表达式 指向数组对象的初始元素,而不是 左值。 C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)
因此,当您访问arr5
时,实际上就是在使用指向int [3]数组的指针。。尝试分配时:
int *row1 = arr5;
您尝试将类型为arr5
的{{1}}分配给int(*)[3]
的{{1}},从而导致警告:
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]
仔细检查一下,如果还有其他问题,请告诉我。
答案 1 :(得分:3)
注意编译器警告。 *((arr5+1)+j)
不是int
,而是int *
。
警告:格式'%d'期望类型为'int'的参数,但是参数2的类型为'int *'[-Wformat =]
注意:(arr5+1)+j
与(arr5+1+j)
相同。我怀疑OP想要*(arr5+1)+j
在这里。
int main() {
int arr5[][3] = {{1,2,3}, {4,5,6}, {7,8,9}};
for (int j = 0; j < 3; j++) {
printf("%d%c", *((arr5+1)+j), (j==2)?'\n':' '); // Warning here!!
}
for (int j = 0; j < 3; j++) {
printf("%d%c", *(*(arr5+1)+j), (j==2)?'\n':' ');
// ^
}
return 0;
}
输出
-13412 -13400 -13388 UB UB UB
4 5 6 OK OK OK