Gre*_*own 6 c arrays variable-length-array
我正在尝试编写一个在c中采用可变大小数组的函数.
void sort(int s, int e, int arr[*]){
...
}
Run Code Online (Sandbox Code Playgroud)
它表示对于可变长度数组,它需要在函数声明中有界.那是什么意思?我正在使用xcode 4.0,使用LLVM编译器2.0.
谢谢您的帮助.
Jen*_*edt 24
我看到没有人回答真正的问题,我在这里给我的.
在C99中,您有可变长度数组(VLA),它们的声明长度在运行时进行评估,而且不仅在编译时与C的早期版本一样.但是将数组传递给函数有点棘手.
一维数组总是作为指针传递
void sort(size_t n, int arr[n]) {
}
Run Code Online (Sandbox Code Playgroud)
相当于
void sort(size_t n, int *arr){
}
Run Code Online (Sandbox Code Playgroud)
更高的尺寸很好地传递给了该功能
void toto(size_t n, size_t m, int arr[n][m]){
}
Run Code Online (Sandbox Code Playgroud)
相当于
void toto(size_t n, size_t m, int (*arr)[m]){
}
Run Code Online (Sandbox Code Playgroud)
在这样的函数内部使用这样的定义,您可以使用表达式访问元素,arr[i][j]并且编译器知道如何计算正确的元素.
现在出现了您发现的语法,它只对原型有用,这些原型是您向前声明函数接口的位置
void toto(size_t, size_t, int arr[*][*]);
Run Code Online (Sandbox Code Playgroud)
所以在这里你可以用*占位符替换数组维度.但是,只有当您没有手头的尺寸名称时,这才有用,并且使用与定义完全相同的版本更为清晰.
void toto(size_t n, size_t m, int arr[n][m]);
Run Code Online (Sandbox Code Playgroud)
通常,为了一致地使用它,在参数列表中首先获得尺寸是很重要的.否则,当编译器解析声明时,它们将不会被知道arr.
如果您没有使用C99 可变长度数组(看起来您是这样,所以请参见下文),通常的解决方案是传递一个指向第一个元素的指针,以及您想要用于访问元素的任何索引。
\n这是一段打印出数组范围的代码,类似于您尝试对sort.
#include <stdio.h>\n\nstatic void fn (int *arr, size_t start, size_t end) {\n size_t idx;\n for (idx = start; idx <= end; idx++) {\n printf ("%d ", arr[idx]);\n }\n putchar (\'\\n\');\n}\n\nint main (void) {\n int my_array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};\n fn (my_array, 4, 6);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n这输出元素四到六(从零开始),给出:
\n5 4 3\nRun Code Online (Sandbox Code Playgroud)\n有几点需要注意。
\n在该函数调用中使用自动my_array将fn数组“衰减”为指向其第一个元素的指针。当您使用数组时,这实际上在大多数(不是全部)情况下都会发生,因此您不必显式声明&(my_array[0]).
C 已经在标准库中内置了一个非常好的排序函数,称为qsort. 在许多情况下,这就是您应该使用的(除非您有想要用于排序的特定算法,或者您正在做家庭作业/自学练习)。
如果您使用真正的 VLA,您应该注意该[*]构造仅在函数原型中有效,而在函数的实际定义中无效。
所以,同时:
\n#include <stdio.h>\n\nstatic void fn (int *arr, size_t start, size_t end) {\n size_t idx;\n for (idx = start; idx <= end; idx++) {\n printf ("%d ", arr[idx]);\n }\n putchar (\'\\n\');\n}\n\nint main (void) {\n int my_array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};\n fn (my_array, 4, 6);\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n有效,但以下内容无效:
\n5 4 3\nRun Code Online (Sandbox Code Playgroud)\n这是因为,虽然您在原型中不需要大小参数,但在定义中却非常需要它。而且,既然你有了它,你就应该使用它:
\nvoid xyzzy(int, int[*]);\nRun Code Online (Sandbox Code Playgroud)\n编译gcc器实际上对此有一个相当清晰的错误消息,比您看到的“需要在函数声明中受到限制”要好得多:
\n\n错误:\xe2\x80\x98[*]\xe2\x80\x99 不允许在函数原型范围以外的地方使用
\n