输出是什么?请解释一下,考虑到我是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));
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));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
现在是 C 语言数组速成班的时候了。
首先,让我们修复数组的初始值设定项:
这定义了
int
的 4 元素数组的 3 元素数组。 表达式a
的类型是“int
4 元素数组的 3 元素数组”。现在是令人头痛的部分。除非它是
sizeof
或一元&
运算符的操作数,或者它是用于在声明中初始化另一个数组的字符串文字,否则数组类型的表达式将将其类型隐式转换(“衰减”)为指针类型。如果表达式
a
单独出现在代码中(例如在printf("%p", a);
这样的语句中,它的类型会从“3-int
的 4 元素数组的元素数组”到“指向int
的 4 元素数组的指针”,或int (*)[4]
同样,如果出现表达式a[i]
在代码中,其类型从“int
的四元素数组”(int [4]
)转换为“指向int
的指针” (int *
)。如果a
或a[i]
是sizeof
或& 的操作数。 不会发生转换。
;,但是,类似地,数组 下标是通过指针算术完成的:表达式
a[i]
被解释为就像*(a+i)
一样,您偏移了i
。 > 从数组基数中提取元素并取消引用结果,因此,a[0]
与*(a + 0)
相同,与相同。代码>*a。
a[i][j]
与编写*(*(a + i) + j)
相同。这是一个总结了上述所有内容的表格:
希望这能为您提供弄清楚输出应该是什么所需的一切。但是,
printf
语句应写为Time for a crash course on arrays in C.
First of all, let's fix the initializer for the array:
This defines a 3-element array of 4-element arrays of
int
. The type of the expressiona
is "3-element array of 4-element arrays ofint
".Now for the headache-inducing part. Except when it's the operand of the
sizeof
or unary&
operators, or if it's a string literal being used to initialize another array in a declaration, an expression of array type will have its type implicitly converted ("decay") to a pointer type.If the expression
a
appears by itself in the code (such as in a statement likeprintf("%p", a);
, its type is converted from "3-element array of 4-element array ofint
" to "pointer to 4-element array ofint
", orint (*)[4]
. Similarly, if the expressiona[i]
appears in the code, its type is converted from "4-element array ofint
" (int [4]
) to "pointer toint
" (int *
). Ifa
ora[i]
are operands of eithersizeof
or&
, however, the conversion doesn't happen.In a similar vein, array subscripting is done through pointer arithmetic: the expression
a[i]
is interpreted as though it were written*(a+i)
. You offseti
elements from the base of the array and dereference the result. Thus,a[0]
is the same as*(a + 0)
, which is the same as*a
.a[i][j]
is the same as writing*(*(a + i) + j)
.Here's a table summarizing all of the above:
Hopefully, that should give you everything you need to figure out what the output should be. However, the
printf
statement should be written as因为二维数组被初始化为只有一维。
完整程序,供参考:
because the 2-dimensional array is initialized as though it had only one dimension.
Complete program, for reference:
首先,您的初始化是错误的:您的初始化程序用于一维数组,而您声明了一个二维数组。
其次,让我们看看您的代码做了什么。
a
是一个二维数组,因此a[0]
是int[4]
类型(一维数组),并且表示多维数组的第 0 列,并且(大部分)与指向该列的前导元素的指针相同。现在使用地址算术:a[0] + 1
是指向第 0 列中前导元素之后的元素的指针(表示为指向它的指针),即指向 1 的指针-第 0 列中的第一个元素。这就是第二个警告出现的地方,指出您的printf
参数是int*
而不是unsigned int
。接下来,
*(a[0]+1)
取消引用指向第 0 列第 1 个元素的指针。这(通常)相当于a[0][1]
。接下来,
*(*(a+0)+1))
是相同的,因为*(a+0)
与a[0] 相同
。(为了理解这一切,您需要了解一些基础知识:在 C 中
*(x + y)
与x[y]
相同,并且一维数组本质上与指向其前导元素的指针相同。)关于您的书与现实之间的差异:第一个输出值只是一个指针,因此它可以是任意值,具体取决于您的数组发生的位置留在记忆中。关于其他两个值,问题取决于错误的初始值设定项如何填充数组。
First of all, your initialization is wrong: your initializer it for one-dimensional array, whereas you declare a two-dimensional one.
Second, let's see what does your code do.
a
is a two-dimensional array, soa[0]
is of typeint[4]
(one-dimensional array), and represents the 0-th column of the multidimensional array, and is (mostly) the same as a pointer to the column's leading element. Now you use address arithmetics:a[0] + 1
is the pointer to element after the leading one in the 0-th column (represented as a pointer to it), that is, pointer to the 1-st element in the 0-th column. That's where the second warning appears, saying that your argument toprintf
isint*
and notunsigned int
.Next,
*(a[0]+1)
dereferences the pointer to the 1-st element of the 0-st column. This is (as usually) equivalent toa[0][1]
.Next,
*(*(a+0)+1))
is the same, because*(a+0)
is the same asa[0]
.(In order to understand this all, you need to know some basics: that in C
*(x + y)
is the same asx[y]
, and that the 1-dimensional array is essentially the same as the pointer to its leading element.)About the difference between your book and the reality: the first output value is just a pointer, so it can be an arbitrary value, depending on where your array happened to be in the memory. About the other two values, the question depends on how the array was filled by the wrong initializer.