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