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

news2024/11/17 11:42:59

文章目录

  • 前言
  • 一、整数在内存中的存储
  • 二、大小端字节序和字节序判断
    • 什么是大小端?
    • 为什么会有大小端?
    • 练习
      • 练习1
      • 练习2
      • 练习3
      • 练习4
      • 练习5
      • 练习6
      • 练习7
  • 总结


前言

  本篇是修炼内功的文章
  首先,你先明白一个事实,数据在内存中是以二进制的形式存储的
  然后正文开始!


一、整数在内存中的存储

  在讲解操作符的时候,我们就讲过了整数的2进制表示方法有三种:原码、反码和补码
  对于有符号数来说,三种表示方法均有符号位数值位两部分,符号位都是用 0 表示 ‘正’ ,用 ‘1’ 表示负,而数值位最高位的一位是被当作符号位,剩余的都是数值位

  正整数的原、反、补码都相同
  负整数的三种表示方法各不相同

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

  对于整型来说,数据存放内存中其实存放的是补码
  为什么呢?我们再来回顾一下:

使用补码,可以将符号位和数值域统一处理;
同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需额外的硬件电路。

二、大小端字节序和字节序判断

什么是大小端?

申请一个变量:int a = 0x11223344; // 占用4个字节

请问,这样在内存中有几种可能?答案是三种:
在这里插入图片描述
我们也思考,数据的存储,是未来将来正确的取出,而第三种方式随便放就显得很奇葩,很难记下来,不符合我们常用的习惯,假如你是C语言设计者,也不会选择这一种方式
而第一种叫做大端字节序存储,第二种叫做小端字节序存储

两者的区别都是在存储超过一个字节的数据显现的,其实说到底就是存储顺序的差别,按照不同的存储顺序,我们分为大端字节序和小端字节序存储

大端存储模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容,保存在内存的低地址处
小端存储模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处

为什么会有大小端?

  这是因为在计算机系统中,我们是以字节为单位,每个地址单元都对应着一个字节,一个字节为8 bit 位,但是在C语言中除了8 bit 的 char 之外,还有16 bit 的 short 型,32 bit 的 long 型(要看具体的编译器),另外,对于位数大于8的处理器,例如有些存储器或宽度大于一个字节,那么必然存在着一个如何将多个字节安放的问题。
  例如:一个16 bit的short型,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式则相反。我们使用的X86结构是小端模式,而KEIL C51则为大端模式。很多ARM、DSP都是小端模式。有些ARM处理器还可以由用户选择大端模式也是小端模式

练习

练习1

 请编写一个小程序来判断你的机器环境是什么字节序

有趣的是,这是一道面试题

 方法也不难,我们想一个 int 有四个字节,假如来个取址符&,就指向低地址的那个字节,这时候强转char*指针再解引用,就得到了那个低地址的数据,若为小端,数据低位在低地址,即拿到了0x01,就是1;若为大端,数据低位在高地址,即拿到了0x00,就是0
代码如下:

#include <stdio.h>  
#include <string.h>

int check_sys()
{
	int test = 0x00000001;
	
	return *((char*)&test); // 拿到低字节

}

int main()
{	
	int ret = check_sys();

	if (check_sys()) printf("是小端\n");
	else printf("是大端\n");

	return 0;
}

练习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;  
}

输出结果是 a = -1, b = -1, c = 255

我们来分析一下:
1.对于第一个有符号char,原码是10000000000000000000000000000001,反码是11111111111111111111111111111110,补码是11111111111111111111111111111111,然而我们现在要把补码放到比特里面,只能放八个比特位,也就是发生了截断,变成了11111111,同样其实b,c放得也是这样,现在对a来说,整型提升补的都是1,接着继续取反加1,这样就得到了-1的原码并打印
2.而对于c,整型提升成00000000000000000000000011111111,直接打印出255

%d是以十进制的形式打印有符号的整数

练习3

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

%u是十进制的形式打印无符号的整数

我们可以先看看有符号的char变量在内存中存储的所有可能性
在这里插入图片描述
一旦看到10000000,直接会被解读为-128,所以有符号char的取值范围是 -128 ~ 127
其实你观察一下11111111,再加个1,直接变成00000000,所以符号char是循环存储的,请记一下
在这里插入图片描述
对于无符号char也是一样的
在这里插入图片描述
我们回到该题,-128在内存中的存储是
10000000000000000000000010000000 原码
11111111111111111111111101111111 反码
11111111111111111111111110000000 补码
所以截断后,a存储的是10000000
打印的时候,发生整型提升,提升的时候是按照自己的类型char提升
11111111111111111111111110000000,这时候,又以无符号的整数打印
就是一个很大的数了 -> 4,294,967,168

