如何检测作为参数传递的数组的大小?

时间:2013-04-08 16:00:25

标签: c arrays pointers

我知道如何在我通过sizeof paramater创建它后检测数组的大小:

int arr[10];
printf("%i",sizeof(arr)/sizeof(int));

但据我所知,当我将一个数组作为参数传递给一个函数时,我实际上将一个指针传递给数组的第一个元素,而不是实际的数组。因此,如果我将使用sizeof运算符,我将获得指针的大小。

我知道我可以通过搜索'\ 0'找到字符串(char数组)的大小。所以我们假设我们正在谈论int数组;

如何检测作为参数传递的数组的大小?

7 个答案:

答案 0 :(得分:3)

像往常一样,当问到这个问题时,会出现大量的答案,说你必须将元素的数量作为参数传递给函数。

这当然是不正确的。如果函数需要知道数组中元素的数量,则必须向函数提供信息,但可以通过多种方式提供。这最简单的是通过一个参数,但它可能是零个或多个参数的任意组合,全局状态,由参数或全局状态直接或间接指向的信息,从先前函数调用中记住的静态信息,数组本身的某些质量(例如哨兵,编译时常数或几乎任何其他可以想象的方法,这些数字可能明确地存在于任何上述内容中,也可能是从信息中计算或推断出来的。

关于无法获取数组中元素数量的唯一方法是通过应用于传递指针的标准C机制。

答案 1 :(得分:1)

您不能,您必须将尺寸作为附加参数发送到该功能。

答案 2 :(得分:1)

你做不到。在C中,当你将一个数组传递给函数时,它从一个数组decays到一个指向类型的指针,就函数的范围而言。

所以,请考虑一下:

int arr[16];
sizeof(arr);          // sizeof WORKS
myFunction(arr);      // Array decays to pointer, sizeof FAILS inside function
myFunction(&arr[0]);  // Array decays to pointer, sizeof FAILS inside function

void myFunction(int* ptr)
{
  // sizeof(ptr) will not give you what you would expect normally
}

在C中执行此操作的传统方法是使用额外的函数参数,即:

void myFunction(int* ptr, size_t mySize)
{
}

或者,创建自己的结构,该结构包含指向数组的指针及其大小,即:

typedef struct myType {
  int*   ptrToArray;
  size_t arraySize;
} myType_t;

int array[16] = { 0 };
myType_t data;
data.ptrToArray = array;
data.arraySize = 16;

void myFunction(myType_t data)
{
}

答案 3 :(得分:0)

通过null终止数组,或通过传入元素的数量。没有办法告诉C中数组中包含多少元素。

答案 4 :(得分:0)

您需要将它作为参数传递给函数。或者您需要将要传递的数组的大小声明为固定...

void myFunc( int* array, size_t numElements );

或者如果数组的大小是已知常数

void myFunc( int array[10] );

或任何其他无数种方法使数组的大小可用于函数(全局等)。它不是C的内置函数,通过其指针检测数组的大小。

答案 5 :(得分:0)

您可以NULL终止数组并循环每次递增一个变量,直到它达到NULL这将为您提供大小。

int arr[10] = {1, 2, 3, 4, 5, NULL}

或类似的东西。在您的情况下,您可能需要将NULL写入当前索引+1。其他选项(如创建保持大小的struct可能会更好,因为它们的成本更低。

答案 6 :(得分:0)

与您所期望的相反,以下程序退出代码1(也是@K Scott Piel)

int f(int a[10])
{
        return sizeof(a)/sizeof(int);
}

int main(void)
{
        int     a[10];
        return f(a);
}

这确实和其他人提到的一样:因为C中的参数数组只是一个指针。你可以检查你的编译器,也许它有扩展来绕过它,但它会使你的代码不可移植。

解决问题的方法是将数组包装在struct内。以下程序确实以代码10退出。

typedef struct { int a[10]; } a10;
int f(a10 a)
{
        return sizeof(a)/sizeof(int);
}

int main(void)
{
        a10     a;
        return f(a);
}
但是,要获得这些元素会更麻烦。如果你想支持不同大小的数组,你必须自己编程(正如其他人指出的那样)。请注意,sizeof是在编译时计算的,就编译器而言是一个常量。它只能因平台而异。

哦,请注意第二个示例中的数组是按值传递的,而第一个中的数组是通过引用传递的。