C语言第二十八弹---整数在内存中的存储

个人主页: 熬夜学编程的小林

💗系列专栏: 【C语言详解】 【数据结构详解】

目录

1、整数在内存中的存储

2、大小端字节序和字节序

2.1、什么是大小端?

2.2、为什么有大小端?

2.3、练习

2.3.1、练习1

2.3.2、练习2

2.3.3、练习3

2.3.4、练习4

2.3.5、练习5

2.3.6、练习6

总结


1、整数在内存中的存储

在讲解操作符的时候,我们就讲过了下面的内容:
整数的2进制表示方法有三种,即原码、反码和补码
三种表示方法均有 符号位和数值位 两部分,符号位都是用 0表示“正”,用1表示“负” ,而数值位最高位(第一位)的⼀位是被当做符号位,剩余的都是数值位。
正整数的原、反、补码都相同。
负整数的三种表示方法各不相同。
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
对于整形来说:数据存放内存中其实存放的是补码。
为什么呢?
在计算机系统中,数值⼀律用补码来表示和存储。
原因在于,使用补码,可以将符号位和数值域统⼀处理; 同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

2、大小端字节序和字节序

当我们了解了整数在内存中存储后,我们调试看⼀个细节:
#include <stdio.h>
int main()
{int a = 0x11223344;return 0;
}
调试的时候,我们可以看到在a中的 0x11223344 这个数字是按照字节为单位,倒着存储的。这是为什么呢?

2.1、什么是大小端?

其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分为大端字节序存储和小端字节序存储,下面是具体的概念:
大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处。
小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。
上述概念需要记住,方便分辨大小端。

2.2、为什么有大小端?

为什么会有大小端模式之分呢?
这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着⼀个字节,⼀个字节为8 bit 位,但是在C语言中除了8 bit 的 char 之外,还有16 bit 的 short 型,32 bit 的 long 型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于⼀个字节,那么必然存在着⼀个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。

例如:⼀个 16bit short x ,在内存中的地址为 0x0010 x 的值为 0x1122 ,那么
0x11 为高字节, 0x22 为低字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中,
0x22 放在高地址中,即 0x0011 中。小端模式,刚好相反。我们常用的 X86 结构是小端模式,而
KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

2.3、练习

2.3.1、练习1

请简述大端字节序和小端字节序的概念,设计⼀个小程序来判断当前机器的字节序。(10分)-百度笔试题。
思路一:
创建一个int类型变量 i 赋值成1,如果通过char*解引用也得到1那么就是小端。
//代码1
#include <stdio.h>
int check_sys()
{int i = 1;return (*(char *)&i);
}
int main()
{int ret = check_sys();if(ret == 1){printf("小端\n");}else{printf("大端\n");}return 0;
}

思路二:

使用联合体方法,创建一个char类型和一个int类型的联合体,将int类型的数据赋值成1,如果char类型的数据也为1,则为小端。

//代码2
int check_sys()
{union{int i;char c;}un;un.i = 1;return un.c;
}

2.3.2、练习2

#include <stdio.h>
int main()
{
char a= -1;
signed char b=-1;
unsigned char c=-1;
printf("a=%d,b=%d,c=%d",a,b,c);
return 0;
}

在第十六弹的操作符(下)中我们谈到整型提升,C语言中整型算术运算总是至少以缺省整型类型的精度来进行的。( 即储存数据类型小于整型储存的32比特位时就使小于32比特位的数据类型整型提升) 为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型(int),这种转换称为整型提升。

1. 有符号整数提升是按照变量的数据类型的符号位来提升的
2. 无符号整数提升,高位补0

我们可以知道我们一般整数进行计算时需要转化为int类型。

10000000 00000000 00000000 00000001    -1的原码

111111111 111111111 111111111 111111110    -1的反码

111111111 111111111 111111111 111111111    -1的补码

但是a的类型为char类型,因此只能存储8个bit位,即11111111   a在内存中实际存储