所以说,有符号的数尽量用%d打印,无符号的用%u来打印

练习4

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

同上,分析后得出还是11111111111111111111111110000000,即4,294,967,168

练习5

#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;  
}

理论上会有 -1 -2 … -1000,可是我们之前说了,char取值范围是个循环,范围在-128-127
到0的时候,strlen读取到就会停止,最后会发现0前面有255个数字,所以答案是255

练习6

#include <stdio.h>  

unsigned char i = 0;  

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

还是循环范围,unsigned char类型的 i 最大就是255,i循环到255后再自加,直接变成0,继续死循环

练习7

// x86环境,小端字节序
#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;  
}

第一个应该很好想,主要是第二个,直接把地址强制转换为整数再加1,再强制转化为 int* 指针,相当于跳过了一个字节,剩余的思考以图形式形象展现
在这里插入图片描述


总结

  写到这里的时候,已经是晚上了,本来还想写浮点数在内存中的存储的,但是我困了,睡觉!
  学到这里,你应该发现已经开始跟之前的知识串联起来了,如果你有这种感觉,很棒,继续加油!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

预测日前电价:回顾最先进的算法、最佳实践和公开基准——阅读笔记

Forecasting day-ahead electricity prices: A review of state-of-the-art algorithms, best practices and an open-access benchmark 预测日前电价&#xff1a;回顾最先进的算法、最佳实践和公开基准 Applied Energy (2021) 摘要&#xff1a;电价预测在过去二十年间已经得到…

python画图|3D surface基础教程

画三维图在当前的需求越来越强烈&#xff0c;因此掌握3D图的画法至关重要。 让我们先来学习3D surface基础教程。 【1】官网教程 首先是来到官网&#xff0c;找到教程&#xff0c;详见下述链接&#xff1a; 3D surface (colormap) — Matplotlib 3.9.2 documentation 教程…

【Linux】代理服务器

一、正向代理 1.1 正向代理的概述 正向代理是一种常见的网络代理方式&#xff0c;他位于客户端和目标服务器之间&#xff0c;代表客户端向目标服务器发送请求。正向代理服务器接受客户端的请求&#xff0c;然后将请求转发给目标服务器&#xff0c;最后将目标服务器的响应返回给…

mybatis与concat实现模糊查询、mybatis中模糊查询concat传入参数为空时的解决方法

文章目录 在mybatis中&#xff0c;一般模糊查询like习惯用concat进行拼接&#xff0c;但是当传入的参数为空时&#xff0c;查询不出数据。 那是因为concat中&#xff0c;若传入参数为null, 则返回null。 以下整理mybatis中like模糊查询的写法 <select id"findByKeyw…

【uni-app】命令行创建 uni-app 项目

命令行创建 uni-app 项目 优势 通过命令行创建 uni-app 项目&#xff0c;不必依赖 HBuilderX&#xff0c;TypeScript 类型支持友好。 命令行创建 uni-app 项目&#xff1a; vue3 ts 版 &#x1f449;国内 gitee 下载github 下载 # 通过 git 从 gitee 克隆下载 git clone…

Servlet学习详解--基本涵盖所有Servlet知识点

目录 一、Servlet二、 Servlet入门2.1. 执行原理2.2. 实现Servlet接口重写其五个方法及其生命周期 三、Request请求对象3.1. 获取请求消息数据3.2. 获取请求头数据3.3. 获取请求体数据3.4. 设置编码3.5. 其他通用功能3.6. 请求转发(Forward)3.7. 转发共享数据 四、Response对象…

算法刷题[比较两个字符串的最大公字符串(滑动窗口实现)]

题目&#xff1a;编程实现&#xff1a;找出两个字符串中最大公共子字符串,如"abccade","dgcadde"的最大子串为"cad" 代码如下所示&#xff1a; #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #inclu…

Wophp靶场漏洞挖掘

首先进入网站发现有个搜索框&#xff0c;那么我们试一下xss和SQL注入 SQL注入漏洞 发现这里页面没有给我们回显 那么我们尝试sql注入 查数据库 查表 最后查出账号密码 找到账号密码之后我们去找后台登录 进入后台后发现这里有个flag flag 接着往下翻找到一个文件上传的地方 …

