在敲代码的时候,我们会给变量一个初始值,以防止因为编译器的原因造成变量初始值的不确定性。
对于数值类型的变量往往初始化为0,但对于其他类型的变量,如字符型、指针型等变量等该如何初始化呢?
0
。1int inum = 0;
2float fnum = 0.00f;
3double dnum = 0.00;
'\0'
。1char ch = '\0';
'\0'
。方法一:使用空的字符串 ""
。
char str[10] = "";
方法二:使用 memset
。
char str[10];
memset(str, 0, sizeof(str));
方法三:写一个循环。
char str[10];
for(int i = 0; i < 10; i++)
{
str[i] = '\0';
}
memset
进行初始化。很多人对 memset
这个函数一知半解,只知道它可以初始化很多数据类型的变量,却不知道其原理是什么样的,这里做一下简要的说明:memset
是按照字节进行填充的。
先看下面的一段代码:
int num;
memset(&num, 0, sizeof(int));
printf("step1=%d\n", num);
memset(&num, 1, sizeof(int));
printf("step2=%d\n", num);
在讨论之前,我们先看一下运行结果
chenyc@DESKTOP-IU8FEL6:~/src$ gcc -o memset memset.c -g
chenyc@DESKTOP-IU8FEL6:~/src$ ./memset
step1 = 0
step2 = 16843009
chenyc@DESKTOP-IU8FEL6:~/src$
看到这个运行结果,是不是和你想象中的不一样呢? step1 = 0
相信大家都好理解,可step2 = 16843009
很多人就不能理解了。按照一般的惯性思维,不是应该= 1
才对么?
这就是我要说的,memset是按照字节进行填充的。
我们知道,int
型是4个字节(每个字节有8位),按二进制表示出来就应该是:
00000000 00000000 00000000 00000000
按照按字节填充的原则,step1 的结果就是将4个字节全部填充0,所以得到的结果仍然是0:
00000000 00000000 00000000 00000000
而 step2 则是将每个字节都填充为1 (注意是每个字节,而不是每个byte位) ,所以相对应的结果就应该是:
00000001 00000001 00000001 00000001
大家可以自己将上面那个二进制数转换成十进制看看,看看是不是 16843009
。
所以严格来说,memset函数本身并不具有初始化的功能,而是一个单纯的按字节填充函数,只是人们在使用的过程中,扩展出了初始化的作用。
'\0'
结束。char year[4+1];
memset(year, 0, sizeof(year));
strcpy(year,"2018");
NULL
。int *pnum = NULL;
int num = 0;
pnum = #
NULL
后,没有给该指针重新分配内存,则会出现难以预料的错误(最最常见的就是操作空指针引起的段错误)。malloc
、calloc
等函数申请过动态内存,在使用完后需要及时释放,一般释放掉动态内存后要及时将指针置空,这也是很多人容易忽略的。char *p = NULL;
p=(char *)malloc(100);
if(NULL == p)
{
printf("Memory Allocated at: %x\n",p);
}
else
{
printf("Not Enough Memory!\n");
}
free(p);
p = NULL; //这一行给指针置空必不可少,否则很可能后面操作了这个野指针而不自知,从而导致出现严重的问题
memset
来对该指针进行初始化:void fun(char *pstr)
{
memset(pstr, 0, sizeof(pstr));
...
}
memset
来进行初始化,指针首先保存的是一个4字节的地址,所以sizeof(pstr)
永远只能 = 4
,这样的初始化就毫无意义。memset
的方式。typedef struct student
{
int id;
char name[20];
char sex;
}STU;
STU stu1;
memset((char *)&stu1, 0, sizeof(stu1));
memset
的第三个参数,一般来说,传入数据类型和变量名效果是一样的,上例中,下面写法是等价的效果:memset((char *)&stu1, 0, sizeof(STU));
STU stus[10];
memset((char *)&stus, 0, sizeof(stus)); //正确,数组本身在内存里就是连续的,sizeof取出的就是数组的字节长度
memset((char *)&stus, 0, sizeof(STU)); //错误,只会初始化第一个STU结构体,后面还有9个STU元素并未初始化
memset((char *)&stus, 0, sizeof(STU)*10); //正确,效果与第一个是一样的
memset
的第二个参数写成以下形式:memset((char *)&stu1, 0x00, sizeof(stu1));
memset
是按字节进行填充的,就知道这样写也是正确的,完全没有问题。1.STM32U5,意法半导体新打造的超低功耗MCU旗舰版
2.【例说Arm-2D界面设计】从不规则图标的显示说起
3.STM8CubeMX和STM32CubeMX功能一样吗?
4.这九种情况下的单片机项目尽量不要接~
5.偷偷把室友的STM32换成了GD32后。。。
6.剖开苹果A15芯片,看看die的布局!
免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。