首先,这里有一些代码:
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
是否有一种方法可以找出ptr指向的数组的大小(而不是仅仅给出它的大小,这在32位系统上是4个字节)?
首先,这里有一些代码:
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
是否有一种方法可以找出ptr指向的数组的大小(而不是仅仅给出它的大小,这在32位系统上是4个字节)?
当前回答
没有神奇的解决办法。C不是一种反射语言。对象不会自动知道它们是什么。
但你有很多选择:
显然,要添加一个参数 将调用包装在宏中并自动添加参数 使用更复杂的对象。定义一个包含动态数组和数组大小的结构。然后,传递结构的地址。
其他回答
这就是我个人在代码中所做的。我喜欢让它尽可能简单,同时仍然能够得到我需要的值。
typedef struct intArr {
int size;
int* arr;
} intArr_t;
int main() {
intArr_t arr;
arr.size = 6;
arr.arr = (int*)malloc(sizeof(int) * arr.size);
for (size_t i = 0; i < arr.size; i++) {
arr.arr[i] = i * 10;
}
return 0;
}
有一个流行的宏,你可以定义它来查找数组中的元素数量(Microsoft CRT甚至为它提供了名为_countof的OOB):
#define countof(x) (sizeof(x)/sizeof((x)[0]))
然后你可以这样写:
int my_array[] = { ... some elements ... };
printf("%zu", countof(my_array)); // 'z' is correct type specifier for size_t
你可以这样做:
int days[] = { /*length:*/5, /*values:*/ 1,2,3,4,5 };
int *ptr = days + 1;
printf("array length: %u\n", ptr[-1]);
return 0;
正如所有正确答案所述,您不能仅从数组的衰减指针值获得此信息。如果衰减指针是函数接收到的参数,则必须以其他方式提供原始数组的大小,以便函数知道该大小。
这里有一个不同于目前所提供的建议,它可以工作:传递一个指向数组的指针。这个建议类似于c++风格的建议,除了C不支持模板或引用:
#define ARRAY_SZ 10
void foo (int (*arr)[ARRAY_SZ]) {
printf("%u\n", (unsigned)sizeof(*arr)/sizeof(**arr));
}
但是,这个建议对于您的问题来说有点愚蠢,因为函数被定义为确切地知道传入的数组的大小(因此,几乎不需要对数组使用sizeof)。不过,它所做的是提供一些类型安全性。它将禁止传入一个不需要的大小的数组。
int x[20];
int y[10];
foo(&x); /* error */
foo(&y); /* ok */
如果假定函数能够操作任意大小的数组,则必须将大小作为附加信息提供给函数。
没有神奇的解决办法。C不是一种反射语言。对象不会自动知道它们是什么。
但你有很多选择:
显然,要添加一个参数 将调用包装在宏中并自动添加参数 使用更复杂的对象。定义一个包含动态数组和数组大小的结构。然后,传递结构的地址。