文章目录
一、数据类型
1.数据类型的意义
(1)让程序员更好地描述生活中的各种问题
(2)使用这个类型开辟内存空间的大小
char—1字节 short—2字节 int—4字节 long—4字节
long long—8字节 float—4字节 double—8字节
(3)提供了看待内存空间的视角
2.数据类型的分类
❤️2.1 整型
char 在内存中以ASCII的形式进行存储
unsigned(无符号的) char
signed(有符号的) char
int
unsigned int 无符号的整型
signed int 有符号的整型
short
unsigned short [int] int可以省略(unsigned short a == unsigned short int a)
signed short [int] int可以省略
long
unsigned long [int]
signed long [int]
long long
unsigned long long [int]
signed long long [int]
除了char类型,一般数据类型是默认有符号的,即 int == signed int,但是char类型要取决于编译器
❤️2.2 浮点型
float 单精度浮点数
double 双精度浮点数
❤️2.3 构造类型(自定义类型)
数组类型 int [10] char [11]
结构体类型 struct
枚举类型 enum
联合类型 union
❤️2.4 指针类型
int* pa char* pa float* pa void* pa(没有具体类型的指针)
❤️2.5 空类型
void — 空类型(无类型),可以应用于函数的返回类型,函数的参数,指针类型,如void arr(void )和void* pa
二、整型的存储
2.1 以补码的形式保存
整型数值可以由各种位进行表示,如10在二进制中是1010,八进制中是12,16进制中是A,虽然表现的形式不一样,但是都是同一个数值。
二进制主要有三种形式,即原码、反码、补码(点击看原码、补码、反码的详细介绍),电脑的数值是以原码的大小打印的,但是内存上的存储和表示是以补码进行的。
但是为什么不以原码或者反码来进行表示呢,这取决于补码有三点优势:
(1)可以把符号位和数值域统一处理
(2)可以加法、减法统一处理(CPU中只有加法处理器),如1 - 1在CPU中的运算是1 + (-1)
(3)补码和原码之间的转换方式都是"取反 + 1",不需要额外的步骤
2.2 大小端问题
首先,我们需要了解为什么会有大小端这个问题?
假设有一个整型a,已知整型是4个字节,但是一个内存单元是1个字节,这4个字节是已怎样的顺序存储进去的,是没有明确规定的,我们可以顺着放、反着放、随机放,只要这个数据方便你取和存,实际上并没有什么优劣之分。
其次,什么是大小端?
基于上面的了解,我们可以先得出,存储是以一个字节为单位的,也就是说大小端更准确的说是“大小端字节序存储”。然后大端是把高位的字节放在低地址处,低位的字节放在高地址中,小端则相反。
那么什么是低位,数学中1234这个四位数,分别有个位、十位、百位、千位,那么个位即是最低位。对应到编程中,整型10的补码是00000000 00000000 00000000 00001010,转为16进制即为00 00 00 0a,那么0a就是最低位的字节
如下图,VS2019版本所使用的是小端存储
2.3 例子解析
#include <stdio.h>
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}
答案:-1 -1 255
解析:
数值就像是一块蛋糕,本身的大小是不会改变的,而类型就像是不同尺寸的刀具,-1是整型放到char类型中,需要发生【截断】,又因为内存中储存的是补码,所以原本32bit的
11111111 11111111 11111111 11111111 截断为8bit的11111111,即a内存中存储的是8个1。
b和c与a同理,里面存的都是8个1,只不过c是无符号的char类型,最高位不是符号位。
%d的意思是“打印有符号的整数”,所以需要【整型提升】,有符号的补符号位,无符号的补0,所以a、b内部储存为11111111 11111111 11111111 11111111,所以打印的数值需要转换为原码,为-1。c内部储存为00000000 00000000 00000000 11111111,由于是无符号的,不需要转换,所以是255
四、浮点型的存储
4.1 (-1)^S * M * 2^E
根据国际标准IEEE754,任意一个二进制浮点数V可以表示成(-1)^S * M * 2^E这种形式
- (-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
- M表示有效数字,大于等于1,小于2。
- 因为都是1.XXXXX,所以储存时省略了1,只保留XXXXX,等到读取的时候再加上1,可以提高精度
- 2^E表示指数位,E是无符号整数
- E为8位:0 <= E <= 255 E为11位:0 <= E <= 2047
- 存入内存时E的真实值需要加上一个真实值(因为指数是有为负数的情况的,但是E的范围不允许),如果E为8位,需要加127,E是11位则加1023
- E在内存中的三种情况
- E不全为0或不全为1:指数E的计算值减去127或1023,得到真实值,再将有效数字M前加上第一位的1
- E为全0:指数E等于1-127或1-1023,有效数字不加上1,而是还原成0.XXXX,表示±0或一个无穷小的数
- E全为1:表示±无穷大
4.2 float 和 double 的存储模型
1.float
2.double