【参考课程:B站 BV1Vm4y1r7jY】
目录
1.数据类型
C语言基本内置数据类型
类型 | 占存储空间大小 | |
---|---|---|
char | 字符型 | 1 byte |
short | 短整型 | 2 byte |
int | 整型 | 4 byte |
long | 长整型 | 32位为4 byte,64位为8 byte //规定sizeof(long)>=sizeof(int) |
long long | 更长的整型(C99语法引入) | 8 byte |
float | 单精度浮点数 | 4 byte |
double | 双精度浮点数 | 8 byte |
类型的意义:
- 使用这个类型开辟内存空间的大小(大小决定使用范围)
- 决定看待内存空间的视角
类型的基本归类
整型家族
取值范围在<limits.h>中定义
unsigned -无符号,表示正数。二进制内存中无符号位
signed -有符号。二进制内存中最高位为符号位 //0-正 1-复
char //字符的本质是ASCII码值,是整型,所以划分到整型家族
unsigned char
signed char
//char是等价于unsigned char还是signed char,C标准未定义,取决于编译器
short
unsigned short [int]
signed short [int]
int
unsigned int
signed int //int <==> signed int 有符号的int
long
unsigned long [int]
signed long [int] //long <==> signed long
long long
unsigned long long [int]
signed long long [int] //long long <==> signed long long
浮点型家族
float //精度低,存储数值范围较小
double //精度高,存储数值范围更大
空类型
void //通常用于函数的返回类型、函数的参数、指针类型
E.g.
//第一个void:函数无返回值 //第二个void:函数不需要传参 void test(void) { }
指针类型
int*
char*
float*
void*
构造类型 //自定义类型
//数组类型
int arr1[5] →其数组类型为:int [5]
char ch[2] → char [2]
struct //结构体类型
enum //枚举类型
union //联合类型
2.整型在内存中的存储
//一个变量的创建--在内存中开辟空间 空间的大小--根据不同的类型决定的
⭐为什么在计算机系统中数值一律用补码来表示和存储?
使用补码可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(CPU只有加法器);此外,补码与反码相互转换,其运算过程是相同的,不需要额外的硬件电路
大小端
大端存储:把一个数的低位字节序的内容存放到高地址处,高位字节序的内容存放在低地址处。
//从高地址开始存
小端存储:把一个数的低位字节序的内容存放到低地址处,高位字节序的内容存放在高地址处。
//从低地址开始存
//在计算机系统中,内存以字节为单位的,每个地址单元都对应着一个字节
E.g.判断大小端
#include<stdio.h> int chekDXD() { int a = 1;//a为整型,占4个字节 //00000000000000000000000000000001 //0x 0 0 0 0 0 0 0 1 char* pa = (char*)&a; //取a的第一个字节的地址 //使用强制类型转换操作符 return *pa; //解引用→取地址上储存的数值 } //返回1-小端,返回0-大端 int main() { if (chekDXD()) //*pa==1→chekDXD为真 printf("小端存储");//01 00 00 00 else //*pa==0→chekDXD为假 printf("大端存储");//00 00 00 01 return 0; }
//使用强制类型转换操作符
3.浮点型在内存中的存储
常见浮点数:
1E10 (即1.0×10¹⁰) 3.14159 ……
浮点数家族:
float
double
long double //C99定义
浮点数表示的范围:在<float.h> 中定义
※浮点型的存储方式与整型不同
E.g.
#include<stdio.h> int main() { int n = 9; /*以整型形式放入*/ float* pf = (float*)&n; printf("%d\n", n); //9 *以整型形式取出* printf("%f\n", n); //0.000000 *以浮点数形式取出* printf("%f\n", *pf); //0.000000 *以浮点数形式取出* *pf = 9.0; /*以浮点数形式放入*/ printf("%d\n", n); //1091567616 *以整型形式取出* printf("%f\n", *pf); //9.000000 *以浮点数形式取出* return 0; }
浮点数储存规则
放入
根据国际标准IEEE 754规定,任意一个二进制浮点数V可以表示成下面的形式:
*IEEE电气和电子工程协会
表示符号位,当
,
为正数;当
,
为负数
表示有效数字,
表示指数位
⭐浮点数储存模型:
为一个无符号整数(unsigned int),但由于科学计数法中的
是可以为负数的
∴IEEE 754规定,存入内存的内存值等于真实值
加上一个中间数:
- 对于单精度浮点数的
(8bit):
//
- 对于双精度浮点数的
(11bit):
//
- 对于单精度浮点数的
:由于
,即
总能写成
的形式(
表示小数部分)
∴IEEE 754规定,在计算机内部保存M时,只保存小数位
E.g.
int main() { float f = 5.5f; //5.5 //101.1 //1.011*2^2 //S=0 E=2 M=1.011 //0 2+127=129 011 //0 10000001 01100000000000000000000 //M-小数点后的数-空位补零在后面补 //0100 0000 1011 0000 0000 0000 0000 0000 //4 0 b 0 0 0 0 0 //0x40 b0 00 00 return 0; }
//小端储存
取出
在IEEE 754标准中,对于单精度浮点数(32bit),指数部分的存储范围是-126到+127,其中-127和+128被保留作为特殊值使用 //[双精度 64bit / -1022 到 +1023 / -1023 和 +1024 保留作为特殊值]
不全为0或不全为1:
存入的逆向操作
全为0:
部分不再在小数点前补1,而是补0(
)表示非常接近于0的极小值
//64bit:
//当也全为0时表示0
全为1:
- 如果
也全为0,则该浮点数表示正无穷大(+∞)或负无穷大(-∞),具体取决于
。这种情况出现在数值溢出的情况下
- 如果尾数部分
不全为0,则该浮点数表示NaN(Not a Number)。NaN用于表示无效的操作或运算结果,比如0除以0、无法确定的数学运算等。NaN值可以有多种具体形式,其中一种就是E全为1且尾数部分不全为0的情况
- 如果
※示例详解
#include<stdio.h> int main() {/*整型存入*/ int n = 9; //00000000000000000000000000001001 float* pf = (float*)&n; /*整型取出*/ printf("%d\n", n); //9 /*[单精度]浮点型取出*/ //0 00000000 00000000000000000001001 //E全为0,M整数位补0 //(-1)^0*0.00000000000000000001001*2^(-126) printf("%f\n", n); //0.000000 printf("%f\n", *pf); //0.000000 /*[单精度]浮点型存入*/ *pf = 9.0; //1001.0 //1.001*2^3 //0 10000010 00100000000000000000000 /*整型取出*/ //01000001000100000000000000000000→正数,补码==原码 printf("%d\n", n); //1091567616 /*[单精度]浮点型取出*/ printf("%f\n", *pf); //9.000000 return 0; }