0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

字符型、指针型等变量等该如何初始化

玩转嵌入式 来源:玩转嵌入式 2024-03-18 11:02 次阅读

在敲代码的时候,我们会给变量一个初始值,以防止因为编译器的原因造成变量初始值的不确定性。

对于数值类型的变量往往初始化为0,但对于其他类型的变量,如字符型、指针型等变量等该如何初始化呢?

数值类变量初始化

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

1int inum = 0;

2float fnum = 0.00f;

3double dnum = 0.00;

字符型变量初始化

字符型变量也可在定义的同时进行初始化,一般初始化为‘�’。

1char ch = ‘�’;

字符串初始化

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

方法一:使用空的字符串“”。

char str[10] = “”;

方法二:使用memset。

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

方法三:写一个循环。

char str[10]; for(int i = 0; i 《 10; i++) { str[i] = ‘�’; } 这里比较推荐的是第二种初始化方法。也即使用memset进行初始化。

很多人对memset这个函数一知半解,只知道它可以初始化很多数据类型的变量,却不知道其原理是什么样的,这里做一下简要的说明:memset是按照字节进行填充的。 先看下面的一段代码:

int num; memset(&num, 0, sizeof(int)); printf(“step1=%d ”, num); memset(&num, 1, sizeof(int)); printf(“step2=%d ”, 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函数本身并不具有初始化的功能,而是一个单纯的按字节填充函数,只是人们在使用的过程中,扩展出了初始化的作用。

字符串初始化有一个小窍门,我们知道字符串本质上是字符数组,因此它具有两个特性,

字符串在内存里是连续的,

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

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 ”,p); } else { printf(“Not Enough Memory! ”); } 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

    文章

    551

    浏览量

    20123
  • 编译器
    +关注

    关注

    1

    文章

    1577

    浏览量

    48614
  • 变量
    +关注

    关注

    0

    文章

    595

    浏览量

    28112

原文标题:初始化,原来这么多讲究,你搞懂了吗?

文章出处:【微信号:玩转嵌入式,微信公众号:玩转嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    字符型、指针型等变量该如何初始化

    在敲代码的时候,我们会给变量一个初始值,以防止因为编译器的原因造成变量初始值的不确定性。对于数值类型的变量往往
    发表于 09-23 11:50 1956次阅读

    功能全局变量的实现

    有点懵。我比较模糊的几个问题是1)我如何知道每个移位寄存器中保存的到底是什么类型的数据,因为他们都为初始化,所以有点疑惑2)我们如何使用为初始化的移位寄存器来实现功能全局
    发表于 09-07 15:52

    请问这样操作指针初始化不对?

    int a=20b=5;  /* 定义两个整型变量ab并初始化 */ int *pa=&a; /* 将变量a的地址赋给指针变量pa */不
    发表于 05-09 07:56

    【设计技巧】指针的使用注意事项:空指针指针赋值、void *指针

    必须是固定的,指针是什么类型,就要赋什么类型的地址值,初始化的方式 基本有以下几种: ① 直接将相同类型变量赋值,比如 int *p = &a;其他类型变量也是一样的,前提是a是确定
    发表于 08-20 08:30

    请问CC3200为什么从有些初始化过的的全局变量在watch Expressions中看到的全是点呢?

    ;.",我改成用a,b,c字符初始化就能在watch Expressions中显示出来,怎么回事,难道只能发送字符么?为何没法定义byte类型的
    发表于 06-12 10:43

    【原创】看完这篇,轻松弄懂STM32 C语言变量的定义和初始化

    `作者:张角老师(张飞实战电子高级工程师)我们今天探讨C语言变量的定义和初始化。那么我们首先要明确三个问题。第一,我们要明白什么是变量,或者为什么C语言一定要有变量;第二个在C语言中如
    发表于 07-19 11:40

    【原创分享】变量初始化技巧

    由于在嵌入式系统中必须考虑程序规模的问题,因此,对程序中的变量初始化也需要进行慎重的考虑。在C语言中,基本数据结构(字符、整型)的初始化
    发表于 09-08 15:28

    char字符基本含义

    时,既不是无符号,也不是有符号。char字符基本含义: 字符数据类型(字节大小为1)eg: ‘a’, ‘b’, '\n’数据类型的本质: 整型数据eg: ‘0’ == 48 ==
    发表于 11-05 08:14

    单片机指针变量的相关资料分享

    单片机C语言变量分别有char,int,long,float,它们分别占用内存为1个单
    发表于 11-30 08:05

    变量初始化的基本原则

    一、变量初始化变量初始化的基本原则为:可综合代码中完成内部变量初始化,Testbench中完成
    发表于 01-19 07:07

    你知道C之变量初始化的重要性?

    C之变量初始化的重要性
    发表于 05-15 16:46 779次阅读
    你知道C之<b class='flag-5'>变量</b><b class='flag-5'>初始化</b>的重要性?

    在51平台下初始化文件的引入导致全局变量无法初始化的问题如何解决

    本文档的主要内容详细介绍的是在51平台下初始化文件的引入导致全局变量无法初始化的问题如何解决。
    发表于 08-20 17:31 0次下载
    在51平台下<b class='flag-5'>初始化</b>文件的引入导致全局<b class='flag-5'>变量</b>无法<b class='flag-5'>初始化</b>的问题如何解决

    使用51单片机进行有关变量初始化问题资料讲解

    如果定义一个变量,不对这个变量进行初始化,其变量默认初值为0。虽然大部分正确,但也是在一定条件下,即所有程序中所有变量占用的字节之和要小于1
    发表于 08-13 17:32 0次下载
    使用51单片机进行有关<b class='flag-5'>变量</b>及<b class='flag-5'>初始化</b>问题资料讲解

    dart语言的变量声明与初始化

    变量是每一们语言的基础,在Dart中所有变量都是对象,并且都有一个初始化的值null。
    的头像 发表于 12-08 16:47 954次阅读

    C语言编程时,各种类型的变量该如何初始化

    C语言编程时,各种类型的变量该如何初始化? 在C语言中,每个变量都需要在使用之前进行初始化初始化是为
    的头像 发表于 12-07 13:53 582次阅读