【C】940/bit2-1数据的储存

本文详细介绍了C语言中的基本数据类型,包括整型、浮点型、空类型和指针类型,以及它们在内存中的存储机制,如大小端和浮点数的IEEE754存储规则。特别关注了整型和浮点型的存储方式,以及为何使用补码表示法。
摘要由CSDN通过智能技术生成

【参考课程:B站  BV1Vm4y1r7jY】

目录

1.数据类型

C语言基本内置数据类型

类型的基本归类

整型家族

浮点型家族

空类型

指针类型

构造类型 //自定义类型

2.整型在内存中的存储

大小端

3.浮点型在内存中的存储

※浮点型的存储方式与整型不同

浮点数储存规则

放入

取出

※示例详解


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

类型的意义:

  1. 使用这个类型开辟内存空间的大小(大小决定使用范围
  2. 决定看待内存空间的视角

类型的基本归类

整型家族

取值范围在<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电气和电子工程协会

  • V=(-1)^S\cdot M\cdot 2^E
  • (-1)^s表示符号位,当S=0V为正数;当S=1V为负数
  • M表示有效数字,1\leq M< 2
  • 2^E表示指数位

浮点数储存模型:

  • E为一个无符号整数(unsigned int),但由于科学计数法中的E是可以为负数的
    ∴IEEE 754规定,存入内存的内存值E_{store}等于真实值E_{real}加上一个中间数
    • 对于单精度浮点数的E(8bit):E_{real}+127=E_{store}       // 2^8/2-1=127
    • 对于双精度浮点数的E(11bit):E_{real}+1023=E_{store}    //2^{11}/2-1=1023
  • M:由于1\leq M< 2,即M总能写成1.xxxxx的形式(xxxxx表示小数部分)
    ∴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 保留作为特殊值]

  • E不全为0或不全为1
    存入的逆向操作

     
  • E全为0
    M部分不再在小数点前补1,而是补0(0.xxxxx)表示非常接近于0的极小值
    E_{real}=1-127=-126      //64bit:E=-1022

    //当M也全为0时表示0
     
  • E全为1
    • 如果M也全为0,则该浮点数表示正无穷大(+∞)或负无穷大(-∞),具体取决于S。这种情况出现在数值溢出的情况下
    • 如果尾数部分M不全为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;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值