Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 227|回复: 0

[默认分类] C语言的数组初始化

[复制链接]
  • TA的每日心情
    无聊
    2021-3-21 17:28
  • 签到天数: 13 天

    [LV.3]偶尔看看II

    发表于 2018-7-6 15:32:11 | 显示全部楼层 |阅读模式

         这是很基础的东西,但基础的重要性不言而喻,我敢肯定这个知识点我肯定曾经了解过,但现在,我不敢确定,由此可见纪录的重要性,这世界没有什么捷径,找对方向,然后不停重复.所以从今天开始,我会比较详细的纪录这些比较小的知识点,其实还是有不少有意思的地方的.

        写这篇文章的起因在于<<COM技术内幕>>第七章新东西太多,看的我目不暇接,所以在网上找了些例子看,其中就有一个例子中出现了这样的语句:

      
       
       ...
    wchar_t wname[
       128
       ]
       =
       ...
       {0}
       ;

       char
        cname[
       256
       ]
       =
       ...
       {0}
       ;
    ...
      

    我感兴趣的是:
    1.这种赋值的结果.
    2.这种形式是否符合标准编码规则?
    我找到了如下资料,可能有助于对这个知识点的掌握.

      
       
       
       /**/
       /*
    初始化值的个数可少于数组元素个数.当初始化值的个数少于数组元素个数时,前面的按序初始化相应值, 后面的初始化为0(全局或静态数组)或为不确定值(局部数组).
    */
      

      
    我相信上面的资料是C和C++语言的标准规范,但实际编译器处理时,可能会和规范有所不同.因为编译器原则上要遵从语言规范,但对于局部数组的不确定值到底是多少,怎么处理,编译器就可以灵活处理.我测试了三种编译器,其实编译器赋予的值是固定的,都是0.
    在这篇blog中 http://hi.baidu.com/widebright/blog/item/a024bc09631402256b60fbd0.html 谈论了相同的话题,现对其摘录如下:

      
       
       
       /**/
       /*
    一直以为 int a[256]={0};是把a的所有元素初始化为0,int a[256]={1};是把a所有的元素初始化为1.
    调试的时查看内存发现不是那么一回事,翻了一下《The C++ Programming Language》总算有定论。PDF的竟然不然复制,就把它这章翻译了,如下

    5.2.1   数组初始化
    数组可以用一个列值来初始化,例如
             int v1[] ={1,2,3,4};
             char v2[]={"a","b","c",0};
    当数组定义时没有指定大小,当初始化采用列表初始化了,那么数组的大小由初始化时列表元素个数决定。所以v1和v2分别为 int[4] 和char[4]类型。如果明确指定了数组大小,当在初始化时指定的元素个数超过这个大小就会产生错误。例如:
             char   v3[2] ={"a","b",0};   //错误:太多的初始化值了
             char   v3[3] ={"a","b",0};   //正确

    如果初始化时指定的的元素个数比数组大小少,剩下的元素都回被初始化为   0。例如
             int   v5[8]={1,2,3,4};
    等价于
              int   v5[8]={1,2,3,4,0,0,0,0};

    注意没有如下形式的数组赋值:
             void f()
             {
                 v4={"c","d",0};   //错误:不是数组赋值
             }
    如果你想这样的复制的话,请使用 vector(16章第三节) 或者 valarray(22章第四节)。
            字符数组可以方便地采用字符串直接初始化(参考第五章 2.2小节)
             译注: 就是 这样啦   char   alpha []="abcdefghijklmn";

    */
      

      
    下面来看一个例子:

      
       
       #include
       <
       iostream.h
       >
       


       int
        array1[
       5
       ]
       =
       ...
       {1,2,3}
       ;

       static
       
       int
        array2[
       5
       ]
       =
       ...
       {1}
       ;



       void
        main()

       ...
       {
        int arr1[5]=...{2};
        static int arr2[5]=...{1,2};
       
        int n;
        cout <<"global: ";
        for(n=0; n<5; n++)
            cout <<" " <<array1[n];
       
        cout <<" global static: ";
        for(n=0; n<5; n++)
            cout <<" " <<array2[n];
       
        cout <<" local: ";
        for(n=0; n<5; n++)
            cout <<" " <<arr1[n];
       
        cout <<" local static: ";
        for(n=0; n<5; n++)
            cout <<" " <<arr2[n];
        cout <<endl;
    }
       


      

    在这个例子中,全局和静态数组都按语言规范要求被初始化为0,但是局部数组并没有向前面所说的为不确定值,下面是用gcc,VC6.0,tuborC++分别编译的结果(注意gcc用g++编译c++文件,gcc不会链接库的):

      
       
       
       /**/
       /*
    GCC 可同时用来编译 C 程序和 C++ 程序。一般来说,C 编译器通过源文件的后缀名来判断是 C 程序还是 C++ 程序。在 Linux 中,C 源文件的后缀名为 .c,而 C++ 源文件的后缀名为 .C 或 .cpp。
        但是,gcc 命令只能编译 C++ 源文件,而不能自动和 C++ 程序使用的库连接。因此,通常使用 g++ 命令来完成 C++ 程序的编译和连接,该程序会自动调用 gcc 实现编译。
    */
      

      
    GCC:

      


      
    VC6.0:




      
    TurboC++

      


      
         这说明了对局部数组没有初始化的元素的值,这几种编译器都将其设置为0.但是,如果如果不对数组进行初始化,即在定义的同时没有用列表初始化,那么局部数组的值就取决于编译器而对程序员来说就是不可预料的了.有时间可以测试一下各个编译器,不过在vc中是0xcc.所以对局部数组的初始化要特别小心.但是全局的数组和静态数组还是会被正确的赋于0值的.
         最后要重申下对变量初始化的重要性, http://blog.vckbase.com/smileonce/archive/2005/06/18/6777.html  这里列举了没有初始化造成的事故.
         此外,这个blog地址值得收藏,在http://blog.vckbase.com/ 排行榜的blog都值得仔细看.
         在VC的安装盘的/VC98/CRT下可以看到vc自带的C/C++库的源代码.
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    .

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2021-9-18 12:30 , Processed in 0.356464 second(s), 29 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表