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

问题描述 投票:0回答:3

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

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

c arrays function pointers
3个回答
2
投票

在 C 语言中,在大多数情况下,数组会衰减为指向其第一个元素的指针:

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

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

这很有用,因为数组索引

a[i]
是使用指针算术定义的:
*(a+i)

因此,您可以对指针使用与对数组相同的操作。
不过,这种一致性有一个缺点:如果不将数组包装在
struct
中,则无法按值传递数组。

接下来,

sentinel
是用作停止标记的元素类型的无效值,例如对于字符串0和指针大多是
NULL

您实际上描述的是一个计数数组,其长度前缀在索引
((size_t*)a)[-1]
或类似位置。


2
投票

哨兵值的选择取决于数组存储的数据类型。对于涉及指针的任何内容,请使用

NULL
,对于浮点数使用
NAN
,例如:

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

现在检查数组的结束位置相当于沿着数组行走,直到找到哨兵:

#include <stddef.h>  // for NULL
#include <math.h>    // for NAN and isnan(…)

size_t count_strings(char** strings) {
    size_t num_strings = 0;
    while ((*strings)++ != NULL) {
        num_strings++;
    }
    return num_strings;
}

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

对于某些数据类型(例如,

int
),查找哨兵更为困难,但您可以选择一个常规值。


-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]));
© www.soinside.com 2019 - 2024. All rights reserved.