b的类型为signed char类型,因此只能存储8个bit位,即11111111   b在内存中实际存储

c的类型为unsigned char类型,因此只能存储8个bit位,即11111111   c在内存中实际存储

a按照%d进行打印,即10进制无符号整数打印,a为char类型,根据整型提升规则,有符号按照符号位提升,a提升之后为11111111 11111111 11111111 11111111

11111111 11111111 11111111 11111111    补码

11111111 11111111 11111111 11111110    反码

1000000 0000000 0000000 00000001   原码    值为-1    因此a打印的值为-1,b同理

c按照%d进行打印,即10进制无符号整数打印,c为unsigned char类型,根据整型提升规则,无符号在前面补0,c提升后为00000000 00000000 00000000 11111111 ----为正数,因为正数的原反补码相同,因此c的10进制值为255

2.3.3、练习3

#include <stdio.h>
int main()
{char a = -128;printf("%u\n",a);return 0;
}

10000000 00000000 00000000 10000000     -128原码

111111111 111111111 111111111 011111111     -128反码

111111111 111111111 111111111 10000000     -128补码

a为char类型,因此a在内存中实际存储为 10000000

a按照%u进行打印,即10进制无符号打印,a首先进行整型提升,无符号按照符号位进行提升,即

11111111 11111111 11111111 10000000    提升之后

按照无符号打印,即直接打印,转化为10进制后结果为:4,294,967,168

#include <stdio.h>
int main()
{char a = 128;printf("%u\n",a);return 0;
}

00000000 00000000 00000000 10000000     128原、反、补码  正数都相等

a为char类型,在内存中存储为10000000

a按照%u打印,先整型提升,char类型按照符号位提升,即

11111111 11111111 11111111 10000000

10进制无符号打印即为4,294,967,168

2.3.4、练习4

#include <stdio.h>
int main()
{char a[1000];int i;for(i=0; i<1000; i++){a[i] = -1-i;}printf("%d",strlen(a));return 0;
}

strlen计算的是'\0'之前的字符串长度,即需知道什么时候为0,循环第一次a[i]=-1-0=-1,然后-2,一直到-128,-128-1为127,然后一直减到0,中间个数有255个,因此长度为255.

2.3.5、练习5

#include <stdio.h>
unsigned char i = 0;
int main()
{for(i = 0;i<=255;i++){printf("hello world\n");}return 0;
}

根据unsigned char类型大小的取值范围,范围为0-255,因此 i 一定小于等于255,所以此处为死循环,一直打印hello world

#include <stdio.h>
int main()
{unsigned int i;for(i = 9; i >= 0; i--){printf("%u\n",i);}return 0;
}

根据unsigned int类型大小的取值范围,范围为0-4,294,967,295,i 一定大于等于0,因此此处也为死循环,先打印9 8 7 ....0  然后打印最大值,最大值-1.....一直循环。

调试可得下图。

2.3.6、练习6

#include <stdio.h>
int main()
{int a[4] = { 1, 2, 3, 4 };int *ptr1 = (int *)(&a + 1);int *ptr2 = (int *)((int)a + 1);printf("%x,%x", ptr1[-1], *ptr2);return 0;
}

x86环境得到的结果,x64可能会出错。

总结


本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

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

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

相关文章

性能全面提升!探索ONLYOFFICE最新8.0版:更快速、更强大,PDF表单编辑轻松搞定!

文章目录 PDF表单功能表单模板 屏幕朗读器功能EXCEL新增功能单变量求解图表向导数字排序 PPT 新增功能新增语言区域设置和优化插件界面 ONLYOFFICE 是由 Ascensio System SIA 推出的一款功能强大的办公套件&#xff0c;其中提供了适用于文本文档、表格以及演示文稿的在线编辑软…

2024 全国水科技大会暨第二届智慧水环境管理与技术创新论坛

