为什么在单个变量上我需要在数组上指定内存地址我不需要它?

时间:2016-04-05 19:25:03

标签: c++ arrays pointers declaration memory-address

简单example

double array[] = {1000.0, 2.0, 3.4, 17.0, 50.0};
double *p1 = array;
printf("p1: %f\n", *(p1));

int x = 2;
int* p2 = &x;
printf("p2: %d\n", *p2);

为什么在p1上我需要使用&在数组上我不需要在c / c ++中使用它?有逻辑原因吗?

4 个答案:

答案 0 :(得分:1)

表达式中的数组指示符(很少例外)转换为指向其第一个元素的指针。

来自C标准(6.3.2.1 Lvalues,数组和函数指示符)

  

3除非它是sizeof运算符或一元&的操作数。   operator,或者是用于初始化数组的字符串文字,a   具有类型''数组类型''的表达式将转换为   带有''指向类型'的指针的表达式,指向初始值   数组对象的元素,而不是左值。如果是数组对象   具有寄存器存储类,行为未定义。

从C ++标准(4.2阵列到指针的转换)

  

1“N T数组”或“未知数组”的左值或右值   T“的绑定可以转换为”指向T“的类型的prvalue。该   result是指向数组第一个元素的指针。

因此这个宣言

double *p1 = array;

相当于

double *p1 = &array[0];
            ^^^

考虑这个示范程序

$include <iostream>

int main()
{
    double array[] = { 1000.0, 2.0, 3.4, 17.0, 50.0 };

    std::cout << "sizeof( array ) = " << sizeof( array ) << std::endl;
    std::cout << "sizeof( array + 0 ) = " << sizeof( array + 0 ) << std::endl;
}    

程序输出

sizeof( array ) = 40
sizeof( array + 0 ) = 8

在第一个输出语句中,数组指示符用作sizeof运算符的操作数。因此,类型double[5]double *没有转化。

在第二个输出语句中,数组指示符用在表达式array + 0中,而表达式sizeof又用作double[5]运算符的操作数。 在这种情况下,存在从类型double *到类型{{1}}的转换。

答案 1 :(得分:1)

您可以认为数组求值为'address'类型的变量,而x是int类型的变量。 x存储在存储器位置,&amp; x为您提供该存储器位置的地址。

数组的地址,即&amp;数组将计算为第一个元素的地址,从而计算出数组本身的地址。

答案 2 :(得分:0)

根据Bjarne Stroustrup的书 - Programming: Principles and Practice Using C++数组的名称指的是数组的所有元素,例如:

char ar[10];
sizeof(ar) // 10
  

但是,数组的名称会变成(“衰减到”)指针   最轻微的借口。

这就是为什么我们可以拥有:char* c = ar。现在c被初始化为&c[0](这是数组的第一个元素),使得sizeof(c) 4(取决于实现。

至于变量,它只是一个元素。

答案 3 :(得分:0)

因为数组衰减到它的声明类型的指针,该指针指向数组所包含的第一个元素。