传递数组,固定大小数组和基地址数组之间的差异作为函数参数
如果我想传递一个已知或未知大小的数组作为函数参数,我很困惑要使用哪种语法。
假设我有这些变种的目的:
void func1(char* str) { //print str } void func2(char str[]) { //print str } void func3(char str[10]) { //print str }
使用其中每一个的优点和缺点是什么?
所有这些变体是相同的。 C只是让你使用替代拼写,但即使最后一个数组大小明确注释衰减到一个正常的指针。
也就是说,即使在最后一个实现中,您也可以使用任何大小的数组调用该函数:
void func3(char str[10]) { } func("test"); // Works. func("let's try something longer"); // Not a single f*ck given.
不用说,这不应该使用:它可能会给用户一种错误的安全感(“哦,这个函数只接受长度为10的数组,所以我不需要自己检查长度”)。
正如Henrik所说, C ++中的正确方法是使用std::string
, std::string&
或std::string const&
(取决于是否需要修改对象以及是否要复制)。
请注意,在C ++中,如果数组的长度在编译时已知(例如,如果您传递了string文字),则实际上可以获得其大小:
template<unsigned int N> void func(const char(&str)[N]) { // Whatever... } int main() { func("test"); // Works, N is 5 }
在C ++中,使用void func4(const std::string& str)
。
这些都是function相同的。 当您将数组传递给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); }
此转换仅适用于数组的第一维。 char[42][13]
被转换为char (*)[13]
, 而不是 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]
是str_array
的types。 这就是你如何写“一个指向13个char
数组的指针”。 这也可以被写成void func4(char str_array[42][13]) { ... }
,尽pipe42在function上没有意义,正如你可以通过实验看到的,将不同大小的数组传递给func4
。
在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]); }
这声明了一个指向char
数组的指针。 请注意,在访问数组之前,您必须取消引用指针 。 在上面的例子中, sizeof str_array[0]
值是数组的大小,而不是第一个元素的大小。 例如,要访问第11个元素,请使用(*str_array)[11]
或str_array[0][11]
。
在一维数组中,编译器对它们全部进行处理。 但是对于一个两维或更多维的数组(例如myArray[10][10]
),它可以用来确定数组的行/列长度。
要添加,以点描述。
1)大家都说它是一样的。
2)在函数参数中传递数组时,数组会被腐蚀成指针。
3)基本的问题可能是在函数中查找数组的大小。 为此,我们可以使用macros像。
#define noOfElements(v) sizeof(v)/sizeof(0[v]) int arr[100] myfunction ( arr, noOfElements(arr))
macros中可以使用0 [v]或v [0],其中第一个用于避免将用户定义的数据types传递给noOfElements。
希望这可以帮助。
在C中,前两个定义是等价的。第三个定义本质上是一样的,但是它给出了数组大小的一个概念。
如果打印str
是你的意图,那么你可以安全地使用它们中的任何一个。实质上,所有这三个函数都传递一个char*
types的参数,只是printf()
需要打印一个string。为了避免你不知道,尽pipe可能看起来,所有传入C的参数都是pass-by-value
模式完成的。
编辑:似乎我将必须非常严格的select在SO以后的话。第三种情况下,它不知道数组的大小,因为它最终减less了传递的函数就像在前两种情况下inputchar*
一样。我的意思是说,它告诉人们阅读它,数组的大小是10.另外,在C中没有错误/非法。但是对于程序来说,好的没用。对于数组的大小和它传递给它的函数一点关系都不知道。先生,感谢您指出,在SO上偶然的态度和疏忽是不能容忍的。