论坛二&#xff1a;第二届智慧水环境管理与技术创新论坛 召集人&#xff1a;刘炳义 武汉大学智慧水业研究所所长、教授 为贯彻落实中共中央国务院印发《数字中国建设整体布局规划》和国务院关于印发《“十四五”数字经济发展规划》的通知&#xff0c;推动生态环境智慧治理&…

Spring Boot打war包部署到Tomcat,访问页面404 !!!

水善利万物而不争&#xff0c;处众人之所恶&#xff0c;故几于道&#x1f4a6; 文章目录 Spring Boot打war包部署到Tomcat&#xff0c;访问页面404 &#xff01;&#xff01;&#xff01;解决办法&#xff1a;检查Tomcat版本和Jdk的对应关系&#xff0c;我的Tomcat是6.x&#x…

3DSC特征描述符、对应关系可视化以及ICP配准

一、3DSC特征描述符可视化 C #include <pcl/point_types.h> #include <pcl/point_cloud.h> #include <pcl/search/kdtree.h> #include <pcl/io/pcd_io.h> #include <pcl/features/normal_3d_omp.h>//使用OMP需要添加的头文件 #include <pcl…

FPGA领域顶级学术会议

FPGA领域顶级学术会议主要有FPGA,FCCM,FPL和FPT。 1 FPGA 会议全名是: ACM/SIGDA International Symposium on Field-Programmable Gate Arrays 网站是:https://dl.acm.org/conference/fpga FPGA常年在美国举办,每年2月,偏FPGA基础研究; 该会议的论文免费下载。这个比…

(十三)【Jmeter】线程(Threads(Users))之tearDown 线程组

简述 操作路径如下: 作用:在正式测试结束后执行清理操作,如关闭连接、释放资源等。配置:设置清理操作的采样器、执行顺序等参数。使用场景:确保在测试结束后应用程序恢复到正常状态,避免资源泄漏或对其他测试的影响。优点:提供清理操作,确保测试环境的整洁和可重复性…

jvm、jre、jdk的关系

jvm Java 虚拟机&#xff08;JVM&#xff09;是运行 Java 字节码的虚拟机。 jre JRE&#xff08;Java Runtime Environment&#xff09; 是 Java 运行时环境。它是运行已编译 Java 程序所需的所有内容的集合&#xff0c;主要包括 Java 虚拟机&#xff08;JVM&#xff09;、J…

C++笔记:OOP三大特性之继承

文章目录 一、继承的概念和定义1.1 概念1.2 定义格式1.3 继承关系和访问限定符 二、基类和派生类对象赋值兼容转换2.1 类型转换存在临时对象的意义2.2 赋值兼容转换不会产生临时变量 三、继承中的作用域四、派生类中的默认成员函数4.1 构造4.2 拷贝构造4.3 赋值重载4.4 析构 五…

【Java多线程】分析线程加锁导致的死锁问题以及解决方案

目录 1、线程加锁 2、死锁问题的三种经典场景 2.1、一个线程一把锁 2.2、两个线程两把锁 2.3、N个线程M把锁&#xff08;哲学家就餐问题&#xff09; 3、解决死锁问题 1、线程加锁 其中 locker 可以是任意对象&#xff0c;进入 synchronized 修饰的代码块, 相当于加锁&…

OpenWRT部署web站点并结合内网穿透实现无公网ip远程访问

文章目录 前言1. 检查uhttpd安装2. 部署web站点3. 安装cpolar内网穿透4. 配置远程访问地址5. 配置固定远程地址 前言 uhttpd 是 OpenWrt/LuCI 开发者从零开始编写的 Web 服务器&#xff0c;目的是成为优秀稳定的、适合嵌入式设备的轻量级任务的 HTTP 服务器&#xff0c;并且和…

尝试一下最新的联合办公利器ONLYOffice

