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

写这篇文章的起因在于<<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};   //正确

如果初始化时指定的的元素个数比数组大小少,         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 <<"\n";    //C++换行
    
    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 可同时用来编译 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都值得仔细看.

版权声明:本文为博主原创文章,未经博主允许不得转载。

数组初始化(c, c++, gcc, g++)的更多相关文章

  1. gcc g++ 参数介绍

    C和C++ 编译器是集成的.他们都要用四个步骤中的一个或多个处理输入文件: 预处理 (preprocessing),编译(compilation),汇编(assembly)和连接(linking).源 ...

  2. C语言 数组初始化的三种常用方法({0}, memset, for循环赋值)以及原理

    C语言中,数组初始化的方式主要有三种: 1.声明时,使用 {0} 初始化: 2.使用memset: 3.用for循环赋值. 那么,这三种方法的原理以及效率如何呢? 请看下面的测试代码: #define ...

  3. 从C过渡到C++——换一个视角深入数组[初始化](1)

    从C过渡到C++--换一个视角深入数组[初始化](1) 目录 从C过渡到C++--换一个视角深入数组[初始化](1) 数组的初始化 从C入手 作用域 代码块作用域 文件作用域 原型作用域 函数作用域 ...

  4. Linux Kernel代码艺术——数组初始化

    前几天看内核中系统调用代码,在系统调用向量表初始化中,有下面这段代码写的让我有点摸不着头脑: const sys_call_ptr_t sys_call_table[__NR_syscall_max+ ...

  5. C++中数组初始化

    #include<iostream>using std::cout;using std::endl;int arr1[5];int arr2[5] = {1,3,5};int main() ...

  6. Linux Kernel代码艺术——数组初始化【转】

    转自:http://www.cnblogs.com/hazir/p/array_initialization.html 前几天看内核中系统调用代码,在系统调用向量表初始化中,有下面这段代码写的让我有点 ...

  7. CentOS 6.6 升级GCC G++ (当前最新版本为v6.1.0) (完整)

    ---恢复内容开始--- CentOS 6.6 升级GCC G++ (当前最新GCC/G++版本为v6.1.0) 没有便捷方式, yum update....   yum install 或者 添加y ...

  8. Clang比 gcc/g++更人性化代码出错提示的C/C++编译器

    编译器方面的几个命令 gcc/g++ 一. 常用编译命令选项 常用用法 gcc -Wall test.c -o test gcc编译过程 .c ->(-E)-> .i[中间文件] -> ...

  9. Linux 之 编译器 gcc/g++参数详解

    2016年12月9日16:48:53 ----------------------------- 内容目录: [介绍] gcc and g++分别是gnu的c & c++编译器 gcc/g++ ...

随机推荐

  1. 自给自足:动手打造html5俄罗斯方块

    时间:凌晨2:36 历时:两晚+半个下午 代码:约300行 这两天发烧,头痛脑壳昏的,没想到竟然还能有动力去做小游戏,其实这不是我第一次想要弄个俄罗斯方块,前几个星期的时候就尝试着去弄一个,然后被凌乱 ...

  2. Flink Program Guide (8) -- Working with State :Fault Tolerance(DataStream API编程指导 -- For Java)

    Working with State 本文翻译自Streaming Guide/ Fault Tolerance / Working with State ---------------------- ...

  3. WdatePicker日历控件使用方法

    1. 跨无限级框架显示 无论你把日期控件放在哪里,你都不需要担心会被外层的iframe所遮挡进而影响客户体验,因为My97日期控件是可以跨无限级框架显示的 示例2-7 跨无限级框架演示 可无限跨越框架 ...

  4. skynet的流程1

    logpath = "."harbor = 1address = "127.0.0.1:2526"master = "127.0.0.1:2013&q ...

  5. C语言字符和字符串随记

    ==========================第11章 字符和字符串函数==========================震惊:字符串常量属于静态存储类,常量引号中的内容作为指向该字符串存储位 ...

  6. Struts2命名空间问题

    警告: No configuration found for the specified action: '/myNameSpace/login.action' in names 今天花了点时间把st ...

  7. 【原】win7下调整分区

    由于装系统时硬盘分区极度不合理,导致现在装一些比较大的开发软件根本不能装,但是又不想重装系统调整分区,而且还不想让已有的文件受到一点伤害,毕竟数据无价啊.几番搜索后,发现了一款比较好用的硬盘管理软件  ...

  8. MySQL必知必会 学习笔记(一)

    第一章  了解SQL 模式:   关于数据库和表的布局以及特性的信息.[描述表可以存储什么样的数据,数据如何分解,各部分信息如何命名等等,可以用来描述数据库中特定的表以及整个数据库(和其中表的关系)] ...

  9. Linux学习十七、正规表达式练习题

    情境模拟题一:透过 grep 搜寻特殊字串,并配合数据流重导向来处理大量的文件搜寻问题. 目标:正确的使用正规表示法: 前提:需要了解数据流重导向,以及透过子命令 $(command) 来处理档名的搜 ...

  10. rem布局

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...