我来我网
https://5come5.cn
 
您尚未 登录  注册 | 菠菜 | 软件站 | 音乐站 | 邮箱1 | 邮箱2 | 风格选择 | 更多 » 
 

本页主题: 变量长度数组 显示签名 | 打印 | 加为IE收藏 | 收藏主题 | 上一主题 | 下一主题

ljpdxj



性别: 帅哥 状态: 该用户目前不在线
等级: 栋梁之材
发贴: 687
威望: 0
浮云: 1108
在线等级:
注册时间: 2006-02-28
最后登陆: 2008-06-29

5come5帮你背单词 [ quart /'kwo:t/ n. 夸脱(英美干量、液量单位) ]


变量长度数组

最近细读《Programming in C》,里面讲数组时讲到了“变量长度数组”,说有的编译器支持这样的用法:

      int i=10;
      char buf[ i ];

      我测试发现VC6是不支持这个的,但是GCC支持!我写了这样的测试代码,发现程序居然也支持i是负数,而且在负数的情况下,GCC的内存分配虽然怪异,但也是保证正确的。

Copy code
#include <stdlib.h>
#include <stdio.h>

void fun(int i)
{
    char kk = 'B';
    char buf[ i ];
    char mm = 'E';

    printf("size :: %d %x -- %x\n", sizeof(buf), (size_t)buf, (size_t)&buf[i-1]);
    buf[i-1] = 'a';
    printf("\t\t\t buf[i-1]:%c\t %x:%c \t %x:%c \n", buf[i-1], (size_t)&kk, kk, (size_t)&mm, mm);
}

int main(int argc, char * argv[], char * envp[])
{
    fun(2);
    fun(3);
    fun(4);
    fun(1);
    fun(0);
    fun(-1);
    fun(-10);
}

GCC安全的为负数长度的数组分配了空间,保证了这种数组的安全使用, 不会影响栈上的其他变量空间。
下面是输出:

Copy code

size :: 2 bfbfec50 -- bfbfec51
                        buf[i-1]:a      bfbfec7f:B      bfbfec7e:E
size :: 3 bfbfec50 -- bfbfec52
                        buf[i-1]:a      bfbfec7f:B      bfbfec7e:E
size :: 4 bfbfec50 -- bfbfec53
                        buf[i-1]:a      bfbfec7f:B      bfbfec7e:E
size :: 1 bfbfec60 -- bfbfec60
                        buf[i-1]:a      bfbfec7f:B      bfbfec7e:E
size :: 0 bfbfec60 -- bfbfec5f
                        buf[i-1]:a      bfbfec7f:B      bfbfec7e:E
size :: -1 bfbfec60 -- bfbfec5e
                        buf[i-1]:a      bfbfec7f:B      bfbfec7e:E
size :: -10 bfbfec60 -- bfbfec55
                        buf[i-1]:      bfbfec7f:B      bfbfec7e:E

我的疑问:




0长度的数组有什么意义?
这个经过搜索资料,我已经知道了,参考:http://bbs.chinaunix.net/viewthread.php?tid=854949

在产品级的软件开发中,这种“变量长度数组”有人应用吗?
嗯,我估计这种不通用的东西产品里应该很少用。尽量避免使用,增强移植性。

至于数组长度是负数的情况,我是这么想的:
      GCC就像数学家发现自然数后又发现了负数那样,GCC为人们实现了负数数组长度,并告诉我们数组长度也可以是负数。
      至于负数有什么物理意义,数学家先不管了;数组长度负数有什么实际意义,Gcc就不管了。

Quote:
引用第1楼yinx于2007-11-30 12:36发表的  :
变量mm的空间分配先于buf数组?
能对0长度数组或者负数长度数组的单元赋值吗?

风中帖的转过来
回答第一个问题:我也不太清楚mm的空间分配是否先于buf,但是肯定的是在程序运行的时候分配,变量长度数组C99是不支持的,但是有些编译器支持如GCC;在标准 C 或者 C++ 中由于不支持 0 长度的数组,所以 int array[0]; 这样的定义是非法的。不过有些编译器的扩展功能支持 0 长度的数组。声明0长度数组也只是做一个地址标记。
第二个问题:从上面测试代码来看很明显如果用GCC, 0长度数组或者负数长度数组的单元赋值是成功的,但内存单元具体怎么实现不清楚

在 C 中,0 长度的数组的主要用途是用来作为结构体的最后一个成员,然后用它来访问此结构体对象之后的一段内存(通常是动态分配的内存)。由于其非标准性,在程序中尽量避免使用 0 长度的数组。作为替换,可以使用 C99 标准中的不完整数组来替换 0 长度的数组定义。
在工程中0长度数组:
Copy code
int main(void)
{
    struct  student{
            unsigned int ID;
            char  follow_info[0];
            /*这里不能再有数据成员*/
        } Ptr*;
  int i = 100 ,count ;
    Ptr = malloc(sizeof(struct student) + i);
    for (count =0 ; count < i; ++count )
        p->data[i] = 1;
}



[ 此帖被ljpdxj在2007-11-30 14:53重新编辑 ]
顶端 Posted: 2007-11-29 22:49 | [楼 主]
zhd32



性别: 帅哥 状态: 该用户目前不在线
等级: 版主
家族: YD一族
发贴: 619
威望: 0
浮云: 543
在线等级:
注册时间: 2006-04-22
最后登陆: 2009-06-22

5come5帮你背单词 [ trade /treid/ n. 贸易,商业,行业;vt. 用…进行交揣,相互交换 ]


Quote:
引用第3楼hhbhhb于2007-11-30 10:41发表的  :
其实从汇编来考虑的话也确实是可以实现的。。只要被调用函数清栈,过程中占了多少栈空间确实无所谓嘛。。

汇编是无所不能的~~
顶端 Posted: 2007-11-30 11:56 | [1 楼]
我来我网·5come5 Forum » 程序员之家

Total 0.011336(s) query 6, Time now is:11-22 21:54, Gzip enabled
Powered by PHPWind v5.3, Localized by 5come5 Tech Team, 黔ICP备16009856号