我在C中有一个函数(我正在使用gcc 4.8.0),它接收一个数组作为参数。有没有办法准确地确定数组中的元素数量,而不传递额外的参数array_count?
答案 0 :(得分:4)
通常无法确定作为参数传递的数组元素的数量。
当您在C中作为参数传递数组时,您只将指针传递给该数组,即指向该数组的内存区域的第一个元素(索引为0)的指针。
很多时候,程序员通常会传递该数组的大小作为另一个参数。例如,标准qsort(3)库函数作为第二个 nmemb 参数,期望要排序的数组中的元素数。
或者,您可以使用flexible array members,例如传递(在C99中,而不是在早期的C标准中)结构的地址,如
struct my_flexarray_st {
int size; // allocated size
int len; // used length, should be less than size
double arr[]; /// only len numbers are meaningful
};
无论使用何种方法,您都需要了解当参数传递时,函数已知常规数组大小。所以,请记录该惯例。你甚至可能有(坏)约定,所有数组都有一些全局变量作为它们的维度。
对于堆分配的内存区域,标准会为您malloc
,calloc
和朋友提供这样的新区域,但无法查询其分配的大小。一些C库具有非标准扩展来查询(但我不建议使用它们)。
在最近的C++11(与 C 语言不同)中,您可能会对std::vector和std::array模板容器感兴趣。
答案 1 :(得分:3)
数组在函数参数中衰减为指针,因此无法确定大小。
表达式中出现的类型为array-of-T的左值[见question 2.5]衰减(有三个例外)为指向其第一个元素的指针;结果指针的类型是指向T的指针,因为数组不是“可修改的左值”,
(例外情况是数组是sizeof或&运算符的操作数,或者是字符数组的文字字符串初始值设定项。)
答案 2 :(得分:1)
除非数组是静态的(即不是动态分配的),否则你不能使用sizeof
运算符。
答案 3 :(得分:0)
不可能。这就是为什么要么使用像链接列表这样的数据结构来实际确定长度,要么在函数中需要长度参数。 即使只有所需的长度参数,也无法知道它是真的。 因此,您的API还应该要求标准的sentinel值来终止数组。 通常这可能是NULL或其他东西,但取决于您的数组类型。
答案 4 :(得分:0)
这在C中是可行的。如果您通过sizeof在其定义的相同范围内,则可以查询数组的大小。如果你在函数范围内,将数组作为参数,则需要将参数声明为指向数组的指针(不仅仅是数组 - 在这种情况下,数组将衰减为指向第一个元素的指针),在这种情况下,数组的大小将被保存在论证传递期间:
void foo(int (*param)[3] ) { assert (sizeof(*param) == sizeof(int)*3; }
但是,如果你的意思是“数组”指向某些动态分配的内存,但在编译时大小是未知的,那么你需要单独传递大小。
答案 5 :(得分:-6)
你可以看看
function(arr[])
{
/* not this is pseduo code */
int i = 0;
while (*arr[i++] != null)
{
}
// i is number of elements
}