关于数组可能所有人都很熟悉,但是这里我想说一下我对这个数组的使用过程中发现的问题:
在函数内定义一个数组,不初始化,数组的值不确定
这个故事告诉我们在函数体内定义的变量都是在栈里的,如果不初始化那么它一定是前面使用过后的垃圾值。
int main(void)
{
UINT8 Array[10];
return 0;
}
内存状态如下图:
好,那知道了不初始化有问题,那接下来咱们对数组进行初始化,怎么写呢,有几种方法,
首先我先写一种最方便最常用的,初始化成全0
int main(void)
{
UINT8 Array[10] = {0};
return 0;
}
这时候看内存:
没毛病,全是0了,这么写没问题。
那我换一种写法,用memset函数来对数组初始化:
int main(void)
{
UINT8 Array[10];
memset(Array, 0x00, sizeof (UINT8) * 10);
return 0;
}
看内存:
也没问题。
当然了,这是两种常用的写法,第一种比较简单,第二种看起来比较高级。
那我还想再试试其它的写法会是什么样的,比如我这样写:只写括号不写值会怎么样?
int main(void)
{
UINT8 Array[10] = {};
return 0;
}
猜一下?
优秀,这样写也没问题,也能初始化成功:
那我现在不想初始化成0了,我想要初始化成全是1,怎么办?来我们试一下:
首先用第一种方法:
int main(void)
{
UINT8 Array[10] = {1};
return 0;
}
凉凉,只有第一个元素是1,其它全是0:
用第二种方法试一下:
int main(void)
{
UINT8 Array[10] = {0};
memset(Array, 0x01, sizeof (UINT8) * 10);
return 0;
}
优秀优秀,正是我所期望的。
所以这个故事告诉我们想要给数组初始化成全是1,不能用第一种方法。
那我又想了,要是换成枚举,会怎么样,试一下?
typedef enum
{
VALUE_0XAA = 0xaa
}VALUE;
int main(void)
{
VALUE Array[10] = {VALUE_0XAA};
return 0;
}
这个就很有意思了,你猜会怎么样?来让我们看看内存:
嗯,,,并没有如我所想,果然这样初始化还是不行,枚举也不例外。
好吧,这个测试没白做,给很久以前写过的代码找到了一个新的bug,,,
本来我一直以为使用枚举会全初始化成对应枚举的,然而事实如此残忍,准备好提变更吧。。。
那又来了新的问题了,我到底应该如何初始化呢?在使用枚举的情况下,试一下第二种方法:
我这样写:看起来没毛病哈,
typedef enum
{
VALUE_0XAA = 0xaa
}VALUE;
int main(void)
{
VALUE Array[10];
memset(Array, VALUE_0XAA, sizeof (VALUE) * 10);
return 0;
}
然而,,,什么情况?这是个啥子嘛?
难道是用这个sizeof枚举用的不对?
那换成UINT8试一下?
typedef enum
{
VALUE_0XAA = 0xaa
}VALUE;
int main(void)
{
VALUE Array[10];
memset(Array, VALUE_0XAA, sizeof (UINT8) * 10);
return 0;
}
这是啥子嘛,,,还是不对啊,,,开始崩溃,,,
那这个应该怎么玩,,,再试试这样,
typedef enum
{
VALUE_0XAA = 0xaa
}VALUE;
int main(void)
{
UINT8 Array[10];
memset(Array, VALUE_0XAA, sizeof (UINT8) * 10);
return 0;
}
终于回归正常了,这个故事告诉我不要随便使用枚举类型的数组,,,
故事还没结束 ,我们继续玩,这次不用UINT8类型了,我用两个字节的UINT16试一下:
int main(void)
{
UINT16 Array[10];
memset(Array, 0x01, sizeof (UINT16) * 10);
return 0;
}
猜一下会怎么样:优秀,果然不出我所料,又是和我想的不一样了,
嗯,让老衲想想,257是什么鬼,,,
问了一下计算器,0x0101,优秀,破案了,memset操作的是1个字节吧?
就是因为memset操作的是1 个字节,导致这对这个数组赋值的时候每个字节都赋值成了0x01,才这样的。
天才如我,嘿嘿嘿。
那我就想把它初始化成0x01怎么办,这样加俩0再试试?
int main(void)
{
UINT16 Array[10];
memset(Array, 0x0001, sizeof (UINT16) * 10);
return 0;
}
凉凉,没的用啊,还是0x0101哇,这可咋整,,,
难道是因为我memset粘多了?减少一下最后一个值试一下?
int main(void)
{
UINT16 Array[10];
memset(Array, 0x0001, 10);
return 0;
}
我了个去,怎么这么难啊?又回到原点了,这样做相当于有一部分直接就没初始化啊。
凉凉,最后还是拿它没办法,只好用最笨的办法,先初始化成0,然后写个循环依次赋值了。
明天我再问问大佬有没有什么好办法吧。