【问题标题】:sizeof abuse : get the size of a const tablesizeof 滥用:获取 const 表的大小
【发布时间】:2010-03-26 14:41:08
【问题描述】:

在声明 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 表的大小,给定一个指向表的指针而不是符号名称?

【问题讨论】:

  • 您的意思是“sizeof(table)”而不是“sizeof(tableB)”吗?这可能会导致您的困惑。
  • 这是故意的。 sizeof(tableB) 有效,而第一个示例确实给出了(正确的)结果 0。我想知道是否有任何技巧来获取 const 表的大小,给定一个指向该表的指针。

标签: c sizeof


【解决方案1】:

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

【讨论】:

  • 我理解这种行为,我正在寻找一种方法来获取 tableA 的大小而不使用它的符号
  • C 根本不这样做。它的指针并不神奇地知道它们指向的数组的大小。如果他们这样做了,那就太奇怪了。想象一个指向数组中间条目的指针:sizeof() 会返回什么?现在,它要么是指针的大小,要么是指向的元素的大小(取决于解引用级别)。既然如此,为什么指向数组的开头更特别? (答案:不是。)
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

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

    有关详细信息,请参阅此 SO 答案:Is there a standard function in C that would return the length of an array?

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

    【讨论】:

      【解决方案4】:

      简短的回答是否定的;如果您只有一个指针,那么就没有(标准)方法来获取通过该指针指向的事物的大小。

      【讨论】:

        【解决方案5】:

        虽然在语法上是正确的,但您的示例更传统地写成:

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

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

        【讨论】:

        • 因为我初始化了所有字段,而且是一个简单的结构,但是添加一些字段甚至其他结构,你提出的初始化样式很快就变得不可读。无论如何,这不是我问题的答案,也不是讨论这个问题的地方。
        猜你喜欢
        • 1970-01-01
        • 2011-05-07
        • 2017-06-26
        • 1970-01-01
        • 1970-01-01
        • 2016-12-12
        • 2016-02-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多