首先,这里有一些代码:

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++风格的建议,除了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 */

如果假定函数能够操作任意大小的数组,则必须将大小作为附加信息提供给函数。

其他回答

不,你不能使用sizeof(ptr)来找到ptr所指向的数组的大小。

尽管分配额外的内存(大于数组的大小)会有帮助,如果你想在额外的空间存储长度。

对于这个特定的例子,是的,如果你使用typedefs(见下面)。当然,如果您这样做,您也可以使用SIZEOF_DAYS,因为您知道指针指向什么。

如果你有一个(void *)指针,就像malloc()之类返回的那样,那么,没有办法确定指针指向什么数据结构,因此,也没有办法确定它的大小。

#include <stdio.h>

#define NUM_DAYS 5
typedef int days_t[ NUM_DAYS ];
#define SIZEOF_DAYS ( sizeof( days_t ) )

int main() {
    days_t  days;
    days_t *ptr = &days; 

    printf( "SIZEOF_DAYS:  %u\n", SIZEOF_DAYS  );
    printf( "sizeof(days): %u\n", sizeof(days) );
    printf( "sizeof(*ptr): %u\n", sizeof(*ptr) );
    printf( "sizeof(ptr):  %u\n", sizeof(ptr)  );

    return 0;
} 

输出:

SIZEOF_DAYS:  20
sizeof(days): 20
sizeof(*ptr): 20
sizeof(ptr):  4

正如所有正确答案所述,您不能仅从数组的衰减指针值获得此信息。如果衰减指针是函数接收到的参数,则必须以其他方式提供原始数组的大小,以便函数知道该大小。

这里有一个不同于目前所提供的建议,它可以工作:传递一个指向数组的指针。这个建议类似于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 */

如果假定函数能够操作任意大小的数组,则必须将大小作为附加信息提供给函数。

你可以这样做:

int days[] = { /*length:*/5, /*values:*/ 1,2,3,4,5 };
int *ptr = days + 1;
printf("array length: %u\n", ptr[-1]);
return 0;
 #define array_size 10

 struct {
     int16 size;
     int16 array[array_size];
     int16 property1[(array_size/16)+1]
     int16 property2[(array_size/16)+1]
 } array1 = {array_size, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

 #undef array_size

Array_size传递给size变量:

#define array_size 30

struct {
    int16 size;
    int16 array[array_size];
    int16 property1[(array_size/16)+1]
    int16 property2[(array_size/16)+1]
} array2 = {array_size};

#undef array_size

用法是:

void main() {

    int16 size = array1.size;
    for (int i=0; i!=size; i++) {

        array1.array[i] *= 2;
    }
}