C将未知大小的数组传递给单个变量中的函数

时间:2014-04-22 00:58:51

标签: c arrays function pointers

在C中,我必须将数组传递给单个变量中的函数,并且在程序运行之前不知道数组的大小。纸上解决方案是在数组中添加一个额外的元素,您将存储数组的大小(我认为这被称为" sentinel值")。好的,但是我在实现这个问题上遇到了问题。

将array []作为函数参数传递似乎不起作用。我想我可以发送指向第一个元素的指针,但是如何访问数组的其余部分呢?

3 个答案:

答案 0 :(得分:1)

在C中,数组在大多数上下文中衰减为指向其第一个元素的指针:

  

6.3.2.1左值,数组和函数指示符

     

[...]除非是 sizeof 运算符的操作数,否则 _Alignof 运算符, 或者   一元 & 运算符,或者是用于初始化数组的字符串文字,一个表达式   类型''数组类型''被转换为类型为''指向类型'的指针的表达式   到数组对象的初始元素,而不是左值。如果数组对象有   注册存储类,行为未定义。

这很有用,因为数组索引a[i]是使用指针算法定义的:*(a+i)
因此,您可以在指针上使用与数组相同的操作 但是,这种一致性还有一个缺点:如果没有将数据包装在struct中,则无法按值传递数组。

接下来,sentinel是用作停止标记的元素类型的无效值,对于字符串0和指针大多为NULL。 你实际描述的是一个计数数组,其长度前面是索引((size_t*)a)[-1]或其他一些。

答案 1 :(得分:1)

sentinel值的选择取决于阵列存储的数据类型。对于任何涉及指针的内容,请使用NULLNaN作为浮点数,例如:

char *strings[] = {"foo", "bar", "baz", NULL};
double *doubles[] = {1.0, 2.4, 6.5, NaN};

现在检查数组结束的位置等于沿着数组行走,直到找到sentinel:

size_t get_length(char **strings) {
    size_t cnt = 0;
    while (*strings++)
        cnt++;
    return cnt;
}

size_t get_length2(double **doubles) {
    ...
    while (!isnan(*doubles++))
    ...
}

对于某些数据类型(例如int),查找标记更加困难,但您可以选择常规值。

答案 2 :(得分:-1)

迭代其地址作为第一个参数传入的数组,并按照传入的数组长度检查范围作为第二个参数。

// Or, void f(int *a, int size) as the array decays
// to a pointer when passed into this function
void f(int a[], int size)
{
   // It's your own responsibility to make sure you
   // don't access the out-of-range elements.
   for (int i = 0; i < size; ++i)
   {
      printf ("%d\n", a[i]);
   }
}

// use of f()
int a[10];
// or f(&a[0], sizeof(a) / sizeof(a[0]))
f(a, sizeof(a) / sizeof(a[0]));