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

本文详细介绍了C语言的基本内置数据类型,包括整型、浮点型、构造类型和指针类型等,以及它们在内存中的存储方式。讨论了原码、反码、补码的概念以及在计算机中数据为何以补码形式存储。此外,还阐述了大小端存储模式的区别及其在数据存储中的作用。最后,提供了一种通过编程判断系统字节序的方法。
摘要由CSDN通过智能技术生成

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<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");
    }
    reurn 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潮.eth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值