【零基础C语言】内存中的存储

一. 整数在内存中的存储

1.原码反码补码

在计算机中整数在内存中存储的是二进制数

二进制的存储有三种表示的方式:

  1. 原码
  2. 反码
  3. 补码

 这三种表示方式又分为符号位和数值位:

 符号位中0表示正数,1表示负数,最高位被当作符号位,其他为数值位

 如:1  和  -1    64位展示
 1:00000000000000000000000000000001

-1:10000000000000000000000000000001

原码,反码,补码解释:
 如:5
 00000000 00000000 00000000 0000101 - 原码
 01111111 11111111 11111111 1111010 - 反码
 01111111 11111111 11111111 1111011 - 补码

相互转换规则:
 原码 -> 反码 :符号位不变,其他取反。 取反 1->0 或者 0->1
 反码 -> 补码 :+1
 原码 -> 补码 :取反+1
 补码 -> 原码 :取反+1

而对于数据在内存中存储的是补码。
 

2.大小端字节序和字节判断

int main()
{
	int a = 0x11223344;
	return 0;
}

 可以看出在内存中存储的是 44 33 22 11 正好和我们的反过来了,这是什么原因呢? - vs底层使用的是小端存储

 什么是大小端?
 首先我们要明白一个数据在内存中存储是有顺序的。

大端存储:数据的低位字节保存在内存的高地址处,高位字节保存在内存的低地址处。

小端存储:数据的低位字节保存在内存的低地址处,高位字节保存在内存的高地址处。
 

 什么是低位字节,我们拿一个数值来类比一下:
 56   6->个位,所以6是低位, 5->十位所以5是高位
 0x11223344 也是如此,  44 -> 低位    11 -> 高位

 

判断当前机器是大端存储还是小端存储

int check()
{
	int i = 1;
	return (*(char*)&i); //cahr* 修饰拿到一个字节的存储
		
}

int main()
{
	int ret = check();
	if (ret == 1)
		printf("小端");
	else
		printf("大端");
	return 0;
}

 练习1

#include <stdio.h>
int main()
{
	// -1 10000000000000000000000000000001 -原码
	//    11111111111111111111111111111110 -反码
	//    11111111111111111111111111111111 -补码

	char a = -1;
	// 以%d形式打印,在vs中char是有符号类型,由于是负数,先取反+1,最后结果还是 -1

	signed char b = -1;
	// 以%d形式打印,是有符号类型,由于是负数,先取反+1,最后结果还是 -1

	unsigned char c = -1;
	// 以%d形式打印,是无符号类型为整数,补码就是原码,但由于unsigned char 范围是 0~255 ,所以打印最大255

	printf("a=%d,b=%d,c=%d", a, b, c);
	return 0;
}

 练习2

#include <stdio.h>
int main()
{
	// -128 - 10000000000000000000000010000000 -原码
	//        11111111111111111111111101111111 -反码
	//        11111111111111111111111110000000 -补码
	char a = -128;
	char b =  128;
	// %d - 有符号的十进制输出     %u - 无符号的十进制输出
	printf("%u\n", a); // a = 4,294,967,168
	printf("%u\n", b); // b = 4,294,967,168
	return 0;
}

 

练习3

#include <stdio.h>
int main()
{
	char a[1000];

	int i;

	for (i = 0; i < 1000; i++)
	{
		a[i] = -1 - i;   
	}
	// -1 -2 -3 -4 -5 .....  -127  128 127 126 .... 0  -1 -2 -3...
	printf("%d", strlen(a)); // a=225

	return 0;
}

 练习4

#include <stdio.h>
unsigned char i = 0; //char - -127~128   unsigned char - 0~255
int main()
{
	for (i = 0; i <= 255; i++)
	{
		printf("hello world\n");  //死循环
	}
	return 0;
}

