可变长度数组的原型

时间:2011-08-29 01:50:40

标签: c arrays variable-length-array

我正在尝试编写一个在c中采用可变大小数组的函数。

void sort(int s, int e, int arr[*]){
    ...
}

它表示对于可变长度数组,它需要在函数声明中有界。那是什么意思?我正在使用xcode 4.0,使用LLVM编译器2.0。

感谢您的帮助。

4 个答案:

答案 0 :(得分:23)

我看到没有人回答真正的问题,我在这里给出了我的意见。

在C99中,您有可变长度数组(VLA),它们的声明长度在运行时进行评估,而且不仅在编译时与C的早期版本一样。但是将数组传递给函数有点棘手。 / p>

一维数组总是作为指针传递,所以

void sort(size_t n, int arr[n]) {

}

相当于

void sort(size_t n, int *arr){

}

更高的维度很好地传递给函数

void toto(size_t n, size_t m, int arr[n][m]){

}

相当于

void toto(size_t n, size_t m, int (*arr)[m]){

}

在这样的函数内部使用这样的定义,您可以访问表达式为arr[i][j]的元素,并且编译器知道如何计算正确的元素。

现在出现了你发现的语法,它只对 prototypes 有用,这是你向前声明函数接口的地方

void toto(size_t, size_t, int arr[*][*]);

所以在这里你可以用*替换数组维度作为占位符。但是,只有当您没有手头的尺寸名称时,这才有用,并且使用与定义完全相同的版本更为清晰。

void toto(size_t n, size_t m, int arr[n][m]);

一般情况下,为了一致使用,您必须首先在参数列表中使用尺寸。否则,当编译器解析arr的声明时,就不会知道它们。

答案 1 :(得分:2)

你想做什么让你的论点成为int *;传递数组的长度(调用者可能知道,但这个例程没有)作为一个单独的参数。您可以将数组作为参数传递。

答案 2 :(得分:2)

如果您没有使用C99可变长度数组,通常的解决方案是传入指向第一个元素的指针,以及要用于访问元素的任何索引。

这是一段打印出一系列数组的代码,类似于您尝试对sort执行的操作。

#include <stdio.h>

static void fn (int *arr, size_t start, size_t end) {
    size_t idx;
    for (idx = start; idx <= end; idx++) {
        printf ("%d ", arr[idx]);
    }
    putchar ('\n');
}

int main (void) {
    int my_array[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
    fn (my_array, 4, 6);
    return 0;
}

这将输出4到6个元素(从零开始),给出:

5 4 3

需要注意的几点。

  • my_array函数中使用fn自动“衰减”数组到指向其第一个元素的指针。当您使用数组时,这实际上发生在大多数(并非所有)情况下,因此您不必明确声明&(my_array[0])

  • C已经 一个内置于标准库的非常好的排序函数,称为qsort。在许多情况下,这就是你应该使用的东西(除非你有一个特定的算法要用于排序,或者你正在做家庭作业/自学教育)。

答案 3 :(得分:1)

可变长度数组的数组括号内*的用法仅限于原型,仅用作占位符。稍后定义函数时,数组的大小应存储在文件范围内可用的变量中或作为参数之一。这是一个简单的例子:

void foo(int, int[*]);
/* asterisk is placeholder */

void foo(int size, int array[size]) {
/* note size of array is specified now */
}