C语言学习分享(第八次)------数据的存储

这篇具有很好参考价值的文章主要介绍了C语言学习分享(第八次)------数据的存储。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:C语言学习分享⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习更多C语言知识
  🔝🔝


C语言学习分享(第八次)------数据的存储



1. 前言🚩

本篇文章带给大家的内容有,整型在内存中的存储,大端小端的介绍与判断,和一些练习.从这篇文章开始,我们将进入C语言进阶知识的部分.


2. 整型在内存中的存储🚩

比如我们定义两个整型变量:

int a = 20;
int b = -10;

我们知道整型在内存中占四个字节的空间,在这之前我们先了解下面的概念


2.1 源码,反码,补码🏁

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

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

我们说正整数的源码,反码,补码都相同.并且对于整形来说:数据存放内存中其实存放的是补码。

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

	int main()
{
	int num  = 20;//创建一个整型变量,叫 num,这时num向内存申请4个字节来存放数据
	//4个字节-32比特位
	//00000000000000000000000000010100-原码
	//00000000000000000000000000010100-反码
	//00000000000000000000000000010100-补码
    //正整数源反补相同
	int num2 = -10;//
	//10000000000000000000000000001010 - 原码
	//11111111111111111111111111110101 - 反码
	//11111111111111111111111111110110 - 补码
	//
	return 0;
}

假设我们要将这两个数相加,我们试试用反码,和补码相加,哪个是正确的:

源码相加:

//0000000000000000000000010100  num
//1000000000000000000000001010  num2
//1000000000000000000000011110  30的源码

补码相加:

//000000000000000000000010100  num
//111111111111111111111110110  num2
//011111111111111111111110110  补码
//000000000000000000000001010  10的源码   

我们有看见用补码做加减法是刚好符合逻辑的.

我们再来看看 -10 在 vs2022 编译器上的内存存储:

C语言学习分享(第八次)------数据的存储

这里是倒着存放的数据,后面会讨论,现在我们暂且不看,但是我们能感受到实际上数据在内存中的存储是以补码的形式存储的


3. 大端和小端🚩

我们之前观察了补码在内存中的存储,我们发现有一点奇怪,为什么数据是倒着放的?这里我们用变量a来阐述这个问题

int a = 0x11223344;

