C语言的未初始化的数组的值为什么是随机的

未初始化数组值随机原因解析
本文围绕未初始化数组的值展开探讨。指出未初始化数组分全局和局部两种情况,全局数组元素默认值为0,局部数组值默认随机。解释了局部数组值随机是因其存于栈区,栈操作遗留数据未清空。还通过代码及地址操作进一步证明未初始化数组值随机的来源。

突然想起来前几天同学问我为什么没有初始化的数组的值是随机的,发现这个困惑自己也是存在的,所以自己总结的心得.

  1. 首先,并不是所有未初始化的数组的值都是随机的.对于没有初始化的数组,分两种情况:

(1)全局数组,也就是定义在main函数外面的数组,元素的默认值是全部为0的

(2)局部数组,定义在函数内部的数组,其值默认是随机的.

#include <stdio.h>

#define LENGTH 5
int a[LENGTH];

int main()
{
for(int i=0;i<LENGTH;i++){
printf("%d “,a[i]);
}
printf(”\n");

int b[LENGTH];
for(int i=0;i<LENGTH;i++){
    printf("%d ",b[i]);
}

}

0 0 0 0 0
4200814 4200720 49 8 41
Process returned 0 (0x0) execution time : 0.739 s
Press any key to continue.
  从代码结果可以清楚地看出来,全局数组与局部数组的默认值是不同的.

2.我们接下来再说局部数组为什么是随机的.局部数组是放在栈区的,而全局数组是放在静态区的.

因为局部数组放在栈区,栈的操作就是入栈和出栈.我们声明数组,其实只是移动栈顶指针.而栈内的数据是上一次出栈时候遗留的数据.栈不会清空.所以数据是随机的.下面用一段代码说明.

#include <stdio.h>
void test();
int main()
{
test();
test();
}

void test()
{
int a[5];
for(int i=0;i<5;i++){
printf("%d “,a[i]);
}
printf(”\n");
for(int i=0;i<5;i++){
a[i] =i;
}
for(int i=0;i<5;i++){
printf("%d “,a[i]);
}
printf(”\n");
}

//输出结果
1944480698 1944480941 4200720 6356884 4200814
0 1 2 3 4
0 1 2 3 4
0 1 2 3 4
  当我们连续两次调用一个函数的时候.我们发现只有第一次的值似乎是随机的.因为我们两次相同的操作对栈的地址操作也是相同的.我们第一次函数对栈的修改并没有被栈清空,所以第二次的随机值就是第一次最后的数据了.

3.第二次更新,今天又想到了一个骚操作来证明.用的是c++.但是道理都是想通的.

因为重复运行这个代码局部数组的地址总是不变的,我的是0x6afed0. 可以通过

printf("%x",a); //a为数组名
来获得数组名,用c++的地址转换将数组首地址赋值给指针sp,然后通过sp操作改变数组第一位的值.以此来解释未初始化的数组的值随机的来源.我们从最终结果可以看出来.内存空间中这个地址当时的值是什么.因为未初始化,所以显示的值就是什么.

#include <stdio.h>
#include

void test();
int main()
{
int* sp=reinterpret_cast<int *>(0x6afed0);
*sp = 168;
test();
*sp = 113;
test();
}

void test()
{
int a[5];
for(int i=0;i<5;i++){
printf("%d “,a[i]);
}
printf(”\n");
for(int i=0;i<5;i++){
a[i] =i;
}
for(int i=0;i<5;i++){
printf("%d “,a[i]);
}
printf(”\n");
}

//输出结果
168 7012032 7012088 7012300 1981401632
0 1 2 3 4
113 1 2 3 4
0 1 2 3 4

C语言初始化数组有以下几种常见方法: ### 声明时使用初始化列表 可以在声明数组时,使用大括号 `{}` 来初始化数组元素。例如: ```c // 初始化一维数组 int arr1[5] = {1, 2, 3, 4, 5}; // 初始化二维数组 int arr2[2][3] = { {1, 2, 3}, {4, 5, 6} }; ``` 如果初始化列表中的元素个数少于数组的大小,剩余的元素会被自动初始化0。例如: ```c int arr3[5] = {1, 2}; // 此时 arr3 为 {1, 2, 0, 0, 0} ``` ### 使用 `{0}` 初始化为全 0 对于字符数组等,可以在声明时使用 `{0}` 将数组所有元素初始化0。例如: ```c #define ARRAY_SIZE_MAX (1*1024*1024) void function1() { char array[ARRAY_SIZE_MAX] = {0}; // 声明时使用{0}初始化为全0 } ``` ### 使用 `memset` 函数 `memset` 函数可以将数组的每个字节设置为指定的,通常用于将数组初始化0。例如: ```c #include <string.h> #define ARRAY_SIZE_MAX (1*1024*1024) void function2() { char array[ARRAY_SIZE_MAX]; memset(array, 0, ARRAY_SIZE_MAX); // 使用memset方法 } ``` 需要注意的是,`memset` 是按字节操作的,对于非字符类型的数组,如果要初始化为非 0 ,可能会得到符合预期的结果。 ### 使用 `for` 循环赋 通过 `for` 循环遍历数组的每个元素,逐个赋。例如: ```c #define ARRAY_SIZE_MAX (1*1024*1024) void function3() { int i = 0; char array[ARRAY_SIZE_MAX]; for (i = 0; i < ARRAY_SIZE_MAX; i++) { // for循环赋 array[i] = 0; } } ``` ### 随机自动生成元素数组大小 可以结合 `rand` 函数随机生成数组的大小和元素。例如: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { srand((unsigned int)time(NULL)); int row = rand() % 9 + 1; int col = rand() % 9 + 1; int arr[12][12]; for (int i = 0; i < row; i++) { col = rand() % 9 + 1; for (int j = 0; j < col; j++) { arr[i][j] = rand() % 99 + 1; printf("%2d ", arr[i][j]); } printf("\n"); } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值