整形数据在内存中的存储(C语言)

整形数据在内存中的存储

      • 1.整形家族
      • 2.(原码、反码、补码)基础知识
      • 3.大小端
        • 3.1 什么是大小端
        • 3.2 为什么有大端和小端
        • 3.3 一道关于大小端字节序的面试题
        • 3.4 关于整形数据存储的题目(7题)
          • 3.4.1
          • 3.4.2
          • 3.4.3
          • 3.4.4
          • 3.4.5
          • 3.4.6
          • 3.4.7
      • 4.总结

1.整形家族

signed可省可不省,一般省略不写unsigned charsigned charunsigned short [int]signed short [int]unsigned intsigned intunsigned long [int]signed long [int]

2.(原码、反码、补码)基础知识

计算机中的整数有三种2进制表示方法,即原码、反码和补码。
三种表示方法均有符号位和数值位两部分,符号位都是用0表示“正”,用1表示“负”。
正数的原、反、补码都相同。
负整数的三种表示方法各不相同。

  • 原码
    直接将数值按照正负数的形式翻译成二进制就可以得到原码。
  • 反码
    将原码的符号位不变,其他位依次按位取反就可以得到反码。
  • 补码
    反码+1就得到补码。

对于整形来说:数据存放内存中其实存放的是补码。

原因在于:在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

int main()
{//为了方便表示,在vs中数据以十六进制呈现出来//0x0000000a  ->10int num = 10;//0xfffffff6  ->-10int num2 = -10;
}

在这里插入图片描述
我们可以看到对于num和num2分别存储的是补码。但是我们发现顺序有点不对劲。
这是又为什么?解下来介绍大小端

3.大小端

3.1 什么是大小端

大端(存储)模式:把一个数据的低位字节的内容,存放在高地址处,把一个数据的高位字节的内容,存放在低地址处。
大端(存储)模式:把一个数据的低位字节的内容,存放在低地址处,把一个数据的高位字节的内容,存放在高地址处。

在这里插入图片描述

3.2 为什么有大端和小端

因为在计算机系统中,是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8 bit。但是在C语言中除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。
常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

3.3 一道关于大小端字节序的面试题

设计一个小程序来判断当前机器的字节序。

#include<stdio.h>
int check_sys1()
{int a = 1;return (*(char*)&a);
}
//方法2int check_sys2()
{union{int i;char c;}un;un.i = 1;return un.c;
}
int main()
{int ret = check_sys1();if (ret == 1)printf("小端字节序存储\n");elseprintf("大端字节序存储\n");printf("%d", ret);
}
3.4 关于整形数据存储的题目(7题)

原码 = 补码-1,然后取反
补充知识:原码 = 补码取反+1

3.4.1
int main()
{char a = -1;  //char是有符号字符类型,并且取值范围能存下-1,因此打印-1//10000000 00000000 00000000 00000001  原码//11111111 11111111 11111111 11111110  反码//11111111 11111111 11111111 11111111  补码//11111111 -a 截断(因为char只有1字节=8bit)//%d整形打印: 先提升,然后将补码转换成原码//11111111 11111111 11111111 11111111  补码//10000000 00000000 00000000 00000000  反码//10000000 00000000 00000000 00000001  原码 ->-1signed char b = -1; //char 和 signed char是一样的,知识char默认为有符号,所以省略了signed,结果也是-1//b同a一样unsigned char c = -1; //此时char是无符号//00000000 00000000 00000000 11111111  补码//11111111 -c 截断,因为是无符号,所以整形提升时前面补0//%d打印:需要发生整形提升//00000000 00000000 00000000 11111111 ->255printf("a=%d,b=%d,c=%d", a, b, c);return 0;
}
3.4.2
int main()
{char a = -128;//10000000 00000000 00000000 10000000  原码//11111111 11111111 11111111 01111111  反码//11111111 11111111 11111111 10000000  补码//10000000  ->-128//按%u: 无符号整形打印,需整形提升//11111111 11111111 11111111 10000000  ->4294967168printf("%u\n", a);return 0;
}
3.4.3

