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

发布于 2024-08-02 15:23:16 字数 483 浏览 9 评论 0原文

给定以下程序,

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

Given the following program,

#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;
}

outputs

main() 100
foo() 4
  1. Why is the array passed as a pointer to the first element?
  2. Is it a heritage from C?
  3. What does the standard say?
  4. Why is the strict type-safety of C++ dropped?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

何止钟意 2024-08-09 15:23:16

是的,它是从 C 继承的。函数:

void foo ( char a[100] );

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

void foo ( char * a );

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

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

C++ '03 8.3 .5/3:

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

To解释一下语法:

检查google中的“从右到左”规则;我在此处找到了它的描述。

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

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

从标识符“a”开始

“a”是一个

向右移动 - 我们找到 ),因此我们反向寻找 (。当我们向左移动时,我们通过 &

“a”是引用

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

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

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

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

Yes it's inherited from C. The function:

void foo ( char a[100] );

Will have the parameter adjusted to be a pointer, and so becomes:

void foo ( char * a );

If you want that the array type is preserved, you should pass in a reference to the array:

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

C++ '03 8.3.5/3:

...The type of a function is determined using the following rules. The type of each parameter is determined from its own decl-specifier-seq and declarator. After determining the type of each parameter, any parameter of type "array of T" or "function returning T" is adjusted to be "pointer to T" or "pointer to function returning T," respectively....

To explain the syntax:

Check for "right-left" rule in google; I found one description of it here.

It would be applied to this example approximately as follows:

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

Start at identifier 'a'

'a' is a

Move right - we find a ) so we reverse direction looking for the (. As we move left we pass &

'a' is a reference

After the & we reach the opening ( so we reverse again and look right. We now see [100]

'a' is a reference to an array of 100

And we reverse direction again until we reach char:

'a' is a reference to an array of 100 chars

蓝眼睛不忧郁 2024-08-09 15:23: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';
}

Yes. In C and C++ you cannot pass arrays to functions. That's just the way it is.

Why are you doing plain arrays anyway? Have you looked at boost/std::tr1::array/std::array or std::vector?

Note that you can, however, pass a reference to an array of arbitrary length to a function template. Off the top of my head:

template< std::size_t N >
void f(char (&arr)[N])
{
  std::cout << sizeof(arr) << '\n';
}
云雾 2024-08-09 15:23:16

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

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

There is magnificent word in C/C++ terminology that is used for static arrays and function pointers - decay.
Consider the following code:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文