我们说内存分为高地址和低地址,而数据又分高位和低位,比如说这里 11223344 的44 就是数据的低位,而 11 就是数据的高位,下面我给出大小端的定义:

  • 大端字节序(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中
  • 小端字节序(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中

字节序—就是以字节为单位,讨论存储顺序的.这里的 11 为一个字节, 22 为一个字节,整型共四个字节


C语言学习分享(第八次)------数据的存储


3.1 为什么有大端小端?🏁

为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为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处理器还可以由硬件来选择是大端模式还是小端模式。


3.2 怎样判断大小端🏁

怎么写一个代码判断当前机器是大端还是小端? 这里我们定义一个整型变量a的值为1

它在大小端机器上应该是这样存储的:

C语言学习分享(第八次)------数据的存储


我们想到,int类型的指针解引用可以访问四个字节的空间,而char类型的指针解引用可以访问一个字节的空间,我们定义一个char类型的指针指向变量a,如果对指针解引用的结果是1,那么当前机器就是小端,解引用后结果是0那么机器就是大端.

#include<stdio.h>
	int main()
{
		int a = 1;
		char* p = (char*)&a;//强制类型转换,否则会报警告
		if (*p == 1)
		{
			printf("当前机器为小端");
		}
		else
		{
			printf("当前机器为大端");
		}
	return 0;
}

4. 类型的范围🚩

我们把整型家族划分为:
C语言学习分享(第八次)------数据的存储
下面我们主要来讨论 char 类型的范围,并做一些练习


4.1 char 类型的范围🏁

我们知道char类型在内存中占1个字节,也就是八个比特位(也可以说占八个二进制位),我们来讨论一下有符号char和无符号char的数据存储范围.

C语言学习分享(第八次)------数据的存储
再来看看无符号位的存储:

C语言学习分享(第八次)------数据的存储

  • 有符号位char的范围: -128~127
  • 无符号位char的范围: 0~255

并且我们可以发现一个规律,无符号char中,255+1,又跳到0去了,形成了一个循环,所以我们可以画这样一个圆形的循环图来理解:

C语言学习分享(第八次)------数据的存储

C语言学习分享(第八次)------数据的存储

我们可以看见,无符号位的char的127+1变成了128,而有符号位的char中的127+1变成了-128.并且无符号位中的255加1又回到了0,所以无符号char能存储的最大数就是255.超过255又会重新回到0.


5. 练习🚩

5.1 练习一🏁

1.
//输出什么?
#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和b很好判断,在vs编译器下,如果没有指定是否是有符号或者无符号,就默认为有符号形,然而c是无符号char类型的变量,它存储-1的补码在内存中,-1的补码是 11111111 然而无符号数的源反补码都相同,所以当-1被存储在无符号数中后,11111111八个1都不是符号位,值就为255了.


5.2 练习二🏁

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

首先这里会输出4294967168,为什么呢?首先a是有符号char类型的变量,存储-128的值,然而%u是打印无符号整数的意思,所以这里的char类型会发生整型提升,从一个字节提升至4个字节,又因为a是负数,它的的符号位为1,所以整型提升时前面全部都是补的1,所以我们就得到了一个数的补码,然而无符号数的源反补码都相同,所以我们就会得到一个特别大的数的源码.


5.3 练习三🏁

3.
unsigned int i;
for(i = 9; i >= 0; i--)
{
    printf("%u\n",i);
}

这里会死循环打印,我们来分析分析,这里的变量 i 是无符号整型,一个无符号数是肯定不会是负数的,当 i 等于0时再减去1,它会像我们刚刚讨论的无符号char类型一样变成无符号整型中的最大值,而不是-1,所以它会一直打印下去

这里给大家看一看现象:

死循环


5.4 练习四🏁

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

这里数组a的长度为255,我们来分析这一点.首先,数组a中存储的数据是有符号char类型的数据,数据范围是: -128 ~ 127之间.这里循环中 i 的范围是: -1 ~ -999 之间,数组中的内容会从-1开始一直往后存储,当i等于-128时,-1-128这时根据我们上面画的循环图,-1-128就等于127.下一步-1-129同理也就是等于126,然后125,124…这样存储下去,直到它变为0后又减一变成-1,以此循环往复直到装满1000个数为止.

当我们分析到这里还没有结束,我们知道这1000个元素其实就是 -128~127之间所有的数重复了几遍组成的,然而我们知道 strlen操作符的结束标志是遇见’\0’, 并且’\0’的ASCLL值是0,也就是说当strlen遇见0时,它就会终止,在外面数组中遇见的第一个0就会被系统当作数组的长度,根据外面刚才的分析,可以得出,第一个0出现时有128+127=255个元素已经在数组中,所以系统会认为数组的长度为255.也就是打印255.


5.5 练习五🏁

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

这个代码也会死循环打印hello world,这是因为当循环走到 i 等于255时, i 再加一其实不是256,因为无符号char类型能够存储的最大数就是255,根据外面刚刚画的循环图,255加一后就会重新走到0,以此一直循环下去.


6. 总结🚩

在数据的存储中,还有一个比较重要的点是浮点型在内存中的存储,这个部分放在下一章节讲解.文章来源地址https://www.toymoban.com/news/detail-465386.html

🔎 下期预告: C语言进阶 🔍
\

到了这里,关于C语言学习分享(第八次)------数据的存储的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言学习(三十一)---结构体、联合体的在内存中的存储

    在上一篇文章中,我们学习了 枚举 、 位段 和 联合体 的相关内容,在文章的末尾,我们还差了关于 联合体的存储 问题的内容,今天我们将学习该部分的内容,好了,话不多说,开整!!! 结构体 在内存中是如何存储的呢,是按里面的变量内容,在 内存中的连续地址中存

    2024年02月12日
    浏览(40)
  • 第八次CCF计算机软件能力认证

    第一题:最大波动 小明正在利用股票的波动程度来研究股票。 小明拿到了一只股票每天收盘时的价格,他想知道,这只股票连续几天的最大波动值是多少,即在这几天中某天收盘价格与前一天收盘价格之差的绝对值最大是多少。 输入格式 输入的第一行包含了一个整数 n,表

    2024年02月15日
    浏览(38)
  • 视觉信息处理与FPGA实现第八次作业——verilog实现亮度调节

    HxD下载链接:https://download.csdn.net/download/weixin_44357071/89045331 解压直接打开exe就能使用。 将需要查看二进制数据的图片拖到软件框里就能读取 从000Eh(h是16进制的意思)到0035是真的有40byte.横坐标是零到16,竖坐标是像十进制一样,把个位数空出来,然后是10,20,30..... 图中框框里

    2024年04月16日
    浏览(37)
  • C语言学习:8、深入数据类型

    C语言中,如果需要用的整数大于int类型的最大值了怎么办? 我们知道int能表示的最大数是2147483647,最小的数是-2147483648,为什么? 因为字32位系统中,寄存器是32位的,寄存器中最高位表示符号位,0表示整数,1表示负数; 所以32位系统中int的最大值可以表示为0111 1111 1111

    2024年02月09日
    浏览(35)
  • 机器学习&&深度学习——NLP实战(自然语言推断——数据集)

    👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习深度学习——NLP实战(情感分析模型——textCNN实现) 📚订阅专栏:机器学习深度学习 希望文章对你们有所帮助 之前我们分别使用了RNN和textCNN实现了情感分析模型,这个任务的目的是将单

    2024年02月12日
    浏览(53)
  • 学习笔记-数据查询语言DQL

    1.基本语法 2.数据准备 3.简单查询 4.条件查询 (1)比较查询 (2).范围查询 (3).逻辑查询 (4).模糊查询 (5).非空查询 5.排序查询 ASC 升序 (默认) DESC 降序 6.聚合查询 7.分组查询 having与where的区别: 1).having是在分组后对数据进行过滤,where是在分组前对数据进行过滤 2).having后面可以使用分

    2024年02月02日
    浏览(64)
  • 学习大数据应该掌握哪些基础语言

    大数据技术的体系庞大且复杂,每年都会涌现出大量新的技术,目前大数据行业所涉及到的核心技术主要就是:数据采集、数据存储、数据清洗、数据查询分析和数据可视化。 学习大数据需要掌握什么语言基础? 1、Java基础 大数据框架90%以上都是使用Java开发语言,所以如果

    2024年02月09日
    浏览(42)
  • 数据的语言:学习数据可视化的实际应用

    数据可视化应该学什么?这是一个在信息时代越来越重要的问题。随着数据不断增长和积累,从社交媒体到企业业务,从科学研究到医疗健康,我们都面临着海量的数据。然而,数据本身往往是冰冷、抽象的数字,对于大多数人而言,很难从中获得实质性的信息。这时,数据

    2024年02月11日
    浏览(37)
  • R语言学习笔记--列表list、数据框

    1-列表 列表 可以包含不同类型的 对象 ,也就是说,列表不是将某些具体的值组织起来,而是组织R对象。列表将数据组织在一个一维集合中。 列表非常好用,因为它可以装任何类型的对象,不要求数据之间是同质的。 创建列表 list()  以上代码,创建了一个列表,其中第一个

    2024年02月15日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包