C++ 将数组、固定大小的数组和数组的基地址作为函数参数传递的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16144535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:06:37  来源:igfitidea点击:

Difference between passing array, fixed-sized array and base address of array as a function parameter

c++arrayspointers

提问by mr5

I am confused about which syntax to use if I want to pass an array of known or unknown size as a function parameter.

如果我想将已知或未知大小的数组作为函数参数传递,我对使用哪种语法感到困惑。

Suppose I have these variants for the purpose:

假设我有这些变体:

void func1(char* str) {
    //print str
}

void func2(char str[]) {
    //print str
}

void func3(char str[10]) {
    //print str
}

What are the pros and cons of using each one of these?

使用其中每一种的优缺点是什么?

回答by Konrad Rudolph

All these variants are the same. C just lets you use alternative spellings but even the last variant explicitly annotated with an array size decays to a normal pointer.

所有这些变体都是相同的。C 只是让您使用替代拼写,但即使是最后一个用数组大小​​显式注释的变体也会衰减为普通指针。

That is, even with the last implementation you could call the function with an array of anysize:

也就是说,即使使用最后一个实现,您也可以使用任意大小的数组调用该函数:

void func3(char str[10]) { }

func("test"); // Works.
func("let's try something longer"); // Not a single f*ck given.

Needless to say this should notbe used: it might give the user a false sense of security (“oh, this function only accepts an array of length 10 so I don't need to check the length myself”).

不用说,这应该被使用:它可能给用户一个安全的假象(“哦,这个函数只,所以我并不需要检查自己的长度长接受10的阵列”)。

As Henrik said, the correct way in C++is to use std::string, std::string&or std::string const&(depending on whether you need to modify the object, and whether you want to copy).

正如 Henrik 所说,C++ 中正确的方法是使用std::string, std::string&or std::string const&(取决于你是否需要修改对象,以及是否要复制)。

回答by Morwenn

Note that in C++, if the length of the array is known at compile time (for example if you passed a string literal), you can actually get its size:

请注意,在 C++ 中,如果数组的长度在编译时已知(例如,如果您传递了一个字符串文字),您实际上可以获得它的大小:

template<unsigned int N>
void func(const char(&str)[N])
{
    // Whatever...
}

int main()
{
    func("test"); // Works, N is 5
}

回答by Henrik

In C++, use void func4(const std::string& str).

在 C++ 中,使用void func4(const std::string& str).

回答by autistic

These are all functionally identical. When you pass an array to a function in C, the array gets implicitly converted to a pointer to the first element of the array. Hence, these three functions will print the same output (that is, the size of a pointer to char).

这些在功能上都是相同的。当您将数组传递给 C 中的函数时,该数组会隐式转换为指向数组第一个元素的指针。因此,这三个函数将打印相同的输出(即指向 的指针的大小char)。

void func1(char* str) {
    printf("sizeof str: %zu\n", sizeof str);
}

void func2(char str[]) {
    printf("sizeof str: %zu\n", sizeof str);
}

void func3(char str[10]) {
    printf("sizeof str: %zu\n", sizeof str);
}

This conversion only applies to the first dimension of an array. A char[42][13]gets converted to a char (*)[13], nota char **.

此转换仅适用于数组的第一维。Achar[42][13]被转换为 a char (*)[13]而不是a char **

void func4(char (*str_array)[13]) {
    printf("sizeof str_array: %zu\n"
           "sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}

char (*)[13]is the type of str_array. It's how you write "a pointer to an array of 13 chars". This could have also been written as void func4(char str_array[42][13]) { ... }, though the 42 is functionally meaningless as you can see by experimenting, passing arrays of different sizes into func4.

char (*)[13]是 的类型str_array。这就是你如何写“一个指向 13 chars数组的指针”。这也可以写成void func4(char str_array[42][13]) { ... },尽管 42 在功能上毫无意义,正如您通过实验将不同大小的数组传递到func4.

In C99 and C11 (but not C89 or C++), you can pass a pointer to an array of varying size into a function, by passing it's size along with it, and including the size identifier in the [square brackets]. For example:

在 C99 和 C11(但不是 C89 或 C++)中,您可以将一个指向不同大小数组的指针传递给函数,方法是将它的大小与它一起传递,并在[square brackets]. 例如:

void func5(size_t size, char (*str_array)[size]) {
    printf("sizeof str_array: %zu\n"
           "sizeof str_array[0]: %zu\n", sizeof str_array, sizeof str_array[0]);
}

This declares a pointer to an array of sizechars. Note that you must dereference the pointerbefore you can access the array. In the example above, sizeof str_array[0]evaluates to the size of the array, not the size of the first element. As an example, to access the 11th element, use (*str_array)[11]or str_array[0][11].

这声明了一个指向大小为chars的数组的指针。请注意,您必须先取消引用指针,然后才能访问数组。在上面的示例中,sizeof str_array[0]计算数组的大小,而不是第一个元素的大小。例如,要访问第 11 个元素,请使用(*str_array)[11]str_array[0][11]

回答by Whoami

To add-on, describing in points.

补充,分点描述。

1) As everyone told it is same.

1)正如每个人所说的那样。

2) Arrays are decayed into pointers when they are passed in the function arguments.

