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

C进阶(1)数据在内存中的存储(上)(数据类型、整型在内存的存储、原反补码、大小端、百度笔试)

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

C进阶(1)数据在内存中的存储(上)(数据类型、整型在内存的存储、原反补码、大小端、百度笔试)

1 数据类型介绍 1.1 C语言基本内置类型
C语言基本内置类型
大小(字节)类型
char1字符串数据类型
short2短整型
int4整型
long

4(32位机器上是4字节)

8(64位机器上是8字节)

长整型
long long8更长的整型
float4单精度浮点数
double8双精度浮点数
1.2 类型的意义

1.使用这个类型开辟空间内存的大小(大小决定了使用范围)

int a= 0 ; 

系统申请四个字节给a,那么a就可以用这四个字节来表示一个整型数值,取值范围为-2147483648~2147483647。

2.如何看待内存空间的视角

int a = 0 ;
float b = 0 ;

系统给a与b都申请了四个字节,但是看待它们是不一样的,系统认为a是整型,b是单精度浮点型。

1.3 类型的基本归类

1.3.1 整型家族

char
    unsigned char
    signed   char
short
    unsigned short [int]
    signed   short [int]
int
    unsigned int
    signed   int
long
    unsigned long [int]
    signed   long [int]
注:[]是可省略的意思

1.3.2 浮点型家族

float
double

1.3.3 构造类型

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

1.3.4 指针类型

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

1.3.5 空类型

void表示空类型
通常用于函数的返回类型、函数的参数、指针类型
2 整型在内存中的存储

一个变量的创建时在内存中开辟空间的。空间的大小是根据不同的类型决定的。

我们接下来将会解释数据在所开辟内存中到底是如何存储的。

例如:int a=10; 与 int b=-10;在内存中存储的方式与区别

2.1 原码、反码、补码

2.1.1 计算机中整数的三种2进制表示方法

计算机中的整数有三种2进制表示方法,即原码、反码和补码。

2.1.2 原码、反码和补码的组成

原码、反码和补码均是有符号位和数值位两部分组成,符号位都是用0表示“正”,用1表示“负”。数值位正整数的原码、反码和补码都是一样的,而负整数的三种表示方法各不相同。

2.1.3 负整数的三种表示方法

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

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

补码:反码+1得到补码

以-5为例
原码:10000000 00000000 00000000 00000101
反码:11111111 11111111 11111111 11111010
补码:11111111 11111111 11111111 11111011

2.1.4 数据存放内存中的其实是补码

为什么呢?

在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;

同时,加法和减法也可以统一处理(cpu只有加法器)此外,补码和原码相互转换的过程是相同的,不需要额外的硬件电路。

以-5为例,展示根据补码求原码的两种计算方法步骤:
-5的补码:11111111 11111111 11111111 11111011
1.根据求原码、反码和补码的方法逆用,来得出原码
补码-1=反码

反码:11111111 11111111 11111111 11111010

反码除符号位不变,其他位按位取反得到原码

原码:10000000 00000000 00000000 00000101
2.按照原码转换成补码的方法
符号位不变,其他位按位取反
100000000 00000000 00000000 00000100
加一得到原码
100000000 00000000 00000000 00000101
由此可见,结果是一样的。

 

加法和减法
6-5=1
6的补码即原码: 00000000 00000000 00000000 00000110
-5的补码:     11111111 11111111 11111111 11111011
             -----------------------------------
6-5的结果是:  00000000 00000000 00000000 00000001
存补码实现了加法和减法运算方法的统一,这样就不需要额外的减法器
2.2 大小端介绍

它们的在内存中存储的顺序是像上面写的那样吗?

int a=5;
int b=-5;

 

 注:内存1是a地址,内存2是b地址。

由此可见,并非是按照正着放(00 00 00 05以5为例)的形式放的,而是数值的低位放在了低地址上,高位放在了高地址上

2.2.1 什么是大小端

大端[存储]模式:数据的低位放在内存的高地址中,数据的高位放在内存的低地址中(低放高,高放低)

小端[存储]模式:数据的低位放在内存的低地址中,数据的高位放在内存的高地址中(低放低,高放高)

                     0x11223344

    数据:高位-----<------低位

    内存:   地位----->------高位

2.2.2 为什么要有大端和小端

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

2.2.3 关于大端小端的练习

百度2015年系统工程师笔试题

请简述大端字节序和小端字节序的概念,设计以恶搞小程序来判断当前机器的字节序。

 分析:

int a = 1 ;

如果是小端那么就是

01 00 00 00

如果是大端那么就是

00 00 00 01

&a是int *类型

*(char*)&a

char*可以截取a地址值的前一个字节。

*(char*)&a=1的话就是小端,否则就是大端

#include
int check_sys()
{
    int i=1;
    return (*(char*)&i);
}
int main()
{
    int ret=check_sys();
    if(ret==1)
    {
        printf("小端n");
    }
    else
    {
        printf("大端n");
    }
    reurn 0;
}

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

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

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