int main()
{char a = 128;//10000000 00000000 00000000 10000000   原码   ->整形提升//11111111 11111111 11111111 01111111   反码//11111111 11111111 11111111 10000000   补码//10000000  ->128//按%u: 无符号整形打印,需整形提升//11111111 11111111 11111111 10000000   ->4294967168printf("%u\n", a);return 0;
}
3.4.4
int main()
{int i = -20;//10000000 00000000 00000000 00010100//11111111 11111111 11111111 11101011//11111111 11111111 11111111 11101100   ->补码unsigned int j = 10;//00000000 00000000 00000000 00001010   ->补码//11111111 11111111 11111111 11101100 +//11111111 11111111 11111111 11110110   ->补码//10000000 00000000 00000000 00001001//10000000 00000000 00000000 00001010   ->10printf("%d\n", i + j);return 0;
}
3.4.5
#include<windows.h>
int main()
{unsigned int i;for (i = 9; i >= 0; i--){printf("%u\n", i);Sleep(1);}return 0;
}

在这里插入图片描述

此结果是无限循环,因为i是无符号整形,i的值只可能大于等于0;

3.4.6
int main()
{char a[1000];int i;for (i = 0; i < 1000; i++){a[i] = -1 - i;}printf("%d", strlen(a));return 0;
}
//-1  -2  -3  -4....-128  127  126  125... 0
//-1  -2  -3  -4....-128  127  126  125... 0
//...

strlen遇到\0就结束,并且\0 == 0的,因此在第一次遇到0时就结束计算;
结果是:128+127=255, 不包括\0;

3.4.7
unsigned char i = 0;
int main()
{for (i = 0; i <= 255; i++){printf("hello world\n");}return 0;
}

因为i是无符号字符型,并且i<=255,当i=255时,此时i++的结果是0,因此导致程序死循环;

4.总结

  1. 正数的原、反、补码都相同。
    负整数的三种表示方法各不相同。
  • 原码
    直接将数值按照正负数的形式翻译成二进制就可以得到原码。
  • 反码
    将原码的符号位不变,其他位依次按位取反就可以得到反码。
  • 补码
    反码+1就得到补码。
  1. 原码 = 补码-1,然后取反;
    补充知识:原码 = 补码取反+1;
  2. 对于整形来说:数据存放内存中其实存放的是补码。

大端(存储)模式:把一个数据的低位字节的内容,存放在高地址处,把一个数据的高位字节的内容,存放在低地址处。
大端(存储)模式:把一个数据的低位字节的内容,存放在低地址处,把一个数据的高位字节的内容,存放在高地址处。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux的网络服务DHCP

一.了解DHCP服务 1.1 DHCP定义 DHCP&#xff08;动态主机配置协议&#xff09;是一个局域网的网络协议。指的是由服务器控制一段IP地址范围&#xff0c;客户机登录服务器时就可以自动获得服务器分配的IP地址和子网掩码。默认情况下&#xff0c;DHCP作为Windows Server的一个服…

搭建Windows版Redis集群

redis集群 Redis单机版安装 链接: Redis官网下载地址 下载完成后解压至指定目录 打开一个 cmd 窗口 使用 cd 命令切换目录到 E:\Redis\Redis 运行&#xff1a; redis-server.exe redis.windows.confRedis集群的安装 1.构建集群节点目录 创建一个redis-cluster目录用于存放…

Container ansible disguises local ansible 【容器 ansible 伪装本地 ansible】

预备条件&#xff1a; ctr & crictl $ nerdctl & containerd install了解 kubespray 是什么 kubespray 包含 ansible、ansible-playbook命令以及通过kubespray项目安装kubernetes集群的介质。 nerdctl pull quay.io/kubespray/kubespray:v2.23.1 nerdctl save -o qu…

