栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

深度剖析数据在内存中的存储(C语言)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

深度剖析数据在内存中的存储(C语言)

文章目录
  • 本章重点
    • 数据类型介绍
      • 类型的基本归类
      • 整型在内存中的存储
        • 原码,反码,补码
        • 大端小端介绍
      • 练习
        • 第一题
        • 第二题
        • 第三题
        • 第四题

本章重点
  1. 数据类型详细介绍
  2. 整形在内存中的存储
  3. 大小端字节序介绍及判断
  4. 浮点型在内存中的存储解析
数据类型介绍

我们已经学习了基本的内置类型

char		//字符数据类型
short		//短整型
int			//整型
long		//长整型
long long		//更长的整型
float		//单精度浮点型
double		//双精度浮点型
//C语言中没有字符串类型

他们所占的存储空间大小.特别注意的是long>=int

类型的意义

  1. 使用这个类型开辟内存空间的大小(大小决定了使用范围)
  2. 如何看待内存空间的视角.
类型的基本归类
char 
		unsigned char
		signed char
short
		unsigned short [int]
		signed short [int]
int 
		unsigned int
		signed int
long 
		unsigned long [int]
		signed long [int]

[]当中的内容可以省略

数值
正数和负数:
有些数值只用正数,没有负数(身高)
有些数值有正数也有负数(温度)

浮点型家族

float
double

构造类型

> 数组类型
> 结构体类型 struct 
> 枚举类型 enum
> 联合类型 union

数组为什么也是构造类型?

int arr[5]
int arr[6]
char brr[5]

这就说明数组类型是不唯一的,所以也属于构造类型

指针类型

int* pi
char* pc
float* pf
void* pv

空类型

void标识空类型(无类型)
通常应用函数的返回值,函数的参数,指针类型

整型在内存中的存储

一个变量的创建是要在内存中开辟空间的.空间的大小是根据不同的类型决定的,接下来我们讲讲数据在所开辟内存中到底是如何存储的?

比如:

int a = 20;
int b = -10;

我们知道这里分别为a,b开辟四个字节的空间
究竟如何存储,我们首先要了解下面的概念:

原码,反码,补码

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

原码
直接将数值按照正负数的形式翻译成二进制就可以得到原码

反码
将原码的符号位不变,其它位依次按位取反就可以得到原码

补码
反码加1就可以得到补码

对于整型来说,数据存放到内存中其实存放的是补码
为什么呢?

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

原码-->补码
原码符号位不变,其它位按位取反再加1就可以得到补码
补码-->原码
1.补码减1,符号位不变,其它位置取反
2.补码取反加1得到原码

一个数值超过一个字节了,要存储在内存中就会有顺序的问题

假如

0x11223344
这个十六进制数字在内存中到底是怎么存储的呢?,
以下图,到底是哪一个存储方式,首先要了解大端和小端的概念

大端小端介绍

什么是大端小端

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

为什么有大端小端

为什么有大小端模式之分那?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元对应一个字节,一个字节8个比特位.但是在C语言中除了8个bite的char之外,还有16个bite的short,另外对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在一个如何将多个字节安排的问题.因此就导致了大端存储模式和小端存储模式.

一个数字权重低的是低位,
例如0x11223344
从右到左权重首先是16^0,16^1,依次升高


小端存储:是指数据的低位保存在内存中的低地址中,数据的高位保存在内存中的高地址中
大端存储:是指数据的低位保存在内存中的高地址中,数据的高位保存在内存中的低地址中
自己总结的口诀:小同大异
程序设计:

#include 

int main() {
    int a = 1;
    char* p = (char*)&a;
    if(*p == 1) {
        printf("小端n");
    }else {
        printf("大端n");
    }
}

思路:
1的十六进制表示为0x00 00 00 01
假设是小端存储就是这个样子:

假设是大端存储,是这个样子:

我们把这个int强转为char只取最低的地址,如果最低位中存放的是1,就是小端存储,如果是0就是大端存储

这里告诉同志们一个题外的知识:

未来在找工作的时候,这一类公司一定要小心:

  1. 你没有投递过这家公司
  2. 但是打电话让你去面试
    这其实都是培训机构,打着招聘的幌子在招生
注意:
1.内存中存放的是补码
2.整型表达式计算使用的内存中补码计算的
3.打印和我们看到的都是原码
练习 第一题
//输出什么
#include 

int main() {
    char a = -1;
    signed char b = -1;
    unsigned char c = -1;
    printf("%d %d %d", a, b, c);
    return 0;
}


又因为题目中定义的是char所以要发生截断,只保留前8个比特位所以-1就变为:

内存中存的也是如上图所示,打印的时候因为是%d,是十进制的整型,所以要发生整型提升,变为:

所以a和b的值都是-1,对于c的整型提升

第二题
#include 

int main() {
    char a = -128;
    printf("%un", a);
    return 0;
}
//%u  是打印无符号整型,认为内存中存放的补码对应是一个无符号数
//%d  是打印有符号整型,认为内存中存放的补码对应是一个有符号数 

内存中存放的是:

整型提升后:

最后是无符号打印,所以是

注意

我在看到这道题目的时候,误区整形提升看的是定义的时候,规定的是否是有无符号,不是看的打印时候规定的是有符号还是无符号的,%u打印的时候当成的是无符号,但实际还是一个有符号的数字

第三题
#include 

int main() {
    char a = 128;
    printf("%un", a);
    return 0;
}

首先发生截断:

最后结算的结果(其中的补码是整型提升得到的):

又因为这是个正数,所以原码,反码,补码相同

第四题
#include 

int main() {
    int i = -20;
    unsigned int j = 10;
    printf("%dn", i + j);
    return 0;
}



因为这是个正数,正数的原码,反码,补码相同,
最后将两个数的补码相加,得到后,转化为原码就可以了

最后讲一下,char类型数的范围

这里的二进制都是补码

注意

1.计算机中存的都是补码,显示出来的是原码
2.整型提升的时候看的是定义的时候是否有符号位
3.对于少于4个字节的数据类型,首先要按照int类型来求原码,反码,补码,最后截断存放到对应的地址中
4.正数的原码,反码,补码相同

最后的最后就是整型提升的方法:

整型提升是C程序设计语言中的一项规定:在表达式计算时,各种整形首先要提升为int类型,如果int类型不足以表示则要提升为unsigned int类型;然后执行表达式的运算。
提升规则:如果有符号按照符号补全如(10001111整型提升为11111111111111111111111110001111)
如果无符号整形提升,则直接补0

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1037014.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号