当一个函数有一个特定大小的数组参数时,为什么要用指针替换它?

根据以下程序,

#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 + + 的严格类型安全性被放弃了?
37210 次浏览

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

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

但是请注意,您可以将对任意长度数组的引用传递给函数 模板。我第一时间想到的是:

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

是的,它继承自 C 函数:

void foo ( char a[100] );

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

void foo ( char * a );

如果希望保留数组类型,则应传入对该数组的引用:

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

C + +’038.3.5/3:

... 函数的类型是使用以下规则确定的。每个参数的类型由其自己的 decl-specfier-seq 和声明程序确定。在确定每个参数的类型之后,任何类型为“ T 的数组”或“函数返回 T”的参数分别被调整为“指向 T 的指针”或“指向函数返回 T 的指针”..。

解释句法:

检查“右-左”规则在谷歌; 我发现它的一个描述 给你

这个例子大致适用如下:

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

从标识符‘ a’开始

A 是 a

向右移动-我们找到一个 ),所以我们反方向寻找 (。当我们向左移动,我们通过 &

“ a”是个参照物

&之后,我们到达了开始的 (,所以我们再次倒车向右看。我们现在看到的是 [100]

‘ a’是对100的数组的引用

然后我们再次调转方向,直到到达 char:

“ a”是对一个包含100个字符的数组的引用

用于静态数组和函数指针的 C/C + + 术语中有一个华丽的词汇—— 腐烂。 考虑以下代码:

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