#include <stdio.h>
int main()
{
	unsigned int i;  //unsigned int -  0~4294967295
	for (i = 9; i >= 0; i--) // i  min=0 这边的循环就会一直走
	{
		printf("%u\n", i);
	}
	return 0;
}

 

练习5
x86环境,小端环境

#include <stdio.h>
int main()
{
	int a[4] = { 1, 2, 3, 4 };
	int* ptr1 = (int*)(&a + 1); //&a - 取出的是整个数组的地址
	int* ptr2 = (int*)((int)a + 1);
	printf("%#x,%#x", ptr1[-1], *ptr2);// ptr1 = 4  ptr2 = 0x02 00 00 00
	return 0;
}

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

  常见的浮点数: 3.14159  1E10(1.0 * 10^10)
 浮点数包含:float / double  / long dlouble

 浮点数的存储
根据国际标准IEEE(电⽓和电⼦⼯程协会)754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:

V = (−1)∗ S M ∗ 2E 

  • (−1)^S 表⽰符号位,当S = 0,V为正数;当S = 1,V为负数
  • M表⽰有效数字,M是⼤于等于1,⼩于2的
  • 2^E 表⽰指数位

 举例;
十进制的5.0 ,二进制是 101.0 ,相当于 1.01*(2^2)
按照格式来写的话,首先是正数 S=0 , M=1.01. E=2。
负数5则是->S = 1, M = 1.01.E = 2。

 

IEEE754规定:

  1. 对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M
  2. 对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M

IEEE754对有效数字M和指数E,还有⼀些特别规定。
前⾯说过, 1≤ M < 2 ,也就是说,M可以写成 1.xxxxxx 的形式,
其中 xxxxxx 表⽰⼩数部分。IEEE754规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后⾯的xxxxxx部分。⽐如保存1.01的时候,只保存01,等到读取的时候,再把第⼀位的1加上去。这样做的⽬的,是节省1位有效数字。
以32位浮点数为例,留给M只有23位,将第⼀位的1舍去以后,等于可以保存24位有效数字。

⾄于指数E,情况就⽐较复杂


⾸先,E为⼀个⽆符号整数(unsigned int)
这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我们知道,科学计数法中的E是可以出现负数的,所以IEEE754规定,存⼊内存时E的真实值必须再加上⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。⽐如,2 ^ 10的E是10,所以保存成32位浮点数时,必须保存成10 + 127 = 137,即10001001

指数E从内存中取出还可以再分成三种情况:

 1.E不全为0或不全为1
这时,浮点数就采⽤下⾯的规则表⽰,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第⼀位的1。


⽐如:0.5的⼆进制形式为0.1,由于规定正数部分必须为1,即将⼩数点右移1位,则为1.0 * 2 ^ (-1),其
阶码为 - 1 + 127(中间值) = 126,表⽰为01111110,⽽尾数1.0去掉整数部分为0,补⻬0到23位
00000000000000000000000,

则其⼆进制表⽰形式为:

 0 01111110 00000000000000000000000


 2.E全为0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第⼀位的1,⽽是还
原为0.xxxxxx的⼩数。这样做是为了表⽰±0,以及接近于0的很⼩的数字。

 0 00000000 00100000000000000000000


 3.E全为1
这时,如果有效数字M全为0,表⽰±⽆穷⼤(正负取决于符号位s)

 0 11111111 00010000000000000000000

 题目解析 

