【C语言】数据在内存中的存储

发布于:2022-12-30 ⋅ 阅读:(450) ⋅ 点赞:(0)

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(取数据)

  1. E不为全0或全1

E的计算值减去中间数字,得到真实值,同时将M前的1.补上。

  1. E为全0

说明E的真实值为-127或-1023,是一个无限接近于0的数字。此时有效数字M不在加上1.,而是直接还原为(-1)^s * 0.xxxx * 2^-126(-1023)的小数。

  1. E为全1

说明E的真实值为128或1024,是一个正负无穷大的数字


网站公告

今日签到

点亮在社区的每一天
去签到