2012-12-02 154 views
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); 
} 
+0

请更好地解释你的问题。我只看到代码是无效的(前两个'printf'语句)。 –

+0

可能重复的[是数组名称中的一个指针?](http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c) – WhozCraig

回答

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); 

格式说明%uunsigned int,如果你有int,最好使用符%d

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

请注意,它是不正确的使用' %1“和”2“。 –

+0

在前两种情况下,printf(”%u \ n“,a/* a)应该是'printf(”%p \ n“,a/* a)'。它应该是'printf(“%d \ n”,** a);'在最后一种情况下。请考虑更新答案以添加此内容。 – axiom

+1

而且,为了学习,指针应该被转换为“void *”。在指向不同类型的指针具有不同大小的平台上,这实际上很重要(但这些平台可能是假设的)。 –

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); 

对于第三种情况**aint型的,因此最好使用%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. 
0

它像如果是地址比* a是一个

enter image description here

0

值除了当它是的sizeof_Alignof操作数,或一元&运算符,或者是在声明中用于初始化另一个数组的字符串文本,则类型为“T”的“N元素数组”的表达式将转换(“衰减”)为“指向T的指针”类型的表达式,并且表达式的值将是该数组的第一个元素的地址。

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

在第二个printf调用中,表达式*a具有类型“int”的2元素数组;通过上述规则,表达式转换为类型“指向int”(int *)的指针,其值将与&a[0][0]相同(与&a[0]相同 - 数组的第一个元素的地址相同作为数组本身的地址)。

在第三printf呼叫时,表达**a具有类型int,并且它的值是什么存储在a[0][0](15在这种情况下)。

0

检查类型是有启发性的。

a具有类型int [3][2],即具有2个整数的3个阵列的阵列。但是,数组类型不能在C中分配或传递。当通过aprintf时,发生什么情况是降级为指向其第一个参数的指针,即&a[0],其类型为int (*)[2],即指向数组2个整数。这是你看到的地址。 (当然,数组的第一个参数的地址也与数组本身的地址相同,所以如果你做了printf("%u", &a);,你会看到相同的地址值(但是类型会有所不同 - - &a将具有类型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。如上所述,*aa,退化,然后解除引用。请记住,*a的数组类型为int [2]。与a一样,当您解引用它时,它会在将其解除引用之前隐式降级为指针。所以**aa,退化,解除引用,退化和解除引用。对发生的事情更明确的描述是*&(*&a[0])[0]。最终结果为a[0][0],其类型为int