#include <stdio.h>
int main()
{
	int n = 9;
	float* pFloat = (float*)&n;
	printf("n的值为:%d\n", n); // n = 9
	printf("*pFloat的值为:%f\n", *pFloat); // 000000
	// 9.0 - S = 0, M = 1001 , E = 0000 
	// V = (-1)^0 * 0.00000000000000000001001 * 2 ^ (1-127)= 1.001*2^(-146)
	// 二进制的形式 0 10000010 001 0000 0000 0000 0000 0000
	*pFloat = 9.0;
	printf("num的值为:%d\n", n); //1091567616
	printf("*pFloat的值为:%f\n", *pFloat);//9.0
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/472693.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DML - 增删改(insert into,delete,update)

引言&#xff1a;对比DB / 表结构 : create , drop , alter 本次记录 数据操作 语言&#xff1a; 1.进入 hive 数据库&#xff0c;再打开 ryx1 表 2. insert select 3. update select 4. delete select

JVM学习-类加载

目录 1.类文件结构 2.类加载器 3.类加载的三个阶段 3.1加载 3.2链接 3.2.1验证 3.2.2准备阶段 3.2.3解析阶段 3.3初始化 4.拓展&#xff1a;反射 4.1获取类对象 4.2创建实例 4.3获取方法 4.4方法调用 1.类文件结构 2.类加载器 类加载器用来将类文件的二进制字节码加载到JV…

3 CUDA硬件概述

3.1 PC 架构 首先&#xff0c;我们看看当下许多PC中都使用的酷睿2(Core2)处理器的典型架构&#xff0c;然后分析一下它是如何影响我们使用GPU 加速器的(如图 3-1所示)。 图3-1典型的酷睿2(Core2)系列处理器的结构图 由于所有的 GPU 设备都是通过 PCI-E(Peripheral Communicat…

修改约束

目录 修改约束 创建数据库 添加约束 删除约束 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 修改约束 如果说表结构的修改还在可以容忍的范畴之内&#xff0c;那么约束的修改是绝对 100% 禁止的 所有的约束一定要在…

王者荣耀使用的UDP通信,十几年编程没用过的协议

缘起 最近在查阅moba相关的资料时&#xff0c;看到了一篇王者荣耀的研发同学的技术分享&#xff0c;从文章中了解到王者荣耀的通信方式是UDP通信&#xff0c;回想到整个职业生涯&#xff0c;貌似并没有用过&#xff0c;今天特地整理下。 udp技术细节 udp协议 UDP协议叫做用…

代码随想录算法训练营三刷day29 | 回溯算法之 491.递增子序列 46.全排列 47.全排列 II

三刷day29 491.递增子序列回溯三部曲 46.全排列回溯三部曲 47.全排列 II 491.递增子序列 题目链接 解题思路&#xff1a; 回溯三部曲 递归函数参数 本题求子序列&#xff0c;很明显一个元素不能重复使用&#xff0c;所以需要startIndex&#xff0c;调整下一层递归的起始位…

c语言指针(二)

文章目录 c语言指针&#xff08;二&#xff09;1.数组名的理解2.使用指针访问数组3.一维数组的传参本质 c语言指针&#xff08;二&#xff09; 1.数组名的理解 int arr[10] { 1,2,3,4,5,6,7,8,9,10 }; int* p &arr[0]这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元…

系统设计实例(一)百万级别用户系统

二、百万级别用户系统 原则&#xff1a; 尽可能地缓存数据采用无状态Web层支持多个数据中心在 CDN 中托管静态资源通过分片扩展数据层将层级拆分为独立的服务 负载均衡器 负载均衡器会将传入的流量均匀分配给在负载均衡集合中定义的Web服务器&#xff0c;用户直接连接负载均…

【C++ leetcode】双指针问题(续)

3. 202 .快乐数 题目 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;也可能是 无限循环 但始终变不到 1。如果这个过程 结…

文件IO (File对象, 文件读写)

文件 狭义的文件: 硬盘上的文件和目录(文件夹) 广义的文件: 泛指计算机中的很多 软硬件资源 OS 中, 把很多硬件设备和软件资源抽象成了文件, 按照文件的方式来统一管理网络编程中, OS 把网卡当成了一个文件来操作 路径 绝对路径: 以盘符**(c: d: e:)**开头的路径 相对路径: 以 …

HarmonyOS ArkTS 通用事件(二十三)

通用事件目录 点击事件事件ClickEvent对象说明EventTarget8对象说明示例 触摸事件事件TouchEvent对象说明TouchObject对象说明示例 挂载卸载事件事件示例 点击事件 组件被点击时触发的事件。 事件 ClickEvent对象说明 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中…

C++:继承:面向对象编程的重要特性

(❁◡❁)(●◡●)╰(*▽*)╯(*/ω&#xff3c;*)(^///^)(❁◡❁)(❁◡❁)(●◡●)╰(*▽*)╯(*/ω&#xff3c;*)(❁◡❁)(●’◡’●)╰(▽)╯(/ω&#xff3c;)(///) C&#xff1a;继承&#xff1a;面向对象编程的重要特性 前言**继承**1.继承的概念及定义1.1继承的概念1.2继…

学完Python的7大就业方向,哪个赚钱最多?

“ 我想学Python&#xff0c;但是学完Python后都能干啥 &#xff1f;” “ 现在学Python&#xff0c;哪个方向最简单&#xff1f;哪个方向最吃香 &#xff1f;” “ …… ” 相信不少Python的初学者&#xff0c;都会遇到上面的这些问题。大家都知道Python很吃香&#xff0c;薪资…

英伟达 V100、A100/800、H100/800 GPU 对比

近期&#xff0c;不论是国外的 ChatGPT&#xff0c;还是国内诸多的大模型&#xff0c;让 AIGC 的市场一片爆火。而在 AIGC 的种种智能表现背后&#xff0c;均来自于堪称天文数字的算力支持。以 ChatGPT 为例&#xff0c;据微软高管透露&#xff0c;为 ChatGPT 提供算力支持的 A…

slab分配器

什么是slab分配器&#xff1f; 用户态程序可以使用malloc及其在C标准库中的相关函数申请内存&#xff1b;内核也需要经常分配内存&#xff0c;但无法使用标准库函数&#xff1b;linux内核中&#xff0c;伙伴分配器是一种页分配器&#xff0c;是以页为单位的&#xff0c;但这个…

【考研数学】零基础全年可实操规划+网课资料分析

我理解的零基础就是一点基础也没有&#xff0c;甚至来呢最基础的求极限都不会 其实大家可以参照我的经验&#xff0c;零基础数学二&#xff0c;经过一年的学习学习&#xff0c;最后考了122分 首先大家要有自信&#xff0c;我都行你们肯定也可以&#xff01;其实考研数学真的没…

XCode升级错误:Command CompileC failed with a nonzero exit code 解决办法

升级完XCode之后&#xff0c;bulid失败&#xff0c;出现如下错误&#xff1a; 问题1&#xff1a; xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrunCommand Compi…

【性能测试】JMeter:集合点,同步定时器的应用实例!

一、集合点的定义 在性能测试过程中&#xff0c;为了真实模拟多个用户同时进行操作以度量服务器的处理能力&#xff0c;可以考虑同步虚拟用户以便恰好在同一时刻执行操作或发送请求。 通过插入集合点可以较真实模拟多个用户并发操作。 (注意&#xff1a;虽然通过加入集合点可…

2024藏在身边的冷门暴利行业,普通人掌握这个方式也能轻松加入赚取100万!适合普通人轻资产创业项目!2024新的创业机会

如果说2024创业圈流传最多的话是什么&#xff0c;那一定是&#xff1a;“阶级固化了&#xff0c;翻身太难”、“2024机会太少了&#xff0c;赚不到钱”、“经济大环境不好&#xff0c;创业寒冬”云云。 其实这些抱怨都是毫无道理的&#xff0c;无论是国内还是国外&#xff0c;对…

突破图神经网络技术瓶颈!新阶段3大创新方向大幅提高模型性能

针对传统的图神经网络在处理非结构化数据、捕捉高阶关系等方面的局限性&#xff0c;研究者们提出了众多优化方案。 这其中&#xff0c;超图神经网络、几何图神经网络、动态图神经网络作为GNN发展的前沿方向&#xff0c;不仅提供了更加丰富和灵活的方法来处理各种复杂的图数据&…