二叉树基础oj练习(单值二叉树、相同的树、二叉树的前序遍历)

讲了这么多数据结构相关的知识(可以看我的数据结构文章专栏): 抓紧刷题巩固一下了 目录 1.单值二叉树 题目描述 思路1 代码1 思路2 代码2 2.相同的树 题目描述 思路 代码 3.二叉树的前序遍历 代码 思路 1.单值二叉树 965. 单值二叉树 - 力扣&#xff08;LeetCod…

67个你可能不知道的神奇的浏览器调试技巧

67个你可能不知道的神奇的浏览器调试技巧 一系列有用的、不明显的技巧&#xff0c;可帮助您充分利用浏览器的调试器。假设对开发人员工具有中级或更高的了解。 Advanced Conditional Breakpoints 高级条件断点 通过在您意想不到的地方使用具有副作用的表达式&#xff0c;我们…

探索检索增强生成(RAG)技术的无限可能:Vector+KG RAG、Self-RAG、多向量检索器多模态RAG集成

探索检索增强生成&#xff08;RAG&#xff09;技术的无限可能&#xff1a;VectorKG RAG、Self-RAG、多向量检索器多模态RAG集成 由于 RAG 的整体思路是首先将文本切分成不同的组块&#xff0c;然后存储到向量数据库中。在实际使用时&#xff0c;将计算用户的问题和文本块的相似…

unity C#中Array、Stack、Queue、Dictionary、HashSet优缺点和使用场景总结

文章目录 数组 (Array)列表 (List<T>)栈 (Stack<T>)队列 (Queue<T>)链表 (LinkedList<T>)哈希表 (Dictionary<TKey, TValue>) 或 HashSet<T>集合 (Collection<T>) 数组 (Array) 优点&#xff1a; 高效访问&#xff1a;通过索引可以…

OCP NVME SSD规范解读-6.标准日志要求-2

STD-LOG-12:针对日志存储的类型定义了多种&#xff0c;复位&#xff08;包括控制器复位&#xff0c;NSSR、FLR、PCIe hot reset&#xff09;与断电重启POWER CYCLE有不同的操作要求。 STD-LOG-14: Lockdown命令是NVMe管理命令集中的一个命令&#xff0c;主要用于安全和管理目的…

太惨了,又一个程序员被渣的开年大瓜

今天闲暇之余浏览了一下mm&#xff0c;忽然看见一条瓜&#xff1a;某东pdf瓜&#xff0c;一份19页的PDF文件&#xff0c;题为《婚房变赠予&#xff0c;京东渣女出轨连环套设计冤大头程序员》&#xff0c;点进去看了一下&#xff0c;简直炸裂了三观&#xff0c;男同志们一定要保…

007-可调脉冲数触发之FPGA实现(Zynq也可驱动,带启动停止及完成中断输出)

文章目录 前言一、设计思路二、代码及仿真1.资源消耗2.具体代码3.仿真波形 总结 前言 此代码是在做显微镜高速聚焦系统中自己写的步进电机电机驱动源码&#xff0c;为了达到最快的驱动速度&#xff0c;因此选用脉冲触发方式进行驱动。在电机驱动的过程中往往需要对脉冲进行使能…

优雅处理并发:Java CompletableFuture最佳实践

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;今天&#xff0c;小黑要和大家聊聊CompletableFuture&#xff0c;这个Java 8引入的强大工具。 在Java传统的Future模式里&#xff0c;咱们都知道&#xff0c;一旦开始了一个异步操作&#xff0c;就只能等它结束…

x-cmd pkg | magick - 开源图像处理工具

目录 简介首次用户功能特点类似工具与竞品进一步探索 简介 magick 是由 ImageMagick 提供的一个功能强大且多功能的开源图像处理工具&#xff0c;可以灵活高效地处理图像文件&#xff0c;例如格式转换、图像大小调整、图像裁减、图像拼接、图像色彩校正和图像合成等常见的图像…