没有长度的数组

来源:互联网 发布:oracle数据库设计方案 编辑:程序博客网 时间:2024/04/29 10:03

 

有人说C语言是一个很诡异的语言,所以有时候我们会见到一些比较奇怪的定义,比如:

struct A{
 int a;
 int data[]
};

这个看起来确实很奇怪,为什么数组没有定义大小呢?

但实际上这段代码不仅可以通过大部分编译器,并且用途还很广泛。我工作的时候就遇到了不少这样的代码,并且还是比较关键的代码。

不过实际上事情并没有那么复杂和难以理解,不用看那些复杂的关于零长度数组是否符合C标准,以及不完整类型等等没见过的名词,其实道理很简单,C也不会专门为了这个而搞出来很复杂的规则。

让我们来看看,什么地方还会用到这样类似的东东:

int f(int array[])

{

...

}

 

int main(void)

{

int a[10];

...

f(a);

...

}

 

想想看,是不是一样的道理?

int a[]无论怎么用,都是一个意思,就是说明a是一个数组,但是不知道它的大小。

当然在struct A的定义中,与这里还是有些不同的,因为int data[]并没有占用实际的空间,sizeof(struct A) = 2(或者是4,依赖于平台)。 

 

另外,int data[0]在有些编译器上也可以通过,并且和int data[]具有相同的效果,所以上面的结构体声明可能看起来象下面这样:

struct A{
 int a1;
 int data[0];
};

这种写法不推荐使用,因为不符合C的标准,而且看起来更怪更难以理解。

 

引用别人的一个例子,就可以更深入的理解了:

#include "stdio.h"
#include "stdlib.h"
struct A{
 short a1;
 short next[0];
} * pA = NULL;

struct B{
 short a1;
 short next[1];
};

main()
{
    short abc[10];
    int i;
    printf("sizeof(struct A)=%d, sizeof(short)=%d, sizeof(struct B)=%d/r/n", sizeof(struct A), sizeof(short), sizeof(struct B));
    for (i=0; i<10; i++) abc[i] = i;
    pA = (struct A * ) abc;

    for (i=0; i<10; i++) {
         printf("i: %d, i.next:%d/r/n", pA->a1, pA->next[0]);
         pA++;
         /*
         注意与的不同,下面的语句要考虑到入栈的顺序,i和i.next的输出是相同的
         printf("i: %d, i.next:%d/r/n", pA->a1, pA++->next[0]);
         */
    };

    getch();
}

注:例子来源于http://www.etcell.com/soft/topicView.aspx?Id=38200,我是用baidu的cache看到的,看不到作者的名字,就不写了,大家看到了帮忙告诉我,我写上。另外,代码修改了一句,以便突出重点。

原创粉丝点击