C语言各种变量的初始化
数值类变量初始化
整型、浮点型的变量可以在定义的同时进行初始化,一般都初始化为0
。
int inum = 0;float fnum = 0.00f;double dnum = 0.00;
- 1
- 2
- 3
字符型变量初始化
字符型变量也可在定义的同时进行初始化,一般初始化为'\0'
。
char ch = '\0';
- 1
字符串初始化
字符串初始化的方法比较多,我这里简单介绍三种,因为字符串本质上是由一个个字符组成的字符数组,所以其初始化的最终目的,就是将字符数组里面的一个个字符都初始化为'\0'
。
方法一:使用空的字符串
""
。
char str[10] = "";
- 1
方法二:使用
memset
。
char str[10];
memset(str, 0, sizeof(str));
- 1
- 2
方法三:写一个循环。
char str[10];
for(int i = 0; i < 10; i++)
{str[i] = '\0';
}
- 1
- 2
- 3
- 4
- 5
这里比较推荐的是第二种初始化方法。也即使用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);
- 1
- 2
- 3
- 4
- 5
在讨论之前,我们先看一下运行结果
chenyc@DESKTOP-IU8FEL6:~/src$ gcc -o memset memset.c -g
chenyc@DESKTOP-IU8FEL6:~/src$ ./memset
step1 = 0
step2 = 16843009
chenyc@DESKTOP-IU8FEL6:~/src$
- 1
- 2
- 3
- 4
- 5
看到这个运行结果,是不是和你想象中的不一样呢?
step1 = 0
相信大家都好理解,可step2 = 16843009
很多人就不能理解了。按照一般的惯性思维,不是应该= 1
才对么?
这就是我要说的,memset是按照字节进行填充的。
我们知道,int
型是4个字节(每个字节有8位),按二进制表示出来就应该是:
00000000 00000000 00000000 00000000
- 1
按照按字节填充的原则,step1 的结果就是将4个字节全部填充0,所以得到的结果仍然是0:
00000000 00000000 00000000 00000000
- 1
而 step2 则是将每个字节都填充为1 (注意是每个字节,而不是每个byte位) ,所以相对应的结果就应该是:
00000001 00000001 00000001 00000001
- 1
大家可以自己将上面那个二进制数转换成十进制看看,看看是不是
16843009
。
所以严格来说,memset函数本身并不具有初始化的功能,而是一个单纯的按字节填充函数,只是人们在使用的过程中,扩展出了初始化的作用。
字符串初始化有一个小窍门,我们知道字符串本质上是字符数组,因此它具有两个特性,
- 字符串在内存里是连续的,
- 字符串遇
'\0'
结束。
所以我们在初始化的时候,总是愿意给字符串本身长度加1的长度的内存进行初始化。
char year[4+1];
memset(year, 0, sizeof(year));
strcpy(year,"2018");
- 1
- 2
- 3
指针初始化
一般来说,指针都是初始化为NULL
。
int *pnum = NULL;
int num = 0;
pnum = #
- 1
- 2
- 3
指针是个让人又爱又恨的东西,一般的整形、字符串等,初始化之后就可以直接拿来用了,可指针如果初始化为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; //这一行给指针置空必不可少,否则很可能后面操作了这个野指针而不自知,从而导致出现严重的问题
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
很多人经常会犯的一个错误,我们知道,在指针作为实参进行参数传递时,该指针就已经退化成了数组,所以很多人就想到用memset
来对该指针进行初始化:
void fun(char *pstr)
{memset(pstr, 0, sizeof(pstr));...
}
- 1
- 2
- 3
- 4
- 5
这种写法是不正确的。我们姑且不管指针能不能用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));
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
关于初始化结构体的长度问题,也即memset
的第三个参数,一般来说,传入数据类型和变量名效果是一样的,上例中,下面写法是等价的效果:
memset((char *)&stu1, 0, sizeof(STU));
- 1
但是对于结构体数组的初始化,长度就需要注意一下了,还是以上例来做说明:
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); //正确,效果与第一个是一样的
- 1
- 2
- 3
- 4
有些人习惯将memset
的第二个参数写成以下形式:
memset((char *)&stu1, 0x00, sizeof(stu1));
- 1
只要理解了memset
是按字节进行填充的,就知道这样写也是正确的,完全没有问题。
C语言各种变量的初始化相关推荐
- C语言中变量未初始化的处理
实例测试1--DEV-C++环境 : #include <stdio.h> //全局整形变量 int int_var1; static int stc_int_var1; short in ...
- 【C 语言】结构体 ( 结构体类型变量初始化 | 定义变量时进行初始化 | 定义隐式结构体时声明变量并初始化 | 定义普通结构体时声明变量并初始化 )
文章目录 一.结构体类型变量初始化 1.定义变量时进行初始化 2.定义普通结构体时声明变量并初始化 3.定义隐式结构体时声明变量并初始化 二.完整代码示例 一.结构体类型变量初始化 1.定义变量时进行 ...
- c语言 静态变量 初始化,c – 静态变量初始化两次
考虑到我在编译单元中有一个静态变量,最后在静态库libA中.然后我有另一个编译单元访问这个变量,最终在一个共享库libB.so(所以libA必须链接到libB).最后,我有一个主要功能也直接从A访问静 ...
- php语言指针的初始化定义,指针变量的初始化,C语言指针变量初始化详解
本节来解决如何给一个指针变量初始化.即怎样使一个指针变量指向另一个变量. 前面章节中的某些程序实际上已经使用了,即可以用赋值语句使一个指针变量得到另一个变量的地址,从而使它指向该变量.比如: int ...
- c语言static变量初始化
<程序员面试笔试宝典>第123页,举了个例子 #include <stdio.h> void fun(int i) {static int value=i++;printf(& ...
- jstl动态取变量_C语言的变量名
变量名是用来标识某个内存块的 地址就是地址啦,如是变量名的话,用取地址运算符&就可以得到它标识的内存块的地址, 而指针变量呢,它本身也是一个变量名,只不过它标识的那块内存存放的是一个地址值 变 ...
- C 语言编程 — 变量和常量
目录 文章目录 目录 前文列表 变量与常量 变量 变量的类型 变量的声明 变量的定义 变量的初始化与赋值 常量 整型常量 浮点型常量 字符型场景 字符串常量 符号常量 前文列表 <程序编译流程与 ...
- c++ 初始化 代码 应放在那里_Go语言goroutine调度器初始化 (12)
先吐槽一下,知乎编辑器居然不支持汇编语言,代码的空格也给我弄没了,你说你把运算符两边的空格搞掉就搞掉吧,还能看,你为啥要把if, for后面的空格也搞掉啊... 本文是<Go语言调度器源代码情景 ...
- 嵌入式c语言为什么变量定义在前面,嵌入式C语言数据类型和变量详解
原标题:嵌入式C语言数据类型和变量详解 一般来讲,标准的C语言类型在嵌入式编译器中是合法的.但由于嵌入式控制器的受限环境.嵌入式c语言的变量和数据类型具有新的特征,这些特征体现在如下方面. 嵌入式C语 ...
最新文章
- 微信高级研究员解析深度学习在NLP中的发展和应用 | 公开课笔记
- oracle rac11g更换存储,11g rac更换存储
- 网易云信亮相LiveVideoStackCon2020,分享RTC中AI音频算法产品化经验
- Linux 下升级 python2 到python3
- linux-shell命令之rm(remove)【删除文件或目录】
- 操作系统:SSH协议知识介绍
- bind简单转发实验
- 云计算,巨头们的背水一战
- 《scikit-learn》使用交叉验证优化KNN参数
- 管理者和领导者的区别_见到一个领导者时如何识别
- java redis源码分析,慢谈 Redis 实现分布式锁 以及 Redisson 源码解析
- 压缩软件能否加上忽略某些目录的功能
- XX数据中心技术方案
- [ 常用工具篇 ] Esxi 安装详解
- 皮肤水分检测原理及测量电路分析
- 中国(西部)云计算中心投产,将成西部规模最大数据中心
- SQL注入(基于 tryhackme 的讲解)
- ui效果图生成html,四步制作一个高大上的iPhone效果图模版 UI呀-学UI设计网
- 数字平原maya制作写实科幻场景
- dcs程序流程图分析_常见DCS工艺流程图识别 教你正确读图
热门文章
- MCtalk教育创业者说:学吧课堂K12领域转型突围之路
- Maven学习总结(14)——Maven 多模块项目如何分工?
- Android自定义Dialog及与Activity的交互
- Nervos CKB 共识协议 NC-Max:突破 Nakamoto Consensus 吞吐量的极限
- vue.js框架原理浅析
- 诺基亚基于区块链推环境感知服务,助力智慧城市发展
- 2016/08/24 CppCon 2015 Bjarne Stroustrup “Writing Good C++14
- [备忘] Automatically reset Windows Update components
- android中的broadcastReceiver
- 如何加入IETF 如何发表自己的RFC