输出是什么?请解释一下,考虑到我是c新手

发布于 2024-11-27 10:52:54 字数 178 浏览 2 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迎风吟唱 2024-12-04 10:52:54

现在是 C 语言数组速成班的时候了。

首先,让我们修复数组的初始值设定项:

int a[3][4] = {
                { 1,  2,  3,  4},
                { 5,  6,  7,  8},
                { 9, 10, 11, 12}
              };

这定义了 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 *)。如果 aa[i]sizeof& 的操作数。 不会发生转换。

;,但是,类似地,数组 下标是通过指针算术完成的:表达式a[i]被解释为就像*(a+i)一样,您偏移了i。 > 从数组基数中提取元素并取消引用结果,因此,a[0]*(a + 0) 相同,与 相同。代码>*a。 a[i][j] 与编写 *(*(a + i) + j) 相同。

这是一个总结了上述所有内容的表格:

Expression   Type          Decays To    Resulting Value
----------   ----          ---------    -----
         a   int [3][4]    int (*)[4]   Address of the first element of the array
        &a   int (*)[3][4] n/a          Same as above, but type is different
        *a   int [4]       int *        Same as above, but type is different
      a[0]   int [4]       int *        Same as above
    *(a+0)   int [4]       int *        Same as above
      a[i]   int [4]       int *        Address of the first element of the i'th subarray
    *(a+i)   int [4]       int *        Same as above
     &a[i]   int (*)[4]    n/a          Same as above, but type is different
     *a[i]   int           n/a          Value of the 0'th element of the i'th subarray
   a[i][j]   int                        Value of the j'th element of the i'th subarray
 *(a[i]+j)   int                        Same as above
*(*(a+i)+j)  int                        Same as above

希望这能为您提供弄清楚输出应该是什么所需的一切。但是,printf 语句应写为

printf("%p %d %d\n", (void *) a[0]+1, *(a[0]+1), *(*(a+0)+1));

Time for a crash course on arrays in C.

First of all, let's fix the initializer for the array:

int a[3][4] = {
                { 1,  2,  3,  4},
                { 5,  6,  7,  8},
                { 9, 10, 11, 12}
              };

This defines a 3-element array of 4-element arrays of int. The type of the expression a is "3-element array of 4-element arrays of int".

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 like printf("%p", a);, its type is converted from "3-element array of 4-element array of int" to "pointer to 4-element array of int", or int (*)[4]. Similarly, if the expression a[i] appears in the code, its type is converted from "4-element array of int" (int [4]) to "pointer to int" (int *). If a or a[i] are operands of either sizeof 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 offset i 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:

Expression   Type          Decays To    Resulting Value
----------   ----          ---------    -----
         a   int [3][4]    int (*)[4]   Address of the first element of the array
        &a   int (*)[3][4] n/a          Same as above, but type is different
        *a   int [4]       int *        Same as above, but type is different
      a[0]   int [4]       int *        Same as above
    *(a+0)   int [4]       int *        Same as above
      a[i]   int [4]       int *        Address of the first element of the i'th subarray
    *(a+i)   int [4]       int *        Same as above
     &a[i]   int (*)[4]    n/a          Same as above, but type is different
     *a[i]   int           n/a          Value of the 0'th element of the i'th subarray
   a[i][j]   int                        Value of the j'th element of the i'th subarray
 *(a[i]+j)   int                        Same as above
*(*(a+i)+j)  int                        Same as 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

printf("%p %d %d\n", (void *) a[0]+1, *(a[0]+1), *(*(a+0)+1));
深海蓝天 2024-12-04 10:52:54
$ 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 <stdio.h>

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;
}
$ 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]

because the 2-dimensional array is initialized as though it had only one dimension.

Complete program, for reference:

#include <stdio.h>

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;
}
穿透光 2024-12-04 10:52:54

首先,您的初始化是错误的:您的初始化程序用于一维数组,而您声明了一个二维数组。

其次,让我们看看您的代码做了什么。

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, so a[0] is of type int[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 to printf is int* and not unsigned int.

Next, *(a[0]+1) dereferences the pointer to the 1-st element of the 0-st column. This is (as usually) equivalent to a[0][1].

Next, *(*(a+0)+1)) is the same, because *(a+0) is the same as a[0].

(In order to understand this all, you need to know some basics: that in C *(x + y) is the same as x[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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文