71

鉴于以下程序,

#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++ 的严格类型安全?
4

3 回答 3

89

是的,它是从 C 继承的。功能:

void foo ( char a[100] );

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

void foo ( char * a );

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

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

C++ '03 8.3.5/3:

...函数的类型使用以下规则确定。每个参数的类型由它自己的 decl-specifier-seq 和 declarator 确定。确定每个参数的类型后,将“T的数组”或“返回T的函数”类型的任何参数分别调整为“指向T的指针”或“指向返回T的函数的指针”......

解释语法:

检查谷歌中的“左右”规则;我在这里找到了它的一个描述。

它将大致应用于此示例,如下所示:

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

从标识符“a”开始

'a' 是一个

向右移动 - 我们找到 a)所以我们反转方向寻找(。当我们向左移动时,我们经过&

'a' 是参考

&我们到达开口之后,(我们再次反转并向右看。我们现在看到[100]

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

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

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

于 2009-08-25T13:22:38.113 回答
16

是的。在 C 和 C++ 中,您不能将数组传递给函数。就是那样子。

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

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

template< std::size_t N >
void f(char (&arr)[N])
{
  std::cout << sizeof(arr) << '\n';
}
于 2009-08-25T13:22:13.947 回答
1

用于静态数组和函数指针的 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
于 2011-12-21T16:53:07.673 回答