2

有人可以解释一下数组是如何被它的名字引用的,通过在它的名字前面加上指针和双指针,就像下面的代码一样:

#include<stdio.h>

main()
{  
    int a[3][2];
    a[0][0]=15;
    a[0][1]=150;
    a[1][0]=115;
    a[1][1]=165;
    a[2][0]=135;
    a[2][1]=139;
    printf( "%u\n", a);
    printf( "%u\n", *a);
    printf( "%u\n", **a);
}
4

5 回答 5

5

第一个

printf("%u\n",a);

打印 的地址a,与第一个元素的地址相同。

第二个

printf("%u\n",*a);

取消引用a并给出第一个“行”的地址a

第三个

printf("%u\n",**a);

取消引用指向第一个“行”的指针,a并给出此二维数组中第一个元素的值。

当您在打开警告的情况下编译示例时,编译器已经开始抱怨,因此会告诉您您使用的一些类型。当您将指针作为参数提供给 时printf,您应该使用格式说明符%p

printf("%p\n",a);
printf("%p\n",*a);

格式说明符%u是 for unsigned int,如果有int,最好使用说明符%d

printf("%d\n",**a);
于 2012-12-02T14:32:44.470 回答
3

两者都是指针a*a因此将其打印在格式化输出中,就像printf()用作%p格式说明符一样。

否则,您的编译器会收到警告消息

warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type ‘int (*)[2]’ warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type ‘int *’

所以试试这个:

printf("%p\n",a);
printf("%p\n",*a);

对于第三种情况**a是类型int,所以最好使用%d%i

printf("%d\n",**a);

根据C标准,

ISO c99 standard : 7.19.6 Formatted input/output functions

9   If a conversion specification is invalid, the behavior is undefined.

    If any argument is not the correct type for the corresponding conversion 

    specification, the behavior is undefined.
于 2012-12-02T14:38:24.913 回答
0

除非它是、 或一元运算符的操作数sizeof,或者是用于在声明中初始化另一个数组的字符串文字,否则“N-element array of”类型的表达式将被转换(“decay”)为类型为“pointer to ”的表达式,表达式的值将是数组第一个元素的地址。_Alignof&TT

在第一次printf调用中,表达式a的类型为“2 元素数组的 3 元素数组int”;int根据上面的规则,表达式将被转换为类型“指针”( )的二元数组,int (*)[2]其值与 相同&a[0]

在第二次printf调用中,表达式*a的类型为“2 元素数组int”;根据上面的规则,表达式被转换为类型“指针int”(int *),它的值将与&a[0][0](这与&a[0]- 数组的第一个元素的地址相同)的地址相同数组本身)。

在第三次printf调用中,表达式**a的类型为int,其值是存储在a[0][0](本例中为 15)处的任何值。

于 2012-12-02T16:16:28.873 回答
0

就像 a 是地址而不是 *a 是 a 的值

在此处输入图像描述

于 2012-12-02T14:41:55.733 回答
0

对类型的检查是有益的。

a具有 type int [3][2],即 2 个整数的 3 个数组的数组。但是,不能在 C 中分配或传递数组类型。传递a给时发生的情况printf是,它降级为指向其第一个参数的指针,即&a[0]具有 typeint (*)[2]的指针,即指向 2 个整数数组的指针。那就是你看到的地址。

(当然,数组的第一个参数的地址也与数组本身的地址相同,所以如果你这样做printf("%u", &a);,你会看到相同的地址值(但类型会不同——&a会有 type int (*)[3][2]) .)

接下来,*a。只能解引用一个指针,所以a先降级为指针(&a[0]),然后解引用(*&a[0])。结果是a[0]的第一个元素aa[0]具有类型int [2],即 2 个整数的数组。同样如上所述,不能传递数组,因此当您将其传递给 时printf,它会降级为指向其第一个参数的指针,即&a[0][0]具有类型int *的指针,指向 int。那就是您第二个看到的地址。同样,它将是与上面相同的地址,因为 的a[0]地址与其第一个元素的地址相同a[0][0](但类型不同)。

最后,你有**a. 如上所述,*ais a,降级,然后取消引用。记住上面*a有 type int [2],一个数组类型。与 一样a,当您取消引用它时,它会在取消引用之前将其隐式降级为指针。降级、取消引用、降级和再次取消引用也是**a如此。a对正在发生的事情的更明确的描述是*&(*&a[0])[0]。最终结果是a[0][0],它有 type int

于 2012-12-02T21:06:20.393 回答