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

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

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

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

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

[…]除非它是sizeof运算符, _Alignof运算符或一元运算符的操作数,或者是用于初始化数组的字符串文字,否则类型为”数组’类型的表达式是转换为类型为”指向类型’的指针的表达式,指向数组对象的初始元素,而不是左值。 如果数组对象具有寄存器存储类,则行为未定义。

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

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

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

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

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

 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 ),查找标记更加困难,但您可以选择常规值。

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

 // 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]));