什么是输出? 请解释一下,考虑到我是c的新手
int a[3][4] = { 1,2,3,4, 5,6,7,8, 9,10,11,12, }; printf("%u %u %u \n", a[0]+1, *(a[0]+1), *(*(a+0)+1));
C语言中数组速成课程的时间
首先,让我们修复数组的初始值设定项:
int a[3][4] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 12} };
这定义了一个由4个元素组成的3元素数组。 表达式 a
的类型是“ int
元素的4元素数组的3元素数组”。
现在为引起头痛的部分。 除非它是sizeof
或一元&
运算符的操作数,或者如果它是一个字符串文字用于初始化声明中的另一个数组,数组类型的表达式将其类型隐式转换(“衰减”)为指针类型。
如果表达式a
本身出现在代码中(例如在printf("%p", a);
等语句中printf("%p", a);
,则其类型从“4元素数组的int
元素数组”转换为“指向int
元素的4元素数组,或int (*)[4]
。类似地,如果表达式a[i]
出现在代码中,其类型将从“4元素数组的int
”( int [4]
)转换to“指向int
”( int *
)。如果a
或a[i]
是sizeof
或&
操作数,则转换不会发生。
类似地,数组下标是通过指针算法完成的:表达式a[i]
被解释为它被写成*(a+i)
。 您从数组的基数偏移i
元素并取消引用结果。 因此, a[0]
与*(a + 0)
相同,与*a
相同。 a[i][j]
与写*(*(a + i) + j)
。
这是一个总结以上所有内容的表格:
表达类型衰减导致的价值 ---------- ---- --------- ----- a int [3] [4] int(*)[4]数组的第一个元素的地址 &a int(*)[3] [4] n / a与上面相同,但类型不同 * a int [4] int *与上面相同,但类型不同 a [0] int [4] int *与上述相同 *(a + 0)int [4] int *与上述相同 a [i] int [4] int *第i个子数组的第一个元素的地址 *(a + i)int [4] int *与上述相同 &a [i] int(*)[4] n / a与上述相同,但类型不同 * a [i] int n / a第i个子数组的第0个元素的值 a [i] [j] int第i个子数组的第j个元素的值 *(a [i] + j)int与上述相同 *(*(a + i)+ j)int与上述相同
希望这应该为您提供所需的一切,以确定输出应该是什么。 但是, printf
语句应该写成
printf("%p %d %d\n", (void *) a[0]+1, *(a[0]+1), *(*(a+0)+1));
$ gcc -Wall -o output output.c output.c: In function 'main': output.c:5:5: warning: missing braces around initializer [-Wmissing-braces] output.c:5:5: warning: (near initialization for 'a[0]') [-Wmissing-braces] output.c:9:5: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'int *' [-Wformat]
因为二维数组被初始化,好像它只有一个维度。
完整程序,供参考:
#include int main() { int a[3][4] = {1,2,3,4, 5,6,7,8, 9,10,11,12, }; printf ("%u %u %u \n", a[0]+1, *(a[0]+1), *(*(a+0)+1)); return 0; }
首先,你的初始化是错误的:你的初始化器是一维数组,而你声明一个二维数组。
其次,让我们看看你的代码做了什么。
a
是一个二维数组,所以a[0]
的类型为int[4]
(一维数组),表示多维数组的第0列,并且(大部分)与指向列的主要元素。 现在使用地址算术: a[0] + 1
是指向第0列中前导元素之后的元素的指针(表示为指向它的指针),即指向0-中的第1个元素的指针第二栏。 这就是出现第二个警告的地方,说你对printf
的参数是int*
而不是unsigned int
。
接下来, *(a[0]+1)
取消引用指向第0列的第1个元素的指针。 这(通常)相当于a[0][1]
。
接下来, *(*(a+0)+1))
是相同的,因为*(a+0)
与a[0]
相同。
(为了理解这一切,您需要了解一些基础知识:C *(x + y)
中的与x[y]
相同,并且1维数组与指向其前导的指针基本相同元件。)
关于你的书和现实之间的区别:第一个输出值只是一个指针,因此它可以是一个任意值,具体取决于你的数组在内存中的位置。 关于其他两个值,问题取决于数组是如何被错误的初始化程序填充的。