1

在这个程序中,我提到的所有三个地址都引用了数组的第一个元素,但是当我取消引用它们时,为什么我没有得到数组第一个元素的值呢?

int main()  
{  
    int a[5] = {1,2,3,4,5};  
    printf("address a = %d\n",a);  
    printf("address of a[0] = %d\n",&a[0]);  
    printf("address of first element = %d\n",&a);  
    printf("value of first element of the array a =%d\n",*(a));  
    printf("first element =%d\n",*(&a[0]));  
    printf("a[0] = %d\n",*(&a));//this print statement again prints the address of a[0] 

    return 0;  
}

我得到了前 3 个打印语句的数组第一个元素的地址,a当我取消引用所有 3 个时,我只得到第四个和第五个打印语句的值,而不是第六个打印语句(附有注释)的值。

4

4 回答 4

5

要记住的事情:

  1. 数组的名称是它的第一个元素的地址

因此,由于数组名称是 a,那么打印 a 将为您提供a[0](这也是数组的地址)的地址,即您将获得&a[0](same as a) 的值并且&a是相同的

现在,您知道a&a[0]引用第一个元素,您可以通过 3 种方式取消引用第一个元素:-

  • *a
  • *(&a[0])
  • a[0]- 请注意,在内部,这将转换为:*(a+0)

要记住的事情:

   2. 给指针加一个整数,得到指向下一个元素的指针

这里,&a指向整个数组的地址。虽然 的值与and&a相同,但是,它是指向数组的指针,而不是指向第一个元素的指针。因此,如果您将 1 添加到ie ,您将超出此数组。&a[0]a&a&a + 1

类似地,作为&a[0]a是指向第一个元素的指针,向它们加 1 将为您提供数组的下一个元素(如果数组中定义了超过 1 个项目)。即(a+1)&a[0] + 1从第一个元素指向下一个元素。现在,为了取消引用它们,您可以使用:

  • *(a+1)
  • *(&a[0] +1)
  • a[1]- 请注意,在内部,这将转换为:*(a+1)

添加更多信息以消除以下疑问:

如果如this answer所述,数组的名称是其第一个元素的地址,那么 &a 将是第一个元素的地址。

这个疑问的答案是“不”和“是”。

  • 不,因为没有类似地址的地址。
  • 为了理解是的,请考虑以下情况:

    假设您有 10 盒巧克力,每个盒子包含 5 块巧克力(在盒子内排成一排)并且盒子排成一排。

5 盒,每盒 5 块巧克力

好的,足够的巧克力来解释。

在这里,盒子代表巧克力阵列。因此,我们有 5 盒每盒 5 块巧克力。对此的声明将是:

将其转换为 C,假设它a是一个包含 5 个数字的数组。

-现在,如果我让你告诉我第一个盒子的位置,那么,你将把它称为&a。如果我让你给我第二个盒子的位置,那么你将把它称为&a +1.

  • 如果我让你告诉我第一个盒子里第一块巧克力的位置,那么你将把它称为&a[0]or(a+0)a
  • 如果我让你告诉我第二个巧克力在第一个盒子里的位置,那么你将把它称为&a[1]or(a+1)a+1注意:在(a+1)中,asa是数组的名称,它是第一个元素的地址,它是一个整数。因此,a加 1 表示第二个元素的地址。
  • 如果我让你告诉我第二盒巧克力的位置,那么,你会称它为(&a+1)
  • 如果我让你告诉我第二盒巧克力中第一块巧克力的位置,那么,你将把它称为*(&a+1)*((&a+1) + 0)
  • 如果我让你告诉我第二盒巧克力中第三块巧克力的位置,那么,你会称它为(*(&a+1))+2
于 2012-08-20T06:50:09.010 回答
0

C 标准规定,类型为“类型数组”的表达式转换为类型“类型指针指向数组的初始元素,除非表达式是&(或其他三个例外,如下所述)的操作数但与这个问题无关)。以下是这适用于您的示例的方式:

  • a是一个 int 数组。它被转换为指向 int 的指针。该值是 的初始元素的地址a
  • &a[0]中,a[0]首先处理。a再次转换为指向 int 的指针。然后应用下标运算符,它为数组的初始元素生成一个左值。最后,&取这个左值的地址,所以这个值就是 的初始元素的地址a
  • 其中&a,a是 的操作数&,因此不会a转换为指向 int 的指针。它仍然是一个数组,并获取它的地址。结果的类型是“指向 int 数组的指针”,它的值是数组的地址,它等于初始元素的地址。&a

为了完整起见:C 标准中的相关规则是 6.3.2.1 第 3 段。例外情况是:

  • 数组表达式是 的操作数&
  • 数组表达式是 的操作数sizeof
  • 数组表达式是 的操作数_Alignof
  • 数组表达式是用于初始化数组的字符串文字。

最后一个意味着 in char s[] = "abc";,"abc"不转换为指向初始元素的指针;它仍然是一个数组,用于初始化 s。

于 2012-08-20T11:22:50.930 回答
0

为了回答您的问题,根据定义,运算符*&是这样的,它们可以抵消。获取变量的地址然后取消引用会返回变量。这是一个数组,a. 在大多数情况下,数组“衰减”到指针,因此您再次看到的是第一个元素的地址。

于 2012-08-20T06:57:07.640 回答
-1

a一个指针并且a[0]*(a+0)。所以当你写的时候*(&a),你并没有取消引用它。

于 2012-08-20T06:43:31.260 回答