如何理解下标为0的数组?

wang_qiao_ying 2010-07-22 06:42:33
nclude <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
struct helloworld_t
{
int num;
char helloworld[0];
};

int main()
{
struct helloworld_t *p;
unsigned int size = sizeof(struct helloworld_t) + strlen("Hello World!\n") + 1;
p = (struct helloworld_t *) malloc(size);
assert(p!=NULL);

memcpy(p, "\x01\x00\x00\x00Hello World!\n", size);

while (p->num--)
{
printf(p->helloworld);
}

//printf("%d \n", sizeof(helloworld_t));

free((void *)p);
return 0;
}

这个程序能正常打印hello world!,请高人帮忙理解一下char helloworld[0]的含义?


如果不在结构中定义下标为0的数组会报错,这是可以理解的,可是在结构中定义就没事了,这是为什么呢?
...全文
389 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wang_qiao_ying 2010-07-23
  • 打赏
  • 举报
回复
结贴了,感谢各位热情帮助,基本已经清楚是怎么回事了,领教了!学习了!^_^
yiruirui0507 2010-07-22
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 lthyxy 的回复:]
这是C/C++伟大的传统~
[/Quote]

赞同!
yiruirui0507 2010-07-22
  • 打赏
  • 举报
回复
http://hi.baidu.com/piaoshi111/blog/item/e22f09096b0589980a7b8224.html

这篇文章楼主看了也就晓得你的代码了。
liutengfeigo 2010-07-22
  • 打赏
  • 举报
回复
这是C/C++伟大的传统~
yiruirui0507 2010-07-22
  • 打赏
  • 举报
回复
这个问题其实就是柔性数组问题,编译器本身并不支持下标为0的数组定义,
大致解释一下,char helloworld[0];//主要是用来得到一个数组的地址,再由数组的个数来访问

);//\x01\x00\x00\x00四字节,就是给num赋值
//在内存中高8位和低8位反一下...
楼上这里说的非常赞同。
说白了char helloworld[0]; //helloworld是个占位符。helloworld[0]就是num后的第一个字节,
//helloworld[1]就是第二个字节。
struct helloworld_t* ph = (struct helloworld_t*)malloc(sizeof(struct helloworld_t)+X);
这样申请空间以后,你可以访问 ph->helloword[0]直到ph->helloworld[X-1]的空间。helloworld只是标记一个位置。
已经很明朗了,如果楼主还不清楚,那就需要自己去百度查查相关资料,动手实践加调试,懂汇编的话就更容易了。GOOD LUCK!
duke56 2010-07-22
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

struct helloworld_t
{
int num;
char helloworld[0];//主要是用来得到一个数组的地址,再由数组的个数来访问
};

int main()
{
struct helloworld_t *p;
unsigned int size = sizeof(struct helloworld_t) + strlen("Hello World!\n") + 1;
p = (struct helloworld_t *) malloc(size);
assert(p!=NULL);
memcpy(p, "\x01\x00\x00\x00Hello World!\n", size);//\x01\x00\x00\x00四字节,就是给num赋值
//在内存中高8位和低8位反一下...
// printf("%d\n",p->num);
while (p->num--)
{
printf(p->helloworld);
}
//printf("%d \n", sizeof(helloworld_t));
free((void *)p);
return 0;
}
phpjspasp 2010-07-22
  • 打赏
  • 举报
回复
struct helloworld_t
{
int num;
char helloworld[0]; //helloworld是个占位符。helloworld[0]就是num后的第一个字节,
//helloworld[1]就是第二个字节。
};

struct helloworld_t* ph = (struct helloworld_t*)malloc(sizeof(struct helloworld_t)+X);
这样申请空间以后,你可以访问 ph->helloword[0]直到ph->helloworld[X-1]的空间。helloworld只是标记一个位置。
wxwlll 2010-07-22
  • 打赏
  • 举报
回复
最起码,让编译器知道操作地址在哪吧!
yjh1982 2010-07-22
  • 打赏
  • 举报
回复
事实上标准是不支持下标为0数组的.这是编译器相关行为
matrixcl 2010-07-22
  • 打赏
  • 举报
回复
google 柔性数组
八哥 2010-07-22
  • 打赏
  • 举报
回复
p->helloworld =(int)p + sizeof(p) ;

如果是
int main
{
int a= 88 ; //&a=esp-4
struct helloworld_t hw; // &hw=esp-8


}

char helloworld[0]; 本身不占空间 不影响程序 你可以把它看成伪指令


//hw.helloworld= esp-8 + 4 = &a
//hw.helloworld[0]=88 ;

我要学技术 2010-07-22
  • 打赏
  • 举报
回复
这代码写得……
baihacker 2010-07-22
  • 打赏
  • 举报
回复
主要是实现一个可变长的结构,这个结构后面的就是变长部分。
用x.helloword表示访问这个数组,而一般数组又会转为对应的指针,于是就得到变长部分的起始地址了。
如果是int helloword。也可以,只是这个变长部分的大小至少是int大小,另外不能方便地得到变部分的起始地址了,要&运行才知道。

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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