C语言:数据在内存中的存储

新手不会敲main 2024-08-26 16:05:02 阅读 62

数据在内存中的存储

一、大小端字节序的判断(一)大小端存储概念1、大端:2、小端

(二)为什么会有大小端呢(三)如何判断当前机器是大端还是小端

二、整形在数据中的存储(一)原码、反码、补码(二)整形存储例题剖析1、求下面代码的输出结果

2、求下面代码的输出结果3、求下面代码的输出结果

三、浮点型在数据中的存储(一)浮点数在内存中的存储

四、字符类型的取值范围(一)图解(二)例题剖析

五、结束语

一、大小端字节序的判断

(一)大小端存储概念

1、大端:

将一个数据的低位字节内容放在高地址处,高位字节内容放在低地址处。

我们以存放0x11223344为例。

在这里插入图片描述

2、小端

将一个数据的低位字节内容放在低地址处,高位字节内容放在高地址处。

在这里插入图片描述

(二)为什么会有大小端呢

计算机系统中,我们是以字节为单位的。但是除了char之外,还有int,short等大于一个字节的类型,这个时候就诞生了两种储存方式。我们常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式

还是小端模式。

(三)如何判断当前机器是大端还是小端

我们可以查看机器中数的存储情况,列如0x11223344,我们去拿它的第一字节,按照大端存储0x11223344,拿到的是0x11;按照小端存储,拿到的是0x44。

<code>#include<stdio.h>

int main() {

int num = 0x11223344;

char* p = (char*)&num;

printf("%#x", *p);

return 0;

}

二、整形在数据中的存储

(一)原码、反码、补码

正数的原、反、补码都相同。

负整数的三种表示方法各不相同。

原码

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

反码

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

补码

反码+1就得到补码。

(二)整形存储例题剖析

1、求下面代码的输出结果

<code>int main() {

char a = -1;

signed char b = -1;

unsigned char c = -1;

printf("%d\n%d\n%d", a, b, c);

return 0;

}

在这里插入图片描述

(1)对a分析

在这里插入图片描述

由于a是字符类型,所以这里应该截取低位一个字节作为存放的内容。

在这里插入图片描述

接着按照%d进行打印,需要进行整形提升。

在这里插入图片描述

接着打印它的原码,结果为-1。

在这里插入图片描述

(2)对b分析:(与a一致)

(3)对c分析

在这里插入图片描述

由于c是字符类型,所以这里应该截取低位一个字节作为存放的内容。

在这里插入图片描述

接着按照%d进行打印,需要进行整形提升。

在这里插入图片描述

结果为255

2、求下面代码的输出结果

<code>int main() {

char a = -128;

printf("%u", a);

return 0;

}

在这里插入图片描述

首先,128的原码,反码,补码如下

在这里插入图片描述

由于c是字符类型,所以这里应该截取低位一个字节作为存放的内容。

在这里插入图片描述

接着按照%u进行打印,需要进行整形提升。

在这里插入图片描述

%u认为它是个无符号整形,所以原码 = 反码 = 补码,这个数就是4,294,967,168

3、求下面代码的输出结果

<code>#include<stdio.h>

int main() {

int arr[] = { 1, 2, 3, 4 };

int* p1 = (int*)(&arr + 1);

int* p2 = (int*)((int)arr + 1);

//printf("%d\n%d", p1[-1], *p2)

printf("%x\n", p1[-1]);

printf("%x", *p2);

return 0;

}

p1和p2指针的指向如图所示

p1[-1]即为指针减一,减去四个字节读取结果为0x00000004

*p2读取结果为0x02000000

在这里插入图片描述

4 ;0x 02 00 00 00

三、浮点型在数据中的存储

(一)浮点数在内存中的存储

任何浮点数都可以表示为上面这种形式。

在这里插入图片描述

在这里插入图片描述

而浮点数在存储时,分为单精度和双精度两种形式。

单精度float有4个字节也就是32位

在这里插入图片描述

双精度double有8个字节64位

在这里插入图片描述

例如:5.5f

在这里插入图片描述

在这里插入图片描述

四、字符类型的取值范围

(一)图解

一个字符是一个字节,拥有8个比特位。如果是(signed char),那么第一位是符号位,可能的排列如下。

在这里插入图片描述

(二)例题剖析

<code>int main() {

char arr[1000];

for (int i = 0; i < 1000; i++) {

arr[i] = -1 - i;

}

printf("%d", strlen(arr));

return 0;

}

当-1减到第255次时arr[255] = 0,因此打印的长度是255.

在这里插入图片描述

五、结束语

那么这篇关于数据储存的文章就先写道这里吧,如果有用的话,记得给小编一个免费的赞,小编会努力带来更多有用的文章!

在这里插入图片描述



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。