数组和指针不相同。在您的情况下,变量是 指针,而不是数组。即使它们不相同,混淆也很常见,您会在许多地方(包括 C/C++ 书籍)发现它们是相同的。这意味着您应该熟悉调用指针数组的人。
在开发 C 语言时,他们决定不通过值传递数组(可能需要大量的复制和堆栈内存),而是将数组静默转换为指向第一个元素的指针,然后将该指针传递给功能。
void f( int a[3] ); // valid and misleading
// what it means:
// void f( int *a);
void test() {
int array[3];
f( array );
// what it means:
// f( & array[0] )
}
为了向后兼容,C++ 保留了该功能,您不能按值传递数组,也不能定义按值获取数组的函数(在这两种情况下,它将被默默地转换为指向第一个元素的指针)。同时,可以在指针上使用数组访问语法来简化指针运算,使其更加混乱:
int array[3];
int *pointer = array; // simplified:
// int * pointer = & array[0]
pointer[2]; // equivalent to *(pointer+2) or array[2]
这意味着 C 和 C++ 数组中的常规函数都会默默地衰减为指针,大多数人会认为它们是同一事物:数组是指向第一个元素的指针。好吧,他们不是。
在 C 和 C++ 中它们是不同的实体,即使某些使用模式由于该设计决策而等效。但实际上它们是不同的:
int array[3]; sizeof(array); // 3*sizeof(int)
int *p1=array; // sizeof(int*), usually 4/8 bytes for 32/64 bit
int *p2=new int[3]; // sizeof(int*)
经过一个函数/方法调用后,都是指针:
void f( int array[3] ) { sizeof(array); } // sizeof(int*) it is really a pointer! size is ignored
void g( int *p ) { sizeof(array); } // sizeof(int*)
在 C++ 中,事情变得更加有趣,因为 pass-by-value 不是唯一可用的范例,您可以通过引用传递:
void f( int (&array)[3] ); // funny syntax to pass an array of 3 integers by reference
void testf() {
int array1[3]; f(array1); // correct
int array2[2]; // f(array2); compilation error, it is not an array of 3 ints!
int *p = array1; // f(p); compilation error, it is not an array of 3 ints!
}
void g( int array[3] ); // means: void g( int *array );
void testg() {
int array1[3]; g(array1); // correct, the array decays into & array[0]
int array2[2]; g(array2); // correct, the array decays again
int *p = array1; g( p ); // correct it is a pointer
}
请注意,当您定义一个按值获取 array 的函数时,您实际上是在定义一个按值获取指针的函数,并且编译器不会检查函数调用的参数是否实际有那个大小。这是一个已知的错误来源,也是大多数采用数组的函数也采用大小参数的原因。
最后,你不能动态创建数组,你只能动态获取内存到指针中,所以当你需要一个堆分配的数组你实际上需要一个指向堆分配的连续块的指针o记忆:
void test() {
int *p = new int[3];
// int array[3] = new int[3]; // error!! an array is not a pointer
delete p;
}
最后这一切都意味着它们不是同一个东西,但是你总是可以使用数组来代替指针,它会被编译器自动转换为指向数组第一个元素的指针.通常,人们会将指向连续内存块(无论是堆栈还是堆分配)的指针称为 array。