试图理解数组名称的含义

trying to understand what does the name of an array mean

我写了这个简单的程序

 #include <iostream>

 using namespace std;

 int main (){
     int arr [5] = {1,2,3,4,5};

     cout<<arr<<endl; //Line 1
     cout<<&arr<<endl; //Line 2

     cout<<sizeof(arr)<<endl; //Line 3
     cout<<sizeof(&arr)<<endl; //Line 4
 }

我的预期是:

但是在第 3 行中:我得到 20 个字节 (sizof(int)* 整数数量)

Line2怎么来的:arr相当于指针,Line3相当于数组

我知道数组不是指针,但是当传递给函数时它会衰减为指针,sizeof(..) 是一个运算符,因此它将 arr 视为数组,但是<<也是,它是运算符而不是函数

I know that an array is not a pointer, but when passed to a function it decays to a pointer, sizeof(..) is an operator, and hence it treats arr as an array

没错。因此你在第 2 行得到了 20 个字节。

but so is <<, it is an operator not a function

事实上,当 << 与除 built-in 整数类型之外的任何东西一起使用时,它是一个 user-defined 函数(请参阅运算符重载)。所以它按预期工作。

要理解 Line2,您确实需要理解数组和指针之间的区别。首先,当你声明一个数组时,你声明了数组持有的类型 (int),然后你保留了组成数组的多个 (int) 大小的字节。毫无疑问,数组是完整的数组结构。

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

如果您想计算出当前机器上 int 的大小(以字节为单位),您可以像在第 4 行中那样询问数组中单个元素的大小。

sizeof &arr
// this is equivalent to ...
sizeof &arr[0]
// you could also ask for just ...
sizeof arr[0]

这些都是 return 你的 4 个字节(你机器上 int 的大小)。

明白一个arr本身是没有地址的。想想当你将一个数组传递给一个函数时,你只是传递了第一个元素的地址。因此这两个函数声明完全相同:

int foo(char *arr);
int foo(char arr[]);

因此,当您在第 3 行中询问数组的大小时,您是在询问整个数组的大小。 (5*4 字节) = 20 字节

另外一个非常重要的理解是,当你将一个数组传递给一个函数时,你传递的只是数组中第一个元素的地址。所以如果你创建了一个函数:

int array_size(char arr[]) { return sizeof arr; }

int main() {
    int foo[5] = { 1, 2, 3, 4, 5 };
    std::cout << "Foo size: " << array_size(foo) << std::endl;
    std::cout << "Foo size: " << sizeof foo << std::endl;
    return 0;
}

结果:

Foo size: 4
Foo size: 20