下载下来一起试试吧 桌面安装版下载地址&#xff1a;https://www.onlyoffice.com/zh/download-desktop.aspx) 官网地址&#xff1a;https://www.onlyoffice.com 普通Office对联合办公的局限性 普通Office软件&#xff08;如Microsoft Office、Google Docs等&#xff09;在面对…

Socket通信---Python发送数据给C++程序

0. Problems 很多时候实现某种功能&#xff0c;需要在不同进程间发送数据&#xff0c;目前有几种主流的方法&#xff0c;如 让python和C/C程序互相发送数据&#xff0c;其实有几种方法&#xff1a; 共享内存共享文件Socket通信 在这里只提供Socket通信的例程&#xff0c;共享…

MySQL学习笔记3: MySQL数据库基础

目录 前言目标数据库操作&#xff08;针对database 的操作&#xff09;1. 创建数据库 create database 数据库名;2. 查看数据库 show databases;3. 选中数据库 use 数据库名;4. 删除数据库 drop database 数据库名; mysql中支持的数据类型1. 数值类型: NUMERIC(M,D)2. 字符串类…

如何在OpenWRT安装内网穿透工具实现远程访问本地搭建的web网站界面

文章目录 前言1. 检查uhttpd安装2. 部署web站点3. 安装cpolar内网穿透4. 配置远程访问地址5. 配置固定远程地址 前言 uhttpd 是 OpenWrt/LuCI 开发者从零开始编写的 Web 服务器&#xff0c;目的是成为优秀稳定的、适合嵌入式设备的轻量级任务的 HTTP 服务器&#xff0c;并且和…

【Vue】本地使用 axios 调用第三方接口并处理跨域

前端处理跨域 一. 开发准备 开发工具&#xff1a;VScode框架&#xff1a;Vue2项目结构&#xff1a;vue脚手架生成的标准项目&#xff08;以下仅显示主要部分&#xff09; 本地已搭建好的端口&#xff1a;8080要请求的第三方接口&#xff1a;http://1.11.1.111:端口号/xxx-api…

大型语言模型的语义搜索(一):关键词搜索

关键词搜索(Keyword Search)是文本搜索种一种常用的技术&#xff0c;很多知名的应用app比如Spotify、YouTube 或 Google map等都会使用关键词搜索的算法来实现用户的搜索任务&#xff0c;关键词搜索是构建搜索系统最常用的方法&#xff0c;最常用的搜索算法是Okapi BM25&#x…

Unity基于AssetBundle资源管理流程详解

在Unity游戏开发中&#xff0c;资源管理是一个非常重要的环节。随着游戏的发展&#xff0c;资源会变得越来越庞大&#xff0c;因此需要一种高效的资源管理方式来减少内存占用和加快加载速度。AssetBundle是Unity提供的一种资源打包和加载方式&#xff0c;可以将资源打包成一个独…

JS前端高频面试

JS数据类型有哪些&#xff0c;区别是什么 js数据类型分为原始数据类型和引用数据类型。 原始数据类型包括&#xff1a;number&#xff0c;string&#xff0c;boolean&#xff0c;null&#xff0c;undefined&#xff0c;和es6新增的两种类型&#xff1a;bigint 和 symbol。&am…

使用 Coze 搭建 TiDB 助手

导读 本文介绍了使用 Coze 平台搭建 TiDB 文档助手的过程。通过比较不同 AI Bot 平台&#xff0c;突出了 Coze 在插件能力和易用性方面的优势。文章深入讨论了实现原理&#xff0c;包括知识库、function call、embedding 模型等关键概念&#xff0c;最后成功演示了如何在 Coze…

【EasyV】QGIS转换至EasyV

QGIS转换至EasyV 第一步&#xff1a;导入QGIS第二步 坐标系转换第三步 集合修正第四步 重命名字段第五步 导出WGS geojson坐标第六步 导入EasyV 第一步&#xff1a;导入QGIS 第二步 坐标系转换 第三步 集合修正 第四步 重命名字段 第五步 导出WGS geojson坐标 第六步 导入EasyV…