struct不能在数组后面有变量吗?

liuqingwu228 2007-08-02 08:26:23
struct mm
{
char b;
int c;
int a[];

};
这样就成功
改成
struct mm
{
char b;

int a[];
int c;

};
就失败,不知道为什么呢?难道与数组大小没有定义有关吗?
...全文
930 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
lockhall 2007-08-06
  • 打赏
  • 举报
回复
OK thanks Chiyer.
星羽 2007-08-06
  • 打赏
  • 举报
回复
用户定义类型 (UDT)
lockhall 2007-08-06
  • 打赏
  • 举报
回复
warning C4200: nonstandard extension used : zero-sized array in struct/union
Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array

UDT是什么意思?
taodm 2007-08-06
  • 打赏
  • 举报
回复
报warning是因为按C99标准应该写a[0];
taodm 2007-08-03
  • 打赏
  • 举报
回复
是有很多编译器不报错的。但是,不报错不表明就正确。
柔性数组成员只有是结构的最后一个成员时才有意义。
编程是要用的,不是挑战编译器的。
Vitin 2007-08-03
  • 打赏
  • 举报
回复
我错了。
Chiyer 和 lockhall 是正确的。

事实是:VS2005在报了一个warning 之后又报了一个 error(昨天竟然只看了一行,汗!)。
warning 是针对a[]的。error则是当发现a[]后还有一个c时报的。
也就是说,error才是第二种情况的直接后果。

在第一种情况中,也报了warning C4200,看来VS2005并不推荐这种用法。

psbeond 2007-08-03
  • 打赏
  • 举报
回复
我解释一下:
int a[]这种语法, 只能用在结构体(或类)中, 而不能用到函数中, 也就是说
void func()
{
int a[];
}
是编译错误的。
当int a[]这种语法用到结构体(类)中的时候,等价于int a[0], 也就是说a不是不定长数组, 而是0长度数组, 这时sizeof(a)的值是0, 不占用空间。
所以, 如果
struct mm
{
char b;
int a[];
int c;
};
成立的话, 那么a和&c的值就是一样的了, 这显然是不被允许的。
lockhall 2007-08-03
  • 打赏
  • 举报
回复
嗯。

早上也试了下,是error不是warning

不知道是不是 vitin 手误 或者 VS2005不一样。
星羽 2007-08-03
  • 打赏
  • 举报
回复
vs2005sp1

对于第2种

\visual studio 2005\projects\c2\c2\c2.cpp(37) : error C2229: struct 't' has an illegal zero-sized array
liuqingwu228 2007-08-03
  • 打赏
  • 举报
回复
谢谢大家介绍,我用的是vc6.0,我只是想弄清楚中间的原理那呵呵
lockhall 2007-08-02
  • 打赏
  • 举报
回复
Vitin(卫亭)

呵呵,VS2005上我確實沒測試過。:)

確認下VS2005給出的是warning不是error?
Vitin 2007-08-02
  • 打赏
  • 举报
回复
附议lockhall

这是来自C的高效手段。从实现上来说,未定长度数组应该在struct的结尾处。

在这一点上,部分编译器只支持数组处在结尾的写法,是因为只有这种写法是有实用性的。

对第二种写法,试了一下DEVCPP和VS2005。前者顺利通过编译,后者给了一个warning:
“warning C4200: 使用了非标准扩展 : 结构/联合中的零大小数组”
lockhall 2007-08-02
  • 打赏
  • 举报
回复
在VS2005和DEVCPP中應該支持這種寫法了。
lockhall 2007-08-02
  • 打赏
  • 举报
回复
樓主用的VC6.0吧

換個vs2005或者devcpp看下
lockhall 2007-08-02
  • 打赏
  • 举报
回复
先轉個結構體中數組下標為0的看下吧。

这是个广泛使用的常见技巧,常用来构成缓冲区。比起指针,用空数组有这样的优势:
1.不需要初始化,数组名直接就是所在的偏移
2.不占任何空间,指针需要占用int长度空间,空数组不占任何空间。

“这个数组不占用任何内存”,意味着这样的结构节省空间;“该数组的内存地址就和他后面的元素的地址相同”,意味着无需初始化,数组名就是后面元素的地址,直接就能当做指针使用。

这样的写法最适合制作动态buffer。因为可以这样分配空间:
malloc(sizeof(struct XXX)+ buff_len);
看出来好处没有?直接就把buffer的结构体和缓冲区一块分配了。用起来也非常方便,因为现在kongsuzu其实变成了buff_len长度的数组了。
这样的好处是:
一次分配解决问题,省了不少麻烦。大家知道为了防止内存泄漏,如果是分两次分配(结构体和缓冲区),那么要是第二次malloc失败了,必须回滚释放第一个分配的结构体。这样带来了编码麻烦。其次,分配了第二个缓冲区以后,如果结构里面用的是指针,还要为这个指针赋值。同样,在free这个buffer的时候,用指针也要两次free。如果用空数组,所有问题一次解决。
其次,大家知道小内存的管理是非常困难的,如果用指针,这个buffer的struct部分就是小内存了,在系统内存在多了势必严重影响内存管理的性能。要是用空数组把struct和实际数据缓冲区一次分配大块问题,就没有这个问题。

如此看来,用空数组既简化编码,又解决了小内存碎片问题提高了性能,何乐不为?应该广泛采用。
uwinb 2007-08-02
  • 打赏
  • 举报
回复
我试了,没有问题!

64,639

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