#1. 变量与常量
- 变量:在程序运行期间,其值可能发生变化
- 常量:在程序运行期间,其值不发生变化
#2. 变量有多种数据类型的原因:
- 现实生活中,值的类型是多样的,因此用描述程序描述现实则要求该程序语言也要有描述多样数据类型的能力。
- 不同数据类型所占内存空间不同,要用恰到好处的空间去存储对应的值,做到性价比高。
#3. C语言的数据类型
其中:
- int为基本整数类型,short、long、signed、unsigned用来修饰,如: unsigned short int和long long int;
- char用于字母和字符,也可表示较小的整数(ASKII码);
- float、double、long double表示小数;
- _Bool为布尔值(true或false);
- _Complex为复数;
- _Imaginary为虚数;
#3.1. 位、字节和字
1字节(Byte)= 8位(bit)
字(word)是设计计算机时给定的自然存储单位,取决于电脑硬件,例如:8位电脑一个字长为8位。
在C语言中,可以使用sizeof(数据类型)查看当前电脑对应数据类型所用的字节
#3.2. 整数与浮点数
浮点数的表示方法:
1. 小数,如1.2等
2. e计数法,如3.14e-8(相当于), 4.4E9(相当于
)
区别:
- 浮点数表示的范围更大
- 对于一些算术运算(如,两个很大的数相减),浮点数损失的精度更多(原因可能是第三点。)
- 浮点数不能表示区间内所有的值。浮点数通常只是实际值的近似值。(原因可能是因为小数点是按2的次方存储,而不是10,因此有些数只能根据精确度,确定一个近似数。)
#3.3. int类型
#3.3.1. 普通int类型
可以表示正整数、0、负整数。一般而言,储存一个int要占用一个机器字长。
创建int类型变量如下:
int a; // 声明变量a,但是未初始化,相当于只在内存中声明这一块是a的,但是里面具体是什么不知道
int a, b, c; // 一次性声明a,b,c三个变量,但都没有初始化
int a = 1; // 声明变量a,并初始化为1,相当于在内存中声明这一块是a的,并且里面的值是1
int a, b, c = 1; // 不要这么写,只有c得到初始化,vs2022中会报错说a,b未初始化
转换说明:%d(可以使用%d打印int类型的数据)
不同进制下的int:
- 八进制:通过添加前缀0表示;对应使用%o打印;要显示前缀0,则使用%#o打印;
- 十六进制:通过添加0x或0X表示;对应使用%x打印;要显示前缀0x或0X,则使用%#x或%#X打印;
#3.3.2. 其他int类型
- short int或short:占用的存储空间可能比int类型少,为有符号类型;对应使用%hd打印
- long int或long:占用的存储空间可能比int多,为有符号类型;对应使用%ld打印
- long long int或long long:占用的储存空间可能比long int多,至少占64位,为有符号类型;对应使用%lld打印
- unsigned int:对应使用%u打印
- 还有unsigned long int或unsigned long、unsigned int或 unsigned short、unsigned long long int或unsigned long long。;对应使用%lu、%hu、%llu打印
- 在任何有符号类型前添加signed,强调使用有符号类型的意图。
什么情况下,要用long代替int:
- 要表示的数超过了int可表示的范围时
- 处理更大的值,使用一种在所有系统上都保证至少是 32 位的类型,可提高程序可移植性。
#3.3.3. long常量 longlong常量
编译器会根据数字的大小,按int -> long -> unsigned long -> long long或unsigned long long顺序选择类型(前提是编译器能识别这些类型)
对于八进制和十六进制,按int -> unsigned int -> long -> unsigned long ->long long -> unsigned long long顺序选择类型
有时候,有些函数要求特定类型,则可在数字常量后加l或L(用L更好)表示该数按long类型存储;类似LL表long long;ull、LLU、Ull表unsigned long long。
#3.3.4. 溢出问题
一般unsigned int类型的溢出后从0开始;而有符号类型则从该类型能表示的最小的数(负数)开始;
#3.4. char类型
char为1字节的存储单元;用char处理小整数很有用。
ASCII码的范围为0~127,一共7位;
声明和初始化:
char 变量名 = '字符常量'
char 变量名 = 字符对应的ASCII码值
使用%c打印
上面的骚操作,只有在字符常量小于4个时才不会报错。
char在编译器中到底是signed char还是unsigned char,标准没定义,主要是看编译器怎么实现。
#3.4.1. 非打印字符
- 换页符(\f)把活跃位置 移至下一页的开始处;
- 回车 符(\r)把活跃位置移动到当前行的开始处;
- 水平制表符(\t)将活跃位置 移至下一个水平制表点(通常是第1个、第9个、第17个、第25个等字符位 置);
- 垂直制表符(\v)把活跃位置移至下一个垂直制表点。
转义序列字符不一定在所有的显示设备上都起作用。
最后两个是用八进制或十六进制来表示ASCII码。
#3.5. _Bool类型
占8位(1字节)存储空间;
#3.6. 浮点数类型
包括float、double以及long double。
- float:至少能表示6位有效数字,且取值范围至少是10^(-37) ~ 10^(37);一般占32位;使用%e打印;
- double:至少能表示10位有效数字,一般占64位;使用%e打印;
- long double:至少与double的精度相同;使用%Lf或%Le打印;
声明与初始化:
float 变量名 = 值;
double 变量名 = 值;
long double 变量名 = 值;
#3.6.1. 浮点型常量
形式:小数或用e表示法的数;C99:十六进制浮点常量,加前缀0x或0X,用p或P替代e或E(2的幂),例如0xa.1fp10;使用%a或%A打印;
注意:
- 编译器默认情况下浮点类型为double,可在数的后面加f或F让编译器将其看作float;可在数的后面加l或L让编译器将其看作long double;
- 可没有小数点或指数部分,如:2E5、1.68;
- 可没有小数部分或整数部分,如:3.E16、.45E-6;
#3.6.2. 上溢或下溢
上溢,则输出为inf或infinity(无穷大);
下溢,低于正常的浮点值。
#3.7. 复数和虚数
复数类型:float_Complex、double_Complex、long double_Complex
虚数类型:float_Imaginary、double_Imaginary、long double_Imaginary
如果包含complex.h头文件,则可用complex代替_Complex,用imaginary代替_Imaginary,用I代替-1的平方根。
#3.8. 构造类型(自定义类型)
包括数组、结构体、枚举、联合类型
#3.9. 指针类型
int *pi;
char *pc;
float *pf;
void *pv;
等
#3.10. 空类型
void表示空类型(无类型);
常应用于函数的返回、函数的参数、指针类型。
#4. 查询类型大小
sizeof(类型),用%zd(C99 C11)或%u %lu打印返回值
对于特定量,可以省略(),如:sizeof name,但还是建议都加上圆括号。
#5. limits.h和float.h
limits.h和float.h设定了整数类型和浮点型大小限制。
#6 类型转换
- 两种类型的运算,两个值会分别转换成两种类型的更高级别
- 类型的级别从高到低:long bouble>double>float>unsigned long long>long long>unsigned long>long>unsigned int>int。当long和int大小相同时,unsigned int比long级别高。
- 赋值表达式中,最终结果的类型取决于被赋值变量的类型,因此可能升级(promotion)也可能降级(demotion)
- 作为函数参数传递时,char、short => int,float = > double
- 类型转换出现在表达式时,char、short => int
#6.1 强制类型转换(cast)
一般,应避免自动类型转换。强制类型转换:在某个量前加上(type)
#7 总结
1. 各数据类型对应转换说明汇总:
数据类型 | 所占字节数 | 转换说明 | 备注 | |
整型 | (signed) int | 常为一个字长 | %d或%i | |
(signed) int | %o、%#o(显示八进制的前缀0) | 八进制 | ||
(signed) int | %x、%#x(显示十六进制前缀0x)或%#X(前缀的x大写,即0X) | 十六进制 | ||
(signed) short int、(signed) short | ≤1字长 | 使用前缀h,%hd、%ho、%hx等 | ||
(signed) long int、(signed) long | ≥1字长 | 使用前缀l(小写的L) | ||
(signed) long long int、(signed) long long | 至少占64bit | 使用前缀ll | ||
unsigned int | 常为一个字长 | %u | ||
unsigned short int、unsigned short | ≤1字长 | %hu | ||
unsigned long int、unsigned long | ≥1字长 | %lu | ||
unsigned long long int、unsigned long long | 至少占64bit | %llu | ||
字符型 | char | 常为1字节(8bit) | %c | |
布尔型 | _Bool | 常为一个字长 | 本质是整型 | |
浮点数类型 | float | 一般4 | %e、%a(十六进制小数) %E和%A表示浮点数的e表示法的e为E | |
double | 一般8 | |||
long double | ≥8 | %Le、%Lf、%La(十六进制小数) %LE、%LF、%LA |
2. 查看自己机器上相应数据类型的所占字节数方法:sizeof(type);用%zd(C99 C11)或%u %lu打印返回值;sizeof也可以计算变量名所占的字节数;
3. 当两种不同数据类型一起运算时,自动向级别更高的类型转换;
4. 强制类型转换:在变量前加上(type);