STM32启用FPU浮点运算

这篇文章产生背景&#xff1a;其他人的文章太杂了&#xff0c;对我这种菜鸡无法接受&#xff1b; 参考文章&#xff1a; stm32h743单片机嵌入式学习笔记7-FPU_stmh743vit4-CSDN博客 stm32F407 打开 FPU(浮点运算处理器)_stm32f407开启fpu-CSDN博客 STM32F4CubeMXHal库下使能…

基于微信小程序的食堂点餐预约管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 基于微信小程序JavaSpringBootVueMySQL的食…

linux-L6 linux管理服务的启动、重启、停止、重载、查看状态命令

来重启一下某一个服务 1.使用命令查看所有的服务状态 Systemctl找到其中的相关的服务 systemctl status xxx_你的应用程序的服务__xxx3.重启该服务 systemctl restart xxx_你的应用程序的服务__xxx下面的是备用&#xff0c;需要用的时候&#xff0c;查看就好了 启动服务 …

[机器学习]聚类算法

1 聚类算法简介 # 导包 from sklearn.datasets import make_blobs import matplotlib.pyplot as plt from sklearn.cluster import KMeans from sklearn.metrics import calinski_harabasz_score # 构建数据 x,ymake_blobs(n_samples1000,n_features2,centers[[-1,-1],[0,0],[1…

如何正确使用布尔表达式

在Java编程语言中&#xff0c;布尔表达式&#xff08;Boolean Expressions&#xff09;是程序逻辑控制的核心部分。它们是用来表示“真”&#xff08;true&#xff09;或“假”&#xff08;false&#xff09;的逻辑语句&#xff0c;通常用于控制程序的执行流程&#xff0c;比如…

【例题】1 二极管

文章目录 二极管的理想模型例题二极管的恒压降模型例题恒压管例题二极管的理想模型例题 根据二极管的理想模型,正向电压断路,反向电压开路分析。 这里的 u 0 u_0 u

OpenHarmony(鸿蒙南向开发)——小型系统芯片移植指南(二)

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ OpenHarmony&#xff08;鸿蒙南向开发&#xff09;——轻量系统芯片移植指南(一) Op…

安全工具 | 使用Burp Suite的10个小tips

Burp Suite 应用程序中有用功能的集合 img Burp Suite 是一款出色的分析工具&#xff0c;用于测试 Web 应用程序和系统的安全漏洞。它有很多很棒的功能可以在渗透测试中使用。您使用它的次数越多&#xff0c;您就越发现它的便利功能。 本文内容是我在测试期间学到并经常的主要…

CSS框架 Tailwind CSS

文章目录 前言一、Tailwind CSS是什么&#xff1f;二、项目中如何使用1.安装Tailwind CSS2.初始化Tailwind CSS该处使用的url网络请求的数据。3.引入Tailwind CSS样式4.进行配置&#xff08;tailwind.config.js&#xff09;5.全局引入注册6.使用Tailwind CSS 总结 前言 Tailwi…

基于鸿蒙API10的RTSP播放器(七:亮度调节功能测试)

目标&#xff1a; 当我的手指在设备左方进行上下移动的时候&#xff0c;可以进行屏幕亮度的调节&#xff0c;在调节的同时&#xff0c;有实时的调节进度条显示 步骤&#xff1a; 界面逻辑&#xff1a;使用Stack() 组件&#xff0c;完成音量图标和进度条的组合显示&#xff0c…

pytorch-AutoEncoders实战

目录 1. AutoEncoders回顾2. 实现网络结构3. 实现main函数 1. AutoEncoders回顾 如下图&#xff1a;AutoEncoders实际上就是重建自己的过程 2. 实现网络结构 创建类继承自nn.Model&#xff0c;并实现init和forward函数&#xff0c;init中实现encoder、decoder 直接上代码&a…

DataWind将string类型转化为int类型的报错解决

一、现象&#xff1a; toInt64([kernel_wakeup_top_count_str]) 二、日志&#xff1a; 遇到&#xff1a;错误: 直连查询失败&#xff0c;内部异常:<class aeolus.aeolus.libs.exception.aeolus_base_exception.AeolusBaseException>: aeolus/logicQuery/logicQueryMysq…