目录
问题来源:在日常学习结构体的语法时看到文章中用数组进行举例,进行输出,在讨论数组是否初始化,输出的值的问题,代码如下
#include<stdio.h>
int main() {
int arry[20] = { 1 };
int arry2[20];
printf("有初始化");
for (int i = 0; i < 20; i++) {
printf("%d ", arry[i]);
}
printf("无初始化");
for (int i = 0; i < 20; i++) {
printf("%d ", arry2[i]);
}
return 0;
}
变量初始化
想到,c语言中的变量和数组如果不进行初始化,虽然在刚开始学习的时候,总告诉我们要进行变量的初始化,那么不进行变量的初始化,会发生什么呢?
在 VS中运行会提示错误,但是我在虚拟机中运行却输出了一个0
那么再尝试下数组不进行初始化,
#include<stdio.h>
int main() {
int array[10];
for (int i = 0; i < 10; i++) {
printf("%d\n", array[i]);
}
return 0;
}
输出结果如下:
问了一下朋友,他运行下来是这样的结果
去搜索了很多最后找到了一个文章去讲解关于这个没有进行初始化随机值的问题
未初始化
随机数的产生
如果一个变量i没有进行初始化,就将其打印出来,那么变量i会和内存中的某一个单元产生关联。然后变量i就代表那个内存单元了,如果要想操作该内存单元只需要通过变量i就可以了。所以内存中到底放的是什么?
产生原理
引用自:C语言变量初始化是必须的吗?不初始化会怎样? (biancheng.net)http://c.biancheng.net/view/156.html
首先,内存条是一个硬件设备,硬件设备里面要么是 0 要么是 1。计算机肯定得通电,没有电就运行不起来,有电之后它就会通过各种二极管、三极管之类的元器件产生高低电平。
如果电压在某一个范围之上,就认为是 1,在某一个范围之下,就认为是 0。所以 1 就表示高电平,0 就表示低电平,即电压的高或低产生 1 或 0。这时候只有两种状态,要么是 1,要么是 0。所以说 i 里面存放的就是由 0 和 1 组成的代码,不可能里面什么都没有!因为计算机要工作肯定得有电,有电就不可能是空的,有电就会转化成 1 或 0 这样的高低电平。所以硬件上要么是 1 要么是 0,不可能既不是 1 也不是 0,什么都没有!计算机硬件没有那种状态,这也是为什么计算机只能识别二进制的原因。所以变量 i 所关联的那内存单元里面肯定是由 0 和 1 组成的代码。这里 i 单元虽然没有给它赋值,但这个空间在之前可能被其他软件使用过。比如放电影的时候将电影中的某一部分数据放到了这个单元中。电影看完之后一关闭,这个单元空间就释放了,即操作系统就会回收该内存空间,以便分配给其他软件使用。
但需要注意的是,操作系统虽然回收了该内存空间,但它并不清空该内存空间中遗留下来的数据,这句话很重要。但这样的话就会出现一个问题:以前的软件如果使用过 i 这个空间的话,那么那些垃圾数据还在里面保留着,如果没有初始化,那么它里面就应该是一个随机的垃圾值。但是当我们多次执行的时候发现它不是一个随机的值,而是一个不变的值。这是为什么呢?这个值叫“填充数字”或叫“填充字”。
微软公司在设计 VC++ 这个软件的时候,在它内部添加了一些特殊的处理。即如果发现一个变量里面存放的是一个垃圾值,就认为没有给它赋初值,那么系统就会自动将一个很小的,如 –858993460 这个填充数字给放进去。所以我们看到的结果都是一个不变的值。
大概是计算机组成原理的知识。
所以我突然想到如果在macos运行的话,是不是就可能不会有微软的填充,就会有之前软件占用或者系统占用留下来的“垃圾值”?
果然,运行结果如上,并没有填充的很小的值!
初始化必要性
所以在任何一个变量在使用之前必须要先对它进行初始化。不初始化的话使用它就没有实际意义了。在实际编程中,习惯上在定义变量的时候就对它进行初始化,这是一个很好的编程习惯。
但是在c89的语言标准下,变量的定义只能在程序的开头或者复合语句的开头。如果中间想要用到某个变量,如何进行初始化呢?一般习惯于在开头先将其初始化为0,后面再用的时候,对他进行重新的赋值。所以这可能就是初学c语言的时候习惯于把变量初始化为0的原因吧。