如何在被调用函数中获得数组的大小?

时间:2014-06-29 13:21:27

标签: c arrays pointers

由于好奇心,这只是一个自我评估的问题;所以请应付它。

我知道在C中我们通过value传递内容。在阵列的情况下,场景是不同的。我们不能通过他们的价值观传递他们,如果我们不这样做的话。将从数组类型降级为指针类型。我们需要将指针的值传递给数组的第一个元素或指向数组的指针本身。是的,这就是人们所说的array decay。因为,在传递时,数组的原始type information会丢失,除非我们通过引用传递,否则我们无法获取被调用例程中传递的数组的size信息。

查看以下代码:

#include <stdio.h>
#include <stdlib.h>

void cal(int (*b)[3]) 
{
    printf("%d",sizeof(*b));
}

int main()
{
    int a[3] = { 2,3,4 };
    cal( &a ); 
}

输出:

12                                                            

好的,我们得到了我们想要的东西。 但我得出的结论是,当您声明一个指向非变量数组的指针时,总是需要数组中的元素数量:

int a[] = { 3, 4, 5 }; // declaring an array of size 3
int (*p)[3]; // declaring a pointer to an array with length 3
p = &a ; // assignment

所以,你隐式地将数组的length传递给被调用的函数,并且总是存在一种不同的方式,通过将额外的length参数传递给在你没有传递数组引用的情况下调用函数。

PS 无论是以显式方式还是以隐式方式进行操作,您总是需要传递长度,这就像硬编码一样

是否存在其他技术,用于在被调用的函数中获取传递的数组的大小信息,或者我正在点钱? 而且,你将如何处理动态的?

3 个答案:

答案 0 :(得分:3)

  

是否存在其他技术来获取被调用函数中传递的数组的大小信息,或者我正在点钱?

是的,你可以。将一个sentinel值作为数组的最后一个元素。然后在传递的数组上使用循环来获得该函数的大小。

答案 1 :(得分:2)

通常的方法是声明第二个参数,该参数将存储声明为第一个参数的数组的大小。事实上,处理数组的所有标准C函数都声明了这种方式,除了处理被视为字符串的字符数组的函数。

答案 2 :(得分:0)

另一种技术是使用数组的第一个元素作为大小。当然,这种用法有些限制,例如,char数组只能存储从CHAR_MINCHAR_MAX的值。您也可以选择始终将值视为无符号,这意味着可以存储从0到UCHAR_MAX的任何值,这是我的首选。

使用此技术还意味着您的阵列变为基于1而不是基于0,并且您无法存储尽可能多的项目(例如,65535个元素1..65535而不是65536元素0..65535)。因此,没有元素的数组在技术上仍会占用空间:第一个用于保持长度的元素。

例如,考虑一个固定长度的字符串类型,其中第一个元素是字符串的长度。由于可能存储在第一个元素中的值的限制,您只能拥有长度为UCHAR_MAX的字符串,在我的系统上为255。如果字符串已满,则string[0]中存储的长度为255,可用元素为string[1]string[255]

如果您愿意,short int数组将包含0到USHRT_MAX元素,或者从SHRT_MINSHRT_MAX,但我仍然看不到有用的数据将其视为未签名的数量。在我的情况下,最多可以有65535个元素,它们都将被解析为arr[1]arr[2],...,arr[ arr[0] - 1 ]arr[ arr[0] ]