【C语言】变量和数据类型 | 回顾C语言003
前面我们已经见识过一个简单的完整C语言程序了,下面让我们来认识一下如何在C语言中定义变量,以及C语言中存在哪些数据类型吧!
前置知识:计算机中都是用二进制0和1来存放数据的。我们把一个二进制位称作一个比特或比特位,1字节=8比特
;
1.定义变量
基本语法如下,和我们日常语言认知中的赋值是一样的思维逻辑。只不过在编程语言中,我们定义一个变量需要告诉编译器它是什么数据类型的。这也是C/C++作为强类型语言的特性之一(变量的数据类型固定,不可以修改数据类型)
1 | 数据类型 变量名1 = 初始值; // 声明并赋值(声明并定义) |
下面给出对应的示例
1 | int a = 10; // 声明并赋值 |
2.数据类型
C语言支持的数据类型如下
2.1 整形
类型 | 存储大小 | 值范围 |
---|---|---|
char | 1 字节 | -128 到 127 或 0 到 255 |
unsigned char | 1 字节 | 0 到 255 |
signed char | 1 字节 | -128 到 127 |
int | 2 或 4 字节 | -32,768 到 32,767 或 -2,147,483,648 到 2,147,483,647 |
unsigned int | 2 或 4 字节 | 0 到 65,535 或 0 到 4,294,967,295 |
short | 2 字节 | -32,768 到 32,767 |
unsigned short | 2 字节 | 0 到 65,535 |
long | 4 或 8 字节 | -2,147,483,648 到 2,147,483,647 或 -9,223,372,036,854,775,808 到 +9,223,372,036,854,775,807 |
unsigned long | 4 或 8 字节 | 0 到 4,294,967,295 或 0 到 +18,446,744,073,709,551,616 |
long long | 8 字节 | -9,223,372,036,854,775,808 到 +9,223,372,036,854,775,807 |
unsigned long long | 8 字节 | 0 到 +18,446,744,073,709,551,616 |
上面的所有数据类型,都是整形家族的成员。
long
和long long
本质上是long int
和long long int
,写的时候可以省略int
。
在很多项目/库函数源码中,你还会看到下面两种整数类型。他们都是基础类型的一个别名。
类型 | 实际对应的类型 | 操作系统 |
---|---|---|
szie_t | unsigned int | windows 11 |
szie_t | long unsigned int | Linux (CentOS8) |
sszie_t | windows不支持 | windows 11 |
sszie_t | long | Linux (CentOS8) |
2.1.1 char也是整形
char字符类型也是整形家族的一员,其底层和整形int的存放方式是一模一样的,只不过其只占用了1个字节。
在printf函数中,我们也可以用%d
来打印char类型,最终输出的结果是char对应的数字。
在计算机底层中,会使用ASCII码表来进行数字和char字符之间的转换,将该表粘贴如下
定义字符的时候,我们需要给字符带上单引号作为标识,不能删除单引号,否则会被识别为变量名;也不能用双引号,双引号代表的是字符串。
1 | char a = 'A'; // 字符A需要带上单引号 |
2.1.2 long和int的区别
这里对int和long做一定说明:在32位操作系统上,int和long都是4个字节。
这时,你可能和初学的我会有一样的疑惑:既然存放大小一样,能存放的长度也一样,那int和long有什么区别?
这是因为不同操作系统/编译器会有不同的默认策略,在一些很古早的操作系统上,可能会出现下面的情况:
- int只有2个字节
- long是4个字节
long类型的含义,就是告知使用者,不管在什么操作系统上,其至少能达到和int一样的长度,或比int更长。这样只要我们需要的数据长度在2~4个字节之间,那就可以使用long来保证该变量一定会用4个字节来存储。避免不同平台中int的默认策略不同而导致的异常。
比如我们有一个占用了3字节的整数,在int为4字节的平台上代码能正常运行,但在int只有2字节的平台上,就无法正常运行该代码。用long就能避免这个问题
当然,如果你所编写的项目对内存占用不敏感,也可以无脑用long long
。
在64位操作系统下,int
类型是4个字节,long
和long long
都是8个字节。
2.1.3 确定长度的int类型
前文提到了:“只要我们需要的数据长度在2~4个字节之间,那就可以使用long来保证该变量一定会用4个字节来存储。”,但实际上这种需要确定长度来存放整形的时候,还有更合适的做法。
C语言在ISO C99
中引入了定长整形的数据类型名,使用这一批数据类型来代替int/long
,能确保我们的数字一定会用指定二进制位数来存放。
这一批数据类型和上文提到的szie_t/sszie_t
一样,都是在不同操作系统环境下对已有的int/long/short
的重命名,也就是说,底层会根据当前操作系统的不同,来自己帮我们重名这些带具体位数的整形类型,只要我们用了这个数据类型,那么代码不管在任何操作系统上,只要这个操作系统支持C99
标准,就一定能以符合我们预期的数据长度来存放对应的整形数字。
比如我们在需要4个字节(32位)来存放一个有符号整数数据时,可以用int32_t
来替代int/long
,这样就能从语言层面彻底确保我们的数字会用32个二进制位来存储。
更多信息可以参考博客:C语言 —— int32_t uint32_t 及size_t
2.3 浮点型
所谓浮点型,即C语言中的小数。
下表中的E代表是科学计数法,E+38 = 1038,E-38 = 10-38;
类型 | 存储大小 | 值范围 | 精度 |
---|---|---|---|
float | 4 字节 | 1.2E-38 到 3.4E+38 | 6 位有效位 |
double | 8 字节 | 2.3E-308 到 1.7E+308 | 15 位有效位 |
long double | 16 字节 | 3.4E-4932 到 1.1E+4932 | 19 位有效位 |
在库函数头文件 <float.h>
存放了浮点数的最大值和最小值的宏。这里我们采用%E
科学计数法的方式打印出浮点数float类型的最大值和最小值。
1 |
|
上述代码输出结果如下
1 | float 存储最大字节数 : 4 |
2.4 指针类型
指针类型是C/C++中比较难懂的一环,这里我们暂时只学习基础的指针变量声明。对指针的深入学习会有专门的文档。
指针的基本格式就是*
,只要在原有数据类型后加一个*
,就代表是该类型的指针。在原有的变量前面加上取地址符号&
,就代表获取该变量的地址(指针)
1 | int a = 10; |
要想使用指针来访问变量a中的数据,我们需要用到解引用,符号也是*
;
1 | int b = *ptr; // 通过解引用,获取到ptr指针指向的地址中的值,赋值给b |
执行完毕这个代码后,变量b就获取到了ptr指针指向的地址中的值,即变量a的值。
指针变量中,星号*
的个数代表指针的等级,一个*
就代表是一级指针,两个*
就代表是二级指针,依此类推。不同等级的指针具体的区别,会在指针章节再谈,本文档只是让大家认识数据类型的。
2.5 bool类型
C/C++中还有一个特殊的类型,布尔类型,即bool类型。
这个类型只有两个预定义的值,分别是false和true,聪明的你肯定已经明白它的作用了。主要就是用于函数的返回值,亦或者是用做flag标记变量,来标定真和假的。
比如:通过函数判断一个字符串是否为一个数字,是返回true,不是返回false
在C语言中使用这个变量需要引用头文件 stdbool.h
,代码示例如下
1 |
|
该变量大小为1个字节,也能算作整形家族的一员(底层其实就是一个宏,分别对应0和1两个数字)
头文件stdbool.h
非常短,这里顺带将完整的内容粘贴出来。其中出现了define和ifdef这些宏定义语法,在本站后文中都会介绍到。我们只需要关注核心:可以看到,true是0,false是1,二者就是数字罢了。
#define 名字 内容
后文出现该名字的位置,全都会被替换成内容;#define true 0
引用头文件后,后文出现的所有true都会在预编译阶段替换成0;
1 | // |
3.const关键字
在继续介绍其他数据类型之前,需要先带大家认识一下const
关键字。
这个关键字的作用是将数据类型添加常量属性,被const
关键字修饰后的属性,将具有常量属性,即不可以被修改。
1 | const int a = 10; // 常量变量,a不可以被修改 |
当我们尝试修改这个变量的时候,会报错,无法通过编译。
1 | const int a = 10; // 常量变量,a不可以被修改 |
后文将介绍数组类型和字符串类型,请继续阅读本专栏。