【问题标题】:C: How to determine sizeof(array) / sizeof(struct) for external array?C: 如何确定外部数组的 sizeof(array) / sizeof(struct)?
【发布时间】:2014-06-07 10:46:29
【问题描述】:

定义类型x和该类型的数组X

x.h:

typedef struct _x {int p, q, r;} x;
extern x X[];

单独的文件以保留巨大的喇叭数组X

x.c:

#include "x.h"
x X[] = {/* lotsa stuff */};

现在我想使用X

main.c:

#include "x.h"

int main()
{
    int i;

    for (i = 0; i < sizeof(X)/sizeof(x); i++) /* error here */
        invert(X[i]);

    return 0;
}

main.c 不会编译;错误是:

error: invalid application of ‘sizeof’ to incomplete type ‘struct x[]’

如何在不进行硬编码的情况下获得X 的大小?

【问题讨论】:

  • 如果 x 是一个结构,你通常必须指定 sizeof(struct x)
  • typedef不需要使用struct

标签: c arrays compiler-errors sizeof


【解决方案1】:

x.h 中添加:

extern size_t x_count;

x.c 中添加:

size_t x_count = sizeof(X)/sizeof(x);

然后在循环中使用变量x_count

除法必须在包含数组初始值设定项的编译单元中完成,因此它知道整个数组的大小。

【讨论】:

  • 这可能会解决 OP 的特定问题,但总的来说它是有缺陷的,因为 count 仍然不是一个常量表达式,并且不能在所有使用 sizeof 的地方使用。此外,int 是错误的类型。应该是size_t
  • 它与单独编译的模块一样接近。如果数组初始化在同一个编译单元中,则size只能是常量表达式。
  • sizeof 的结果是一个常量表达式,用于初始化全局变量。但是,您使用 size_t 是完全正确的。
  • 谢谢,我将此解决方案与包装器 #define XCOUNT x_count 一起用于遗留用途。
  • 我认为将x_count 声明为const size_t 没有问题
【解决方案2】:

如果可以在数组末尾放置一个终止指示符,如:

x X[] = {/* lotsa stuff */, NULL};

可能是数组中的元素数量无关:

#include "x.h"

int main()
   {
   x *ptr = X;

   while(ptr)
      invert(ptr++);

   return 0;
   }

如果需要数组的元素个数,也可以用上面的方法来统计元素个数。

【讨论】:

    【解决方案3】:

    这里是使用复合文字的解决方案:

    .h

    typedef struct _x {int p, q, r} x;
    
    #define LOTSA_STUFF        {1, 2, 3}, {4, 5, 7}
    #define LOTSA_STUFF_SIZE  sizeof ((x[]) {LOTSA_STUFF})
    
    extern x X[LOTSA_STUFF_SIZE];
    

    .c

    x X[LOTSA_STUFF_SIZE] = {LOTSA_STUFF};
    

    对于.c 中的定义,您甚至可以做得更好并使用静态断言(STATIC_ASSERT 的定义可以作为读者练习;):

    x X[] = {LOTSA_STUFF};
    
    STATIC_ASSERT(sizeof X != LOTSA_STUFF_SIZE, "oops, sizes are not equal");
    

    【讨论】:

    • 多么酷的例子。我从未使用过复合文字,也不熟悉语法。 Dr. Dobb's 上有一篇非常好的文章,供有兴趣了解更多信息的人使用。
    • 哦...在.h 示例的第四行中,您的LOTSA_STUF 上缺少一个“F”。
    • 这个版本仍然需要在标题中显示初始数据,我认为 OP 试图避免这种情况。
    【解决方案4】:

    如果只包含 x.h,编译器将不知道 X 的实际大小是多少。光看x.h,是没法猜的。 您必须声明 X 的大小:

    extern x X[15];
    

    【讨论】:

    • 使用sizeof(X)/sizeof(x) 的全部意义在于,您不必硬编码元素的数量,它会根据数组初始值设定项中的元素数量自动调整大小。
    【解决方案5】:

    你不能那样做。但是您可以提供一种获取大小的方法。

    除了

    extern x X[];
    

    添加

    extern size_t xArraySize;
    

    或者,最好是,

    extern size_t xArraySize(void);
    

    x.h

    x.c中定义它。

    将循环更改为:

    for (i = 0; i < xArraySize(); i++)
        invert(X[i]);
    

    【讨论】:

    • 为什么函数更可取?
    • @Rick 它允许您隐藏数据存储方式的详细信息。
    猜你喜欢
    • 2014-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多