1.C语言的类型
类型决定了这个类型开辟内存空间的大小
1.1内置类型
(在内存中默认以有符号数的形式存储)
整型家族:
char
unsigned char
signed char //8个比特位中,最高位为符号位
short
unsigned short [int] //[ ]表示可以省略
signed short [int]
int //在内存中以补码的类型存储
unsigned int
signed int
long
unsigned long [int]
signed long [int]
浮点型家族
float
double
1.2自定义类型(构造类型)
数组类型
结构体类型 struct
枚举类型 enum
联合类型 union
1.3指针类型
int* pi
char* pc
float* pf
void* pv //无具体类型的指针
tip1:指针类型决定了解引用操作符能访问几个字节
tip2:指针类型决定了指针+1、-1操作时,加(减)几个字节
1.4空类型
void表示类型(无类型)
2.整型在内存中的存储(补码)(小端模式)
计算机中的有符号数(整型)有三种表示方式:原码,反码,补码
三种表示方法均有符号位和数值位两部分,符号位用0表示“正”,用1表示“负”
2.1整型
1.有符号数 正数:原码、反码、补码相同
负数:原码、反码、补码不同
2.无符号数 原码、反码、补码相同
//整型存储到内存中的是补码,所以移位操作的也是补码
//-1的原码、反码、补码
//1000 0000 0000 0000 0000 0000 0000 0001-原码 最高位为符号位,其余位置按权重分配
//1111 1111 1111 1111 1111 1111 1111 1110-反码 符号位不变,其余位置取反
//1111 1111 1111 1111 1111 1111 1111 1111-补码 反码+1
2.1.1有符号数、无符号数详解
以char类型为例
有符号数
无符号数
2.2内存
每一个字节在内存中是倒着存进去,倒着取出来的
以大端存储模式为例:
int a = 0x11223345
在内存中从低地址到高地址是45 33 22 11(int是4字节,32位)
2.3大小端存储模式
大端(存储)模式:数据的低位保存在内存的高地址,数据的高位保存在内存的低地址中
小端(存储)模式:数据的低位保存在内存的低地址,数据的高位保存在内存的高地址中
(地址:右边是高地址 数据:左边是高位)
2.3.1判断系统的数据存储模式(代码实现)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//判断系统是大端存储还是小端存储
//判断函数ver.1
//int check_sys()
//{
// int a = 1;
// char* p = (char*) &a;
// if (*p == 1)
// return 1;
// else
// return 0;
//}
//判断函数ver.2
//int check_sys()
//{
// int a = 1;
// char* p = (char*) &a;
// return *p; //返回1为小端,返回0为大端
//}
//判断函数ver.3
int check_sys()
{
int a = 1;
return *(char*) &a;
}
int main()
{
int i = 1;
int ret = check_sys();
if (ret == 1)
printf("系统为小端存储");
else
printf("系统为大端存储");
return 0;
}
3.浮点型在内存中的存储
IEEE 754对浮点数的规定
任何一个浮点数类型的数据,要将十进制转化成二进制,再用科学计数法的形式表示,即将一个数字表示为 (-1)^s * M * 2^E
(-1)^s 为符号位,s=0表示正数,s=1表示负数
M 表示有效数字,该数字总是大于等于1,小于2
2^E 表示指数位
举例来说:
十进制的5.0 ->二进制101.0 ->科学计数法(-1)^0 * 1.01 * 2^2 -> s=0 M=1.01 E=2
十进制的-0.5->二进制-0.1 ->科学计数法(-1)^1 * 1.0 * 2^-1 -> s=1 M=1.0 E=-1
对于float(32位)的浮点数,最高1位是符号位S,接着8位是指数位E,剩下的23位为有效数字M
对于double(64位)的浮点数,最高1位是符号位S,接着11位是指数位E,剩下的52位为有效数字M
特别规定:
有效数字M
由于有效数字总是可以写成1.xxxx的形式,因此默认将第一位的1去除,这样就可以节省一位有效数字
指数E(存数据)
由上述例子可知,使用科学计数法,指数E是可能出现负数的,但是我们又规定E为无符号数(即不能表示负数),所以IEEE 754规定:存入内存时E的真实值必须再加上一个中间数字。对于float类型,E位8位,所以中间值为127;对于double类型,E为11位,所以中间值为1023。
例如float类型的2^10,E为10,再内存中要保存为137(10+127)
指数E(取数据)
- E不为全0或全1
E的计算值减去中间数字,得到真实值,同时将M前的1.补上。
- E为全0
说明E的真实值为-127或-1023,是一个无限接近于0的数字。此时有效数字M不在加上1.,而是直接还原为(-1)^s * 0.xxxx * 2^-126(-1023)的小数。
- E为全1
说明E的真实值为128或1024,是一个正负无穷大的数字