1

输出:

a=1606416992, &a=1606416992,
*a=1, &(*a)=1606416992

程序:

#include "stdio.h"
main()
{
    int a[4]={1,2,3,4};
    printf("a=%u, &a=%u, *a=%d, &(*a)=%u\n",a,&a,*a,&(*a));
}

我知道数组名是指向数组第一个元素的指针。但我怀疑指针应该存储在某个地方并且它应该有一个地址位置。如果是这样,如何在位置“1606416992”存储元素“1”并且相同的“1606416992”是指向数组的指针的地址位置?

请帮忙澄清。

4

3 回答 3

5

数组名在表达式中使用时会衰减为指向第一个元素的指针。但是,此规则有 3 个例外:

  • 数组显示为sizeof();
  • 数组的地址由&运算符获取;
  • 该数组是一个字符串或宽字符串初始值设定项。

在您的代码中,a&(*a) 是同一件事,因为*a等同于a[0],因此与 .&(*a)的地址相同a

&a具有相同的地址,a因为 with &,数组不会衰减为指针。因此,&a表示数组的地址,即可以找到第一个元素的地址。使用&a,您不会获取指向第一个元素的指针的地址,而是获取数组的地址,因为a在这种特殊情况下不是指向第一个元素的指针。

编辑 如其他答案中所述,您应该%p在转换为之后使用打印指针值void *

printf("a=%p, &a=%p, *a=%d, &(*a)=%p\n",(void *) a, (void *) &a,*a,(void *) &(*a));
于 2013-10-13T10:51:47.827 回答
1

的输出a&a保持相同的值。但是,它们因类型而异。

a对具有类型“ ”的引用,pointer to type&a它是“ pointer-to-array-of-n-type”,其中n是数组的大小。

让我们尝试在下面的代码中理解相同的内容:

#include <stdio.h>

int main()
{

   int a[4]={1,2,3,4};

   int *ptr1=a;

   int (*ptr2)[4]=&a;

   printf("a points to first element of array :%p\n",(void*)a);
   printf("&a points to whole array. Start address is same as 'a': %p\n",(void*)&a);
   printf("Incrementing 'a' steps to the next element in array New Value: %p\n",(void*)(a+1));
   printf("Incrementing '&a' steps over the entire array. New Value: %p\n",(void*)(&a+1));

   printf("ptr1: %p, ptr2:%p\n",(void*)ptr1,(void*)ptr2);

   return 0;
}

输出:

a points to first element of array :0x7fff3da3d560
&a points to whole array. Start address is same as 'a': 0x7fff3da3d560
Incrementing 'a' steps to the next element in array New Value: 0x7fff3da3d564
Incrementing '&a' steps over the entire array. New Value: 0x7fff3da3d570
ptr1: 0x7fff3da3d560, ptr2:0x7fff3da3d560

ptr1是类型:指向整数的指针。在这个程序中,定义为指向数组名的指针。因此,保存数组第一个元素的地址。ptr1 = &a[0]

ptr2是类型:指向 4 个整数数组的指针。在这个程序中,定义为指向整个数组的指针。递增ptr2导致它跨过整个阵列。通常仅在使用数组数组操作时有用。

可视化数组的存储a

+-----------------+-----------------+-----------------+-----------------+
|        1        |        2        |        3        |        4        |
+-----------------+-----------------+-----------------+-----------------+
0x7fff3da3d560    0x7fff3da3d564    0x7fff3da3d568    0x7fff3da3d56c    0x7fff3da3d570
▲ ▲   ▲      ▲    ▲        ▲                                            ▲  ▲
| |   |      |    |        |                                            |  |
|(a)  |      |    (a + 1)  |                                            |  |
|     (ptr1) |             (ptr1 + 1)                                   |  (ptr2 + 1) 
|------------|----------------------------------------------------------|
|            |                                                          | 
|            (ptr2)                                                     |
|                                                                       |
(&a) = 0x7fff3da3d560                                                   (&a + 1) = 0x7fff3da3d570
于 2013-10-13T12:13:35.097 回答
1

数组名称是数组而不是指针,但在作为参数传递给函数时衰减为指针(不包括一些例外)。

a传递给printfthen 时,它会衰减指向其第一个元素的指针。&a是整个数组的地址a。由于每个变量占用一个或多个字节的内存:第一个字节的地址被称为变量的地址,数组的地址是堆栈内存的起始地址,也是 的第一个元素的地址a

传递&(*a)类似于传递a(取消引用a并再次引用它)。
此处还应注意,%u期望unsigned int. 要打印指针使用%p和转换的值,将需要。

printf("a=%u, &a=%u, *a=%d, &(*a)=%u\n", (void *)*a, (void *)&a,*a, (void *)&(*a));
于 2013-10-13T10:34:56.677 回答