2) 数组在传入函数参数时衰减为指针。

3) Fundamental problem could be finding the size of a array in the function. For that we can use macro like.

3) 基本问题可能是在函数中找到数组的大小。为此,我们可以使用宏之类的。

   #define noOfElements(v) sizeof(v)/sizeof(0[v])

   int arr[100]
   myfunction ( arr, noOfElements(arr))

either 0[v] or v[0] can be used in the macro, where the first is used to avoid user defined data type passed in to noOfElements.

宏中可以使用 0[v] 或 v[0],其中第一个用于避免传递给 noOfElements 的用户定义数据类型。

Hope this helps.

希望这可以帮助。

回答by Rüppell's Vulture

In C, the first two definitions are equivalent.The third one is essentially same but it gives an idea about the size of the array.

在 C 中,前两个定义是等价的。第三个基本相同,但它提供了有关数组大小的概念。

If printing stris your intent, then you can safely use any of them.Essentially all three of the functions are passed a parameter of type char*,just what printf()needs to print a string.And lest you don't know, despite what it may seem, all parameter passing in C is done in pass-by-valuemode.

如果打印str是您的意图,那么您可以安全地使用它们中的任何一个。本质上,所有三个函数都传递了一个类型的参数char*,正是printf()需要打印字符串的参数。以免您不知道,不管它看起来如何,在 C 中传递的所有参数都是在pass-by-value模式下完成的。

Edit:Seems like I'll have to be very rigorous in my choice of words on SO henceforth.Well,in the third case it gives no idea about the size of the array to the functionto which it is passed as eventually it is reduced to type char*just as in the first two cases.I meant to say it kinda tells the human reading it that the array's size is 10.Also,it is not wrong/illegal in C.But for the program,doing it is as good as useless.It gives no idea whatsoever about the array size to the function it is passed to.Mr.Downvoter, thanks for pointing out that casual attitude and negligence is not tolerated on SO.

编辑:从今往后,似乎我必须非常严格地选择 SO 上的单词。好吧,在第三种情况下,它不知道传递给它的函数的数组大小,因为它最终会减少以类型char*,就像前两个意思办案。要说它有点讲述人读它,数组的大小是10.Also,这是没有错/非法的C.But的程序,这样做是一样好没用。它不知道传递给它的函数的数组大小。Downvoter 先生,感谢您指出在 SO 上不能容忍随意的态度和疏忽。

回答by user2301717

In a one dimensional array they are all treated the same by the compiler. However for a two or more dimensional array, (e.g. myArray[10][10]), it is useful as it can be used to determine the row/column length of an array.

在一个一维数组中,它们都被编译器同等对待。然而,对于二维或多维数组(例如myArray[10][10]),它很有用,因为它可用于确定数组的行/列长度。