嵌入式中的数据初始化

news/2024/7/7 19:08:00

1. 数值类 变量初始化

整型、浮点型的变量可以在定义的同时进行初始化,一般初始化为 0.

int num = 0;
float fnum = 0.21f;
double dnum = 0.32;

2. 字符型 变量初始化

字符型变量也可在定义的同时进行初始化,一般初始化为 '\0'。

char ch = '\0';

3. 字符串初始化

字符串初始化的方法比较多,这里简单介绍三种方法,因为字符串本质上是由一个个字符组成的字符数组,所以其初始化的最终目的,就是将字符数组里面的一个个字符都初始化为'\0';

方法一:使用空的字符串"";

char str2[10] = "";

方法二:使用memset。

char str2[10];
memset(str2, 0, sizeof(str2));

方法三:写一个循环。

char str2[10];
for (int i = 0; i < 10; i++) {
    str2[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);

在讨论之前,我们先看一下运行结果

$ gcc -o memset memset.c  
$ ./memset               
step1 = 0
step2 = 16843009

看到这个运行结果,是不是和你想象的不一样呢?

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' 结束

所以我们在初始化的时候,总是愿意给字符串本身长度加1的长度的内存进行初始化。

char year[4+1];

memset(year, 0, sizeof(year));
strcpy(year, "2023");

4. 指针初始化

一般来说,指针都是初始化为 NULL。

int *pnum = NULL;
int num = 0;
pnum = &num;

指针是个让人又爱又恨的东西,一般的整型、字符串等,初始化之后就可以直接拿来用了,可指针如果初始化为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,这样的初始化就毫无意义。

5. 结构体初始化

结构体的初始化就比较简单了,基本也都是采用 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, 0, sizeof(stu1));

只要理解了 memset 是按字节进行填充的,就知道这样写也是正确的,完全没有问题。


http://lihuaxi.xjx100.cn/news/1939798.html

相关文章

快递物流怎么寄最便宜?你一定要知道的5个方法 !

家人们&#xff0c;临近年关&#xff0c;大家的钱包是不是鼓鼓的了&#xff0c;难免的亲戚朋友之间会相互寄送一些东西&#xff0c;所以最近因为需要经常寄快递物流&#xff0c;小编所以特地整理了5个我们平时个人寄快递便宜的方法攻略&#xff0c;推荐第五个&#xff0c;实用干…

大数据情况下如何保证企业数据交换安全

数据交换是指在网络或其他方式下&#xff0c;不同主体按照规定的规则和标准实现数据的共享、传输和处理的过程。大数据时代的到来使得数据交换的重要性更为凸显&#xff0c;大数据带来了海量、多样、高速、低价值密度等特点&#xff0c;也带来了更多的价值挖掘和应用场景。 保障…

Ubuntu18.04 安装 qt 5.15.2

安装qt 1.下载 在线安装包 使用国内镜像源在线安装QT(2023.3.25更新)_qt国内镜像-CSDN博客 2.安装 注意&#xff1a;我安装时 勾选 Qt Design studio 会导致报错&#xff0c;直接不勾选。 Ubuntu 18.04 安装Qt5.15.2开发环境_ubuntu安装qt5.15.2-CSDN博客 3.配置

220.【2023年华为OD机试真题(C卷)】考勤信息(滑动窗口算法-JavaPythonC++JS实现)

🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-考勤信息二.解题思路三.题解代码Python题解代码…

5.3 Android BCC环境搭建(eadb版 下)

四,BCC使用示例 这里以tcplife为例,来显示TCP会话的生命周期和吞吐量统计。 4.1 进入/bcc/tools目录 root@localhost:/bcc# cd tools/ root@localhost:/bcc/tools# ls CMakeLists.txt javacalls.sh rubystat_example.txt argdist.py javacalls_e…

电子元器件选型与实战应用—07 二极管选型与应用第2篇

文章目录 一、稳压二极管1.1 原理1.2 参数解析1.3 稳压管选型案例1.3.1 工作原理1.3.2 仿真1.3.3 限流电阻确定二、LED二极管2.1 介绍2.2 案例介绍2.2.1 问题描述2.2.2 电路设计前文推荐: 电子元器件选型与实战应用—06 二极管选型与应用第1篇</

CCNP课程实验-06-EIGRP-Trouble-Shooting

目录 实验条件网络拓朴 环境配置开始排错错误1&#xff1a;没有配置IP地址&#xff0c;IP地址宣告有误错误2&#xff1a;R3配置了与R1不同的K值报错了。错误3&#xff1a;R4上的AS号配置错&#xff0c;不是1234错误4&#xff1a;R2上配置的Key-chain的R4上配置的Key-chain不一致…

接口功能测试策略

由于平台服务器是通过接口来与客户端交互数据提供各种服务&#xff0c;因此服务器测试工作首先需要进行的是接口测试工作。测试人员需要通过服务器接口功能测试来确保接口功能实现正确&#xff0c;那么其他测试人员进行客户端与服务器结合的系统测试过程中&#xff0c;就能够排…