Skip to content

C++ 数组名与指针

以大小为16,元素类型为int的数组为例。

首先,int[16]是一种类型,我们可以使用using取个别名。这种类型至少能够反映出三种信息:类型,大小,维度。

cpp
using arr_t = int[16];

其次,下面对于数组的定义完全相同:

cpp
arr_t a = {0};		// 等同于int a[16] = {0};

a可以理解成一种变量:名字是a, 类型是int[16], 值是首地址。sizeof(a)是整个内存块的大小,&a是整个内存块的首地址,所以&a 和 a 在值上是相等的,但是类型不同。

所以数组名的的类型应该为int[16],而不是int*,这一点通过typeid可以打印出来。

cpp
std::cout << typeid(a).name() << std::endl;
std::cout << typeid(&a).name() << std::endl;
std::cout << typeid(int*).name() << std::endl;

当我们将数组名赋值给一个指针时,中间应该发生了隐式类型转换,丢失了一些信息(比如类型,大小,维度),只保留了数组的地址信息。这种现象也可以成为数组衰减为指针,这其中有历史的原因。

cpp
std::cout << sizeof(a) << std::endl;		// 16
int* b = a;
std::cout << sizeof(b) << std::endl;		// 8

同理,当我们给一个函数传递一个数组时,我们只能通过指针传递(语言本身的设计,况且函数的调用堆栈也不存储不了太大的数组),中间也发生了隐式类型转换,所以我们无法在函数内部通过指针得到数组的大小,必须增加表示数组大小的参数。

Released under the MIT License.