当一个函数具有一个特定大小的数组参数时,为什么它被一个指针replace?

鉴于以下scheme,

#include <iostream> using namespace std; void foo( char a[100] ) { cout << "foo() " << sizeof( a ) << endl; } int main() { char bar[100] = { 0 }; cout << "main() " << sizeof( bar ) << endl; foo( bar ); return 0; } 

输出

 main() 100 foo() 4 
  1. 为什么数组作为指针传递给第一个元素?
  2. 这是C的遗产吗?
  3. 标准说什么?
  4. 为什么C ++的严格types安全性下降?

是的,它是从Cinheritance的。function:

 void foo ( char a[100] ); 

将参数调整为一个指针,因此变成:

 void foo ( char * a ); 

如果你想保存数组types,你应该传入一个对数组的引用:

 void foo ( char (&a)[100] ); 

C ++ '03 8.3.5 / 3:

…函数的types是使用以下规则确定的。 每个参数的types由它自己的decl-specifier-seq和声明符决定。 在确定每个参数的types之后,分别将types“T的数组”或“返回的函数”的参数分别调整为“指向T的指针”或“返回T的函数的指针”。

解释语法:

在谷歌检查“左 – 右”的规则; 我在这里find了一个描述。

它将被应用于这个例子大致如下:

 void foo (char (&a)[100]); 

从标识符“a”开始

'a'是一个

向右移动 – 我们finda )所以我们反转方向寻找( 。当我们向左移动时&

'a'是一个参考

我们到达开幕后(所以我们再次反转,看起来是正确的,我们现在看到[100]

'a'是对100个数组的引用

我们再次反转方向直到达到char

'a'是对100个字符数组的引用

是。 在C和C ++中,你不能将数组传递给函数。 就是这样。

为什么你要做简单的数组呢? 你看过boost / std::tr1::array / std::array或者std::vector吗?

请注意,但是,可以将对任意长度数组的引用传递给函数模板 。 closures我的头顶上:

 template< std::size_t N > void f(char (&arr)[N]) { std::cout << sizeof(arr) << '\n'; } 

C / C ++术语中有一个macros伟的词,用于静态数组和函数指针 – 衰减 。 考虑下面的代码:

 int intArray[] = {1, 3, 5, 7, 11}; // static array of 5 ints //... void f(int a[]) { // ... } // ... f(intArray); // only pointer to the first array element is passed int length = sizeof intArray/sizeof(int); // calculate intArray elements quantity (equals 5) int ptrToIntSize = sizeof(*intArray); // calculate int * size on your system