1

声明 const 表时,可以使用 sizeof 获取表的大小。但是,一旦您停止使用符号名称,它就不再起作用了。有没有办法让以下程序为表 A 输出正确的大小,而不是 0 ?

#include <stdio.h>

struct mystruct {
    int a;
    short b;
};

const struct mystruct tableA[] ={
    { 
        .a = 1,
        .b = 2,
    },
    { 
        .a = 2,
        .b = 2,
    },
    { 
        .a = 3,
        .b = 2,
    },
};

const struct mystruct tableB[] ={
    { 
        .a = 1,
        .b = 2,
    },
    { 
        .a = 2,
        .b = 2,
    },
};


int main(int argc, char * argv[]) {
    int tbl_sz;
    const struct mystruct * table;

    table = tableA;
    tbl_sz = sizeof(table)/sizeof(struct mystruct);
    printf("size of table A : %d\n", tbl_sz);

    table = tableB;
    tbl_sz = sizeof(tableB)/sizeof(struct mystruct);
    printf("size of table B : %d\n", tbl_sz);

    return 0;
}

输出是:

size of table A : 0
size of table B : 2

这是 sizeof 的预期行为。但是有没有办法让编译器知道 const 表的大小,给定一个指向表的指针而不是符号名称?

4

5 回答 5

5

您要的是指针的大小。这始终是指针大小(即在 32 位机器上通常为 4 个字节,在 64 位机器上通常为 8 个字节)。在第二次尝试中,您要求数组的大小,因此您会得到您期望的结果。

于 2010-03-26T14:42:37.237 回答
2

有没有办法让编译器知道 const 表的大小,给定一个指向表的指针而不是符号名称?

不,因为sizeof()是在编译时评估的(除非它是 VLA,但 VLA 不是常量表),并且编译器通常无法判断指针指向哪个表。诚然,在所示的场景中,C 语言的一些假设变体可能是可能的,但这意味着 sizeof() 返回的定义不同,这比没有得到你可能喜欢但不得到的答案更大的问题得到。

因此,正如其他人巧妙地指出的那样,当您获取指针的大小时,您会得到指针的大小。假设一个标准的 32 位机器,因为结果与该假设一致,你的结构是 8 个字节,你的指针是 4 个字节,所以除法的结果是零,正如预期的那样。

于 2010-03-26T15:31:04.570 回答
1

不-您要的是sizeof()a 指针。但是由于您真正想要获取的是数组中元素的数量,因此您可以使用一个宏来返回该值,但如果您传递指针而不是数组,通常会给您一个错误:

#define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))

有关更多详细信息,请参阅此 SO 答案:C 中是否有标准函数可以返回数组的长度?

对于使用 C++ 而不是 C 时更安全的解决方案,请参阅使用模板以确保尝试获取指针上的数组计数始终会产生错误的 SO 答案:Compile time sizeof_array without using a macro

于 2010-03-26T14:50:33.403 回答
1

Short answer is no; if all you have is a pointer, then there's no (standard) way to get the size of the thing being pointed to through that pointer.

于 2010-03-26T16:19:45.497 回答
0

尽管语法正确,但您的示例更传统地写为:

const struct mystruct tableA[] = {
    {1, 2},
    {2, 2},
    {3, 3}, 
};

这不那么冗长,因此更具可读性。

于 2010-03-26T14:49:10.093 回答