首页 > 作文

c语言 数据存储与原码 反码 补码详细解析

更新时间:2023-04-04 23:43:05 阅读: 评论:0

目录
前言1.数据的类型介绍1.1整形家族2.整形在数据内存中的存储2.1 原码 反码和补码(三种整型数的表示方法)2.2大小端字节序序的介绍2.3 练习3.浮点型在内存中的存储3.1 先举一个例子3.2 浮点数储存的规则

前言

学习本章你会了解:

1.数据类型详细介绍

2.整形在内存中的存储:以及了解原码、补码、反码

3.大小端字节序的介绍和判断

4.浮点型在内存中的存储解析

1.数据的类型介绍

在学习数据储存之前,让我们先认识一下数据类型。以下这些数据类型是我们初学c语言时的基础类型以及大小所占字节数。

比如所占字节数类型char1//符数据的类型shot2//短整型int4//整形long (规定sizeof(long)>=sizeof(int) )4//长整型long long(部分编译器不支持)8//更长的起整数float4//单精度浮点数double8//双精度浮点数

还有构造类型:

数组类型

结构体类型struct

枚举类型enum

联合类型union

指针类型:

int* pa;

char* pb;

float* pc;

void* pd;

除了以上类型,实际上还有布尔类型:_bool(专门用来表示真假的类型)

举个栗子(在c99中可用)

#include<stdio.h>#include<stdbool>main(){_bool flag=true;if(flat)printf("hello world")return 0;}              //结果就会打印一个hello world

1.1整形家族

整形家族中包括int short long,还有char。

char也是整形家族中的吗?

答案是:是的,因为char对应的字符的ascii码值中,字符对应的就是整形。

在这些整形类型之中,还可以分为无符号整形和有符号整型:

int=signed int

short=signed short

long=signed long

那是否char 等于signed char呢

结果又跟其他整形家族中的成员不同,在标准情况下char不是等于sign char~(但是在常规编译器中是相等的)。

2.整形在数据内存中的存储

我们知道变量创建就是开辟空间,开辟空间的大小由数据的类型来决定。

那么数据在所在的空间是怎样储存的呢?

在vs2019中输入:

int    a=20;int    b=-10;

就代表在内存中开辟四个字节的空间

其中14 00 00 00 就是a十六进制对应反码的值

和前面相同,f6 ff ff ff就是b十六进制对应反码的值

我们都知道计算机都是以二进制来存储信息,那为什么在内存图中看到的是十六进制呢?

这仅仅是便于观察,当以十六进制储存时,有没有感到反码有点长呢,如果换成二进制就更不宜观察了,故规定以十六进制来保存。

提到这里,什么是反码呢?为什么又反码的出现呢?

2.1 原码 反码和补码卓文君与司马相如(三种整型数的表示方法)

原码:原码就是数字对应二进制的表示方法,其中最后一位数字是符号位,表示正负的,

而小字节序就是二进制对应的是数。

如a的原码是:00000000000000000000 1010

反码:反码的数值就是在原码的基础之上进行转换过来的,当数值为正数时,反码的数据大小跟原码相同,当数值是负数是,其反码的值就是在原码的基础上,除了符号位,其他位都是按位取反。

补码:补码数值为正数时,其值大小就是原码,为负时,其值的大小就是在反码的基础之上,在进行加一。

原码得到补码取反加一即可,其实补码得到原码也是取反加一(感兴趣的可以试试)

举个栗子:

a的原码 反码 补码

原:0000000000000000 00010100

反:0000000000000000 00010100

补:0000000000000000 00010100

b的原码 反码 补码

原:1000 0000 00000000 0000 1010

反:1111 1111 1111 111111110101

补:1111 1111 1111 11111111 0110

那我们系统会出现原码反码和补码三种表示方法呢,一种表示方法不行吗?

我们能想到的,科学家也能想到,但一种表示方法有缺陷。

就比如说:当计算1+(-1)的时候(计算机只能实现加法的运算)

统一用原码的结果是

0000000000000000 00000001

10000000000000000000 0001

结果是10000000000000000000 0010

用补码计算的结果是:

00000000000000000000 0001

0111 1111 11111111 1111 1111

结果是10吴山天风00 0000000000000000 0000 也就是0

你是不是瞬间知道为什么要三种表示方法,为什么有补码的存在了

有没有get到科学家的伟大之处

2.2大小端字节序序的介绍

大小端字节序分别是哪一种?

a在内存中的数值44 33 22 11就是小端字节序

那大端字节序就是11 2大学社团有哪些2 33 44

大小端字节序的定义是什么?

大端字节序:当一个数的低字节序放在高地址处,或者高字节序的放在低地址处时,就是我们所说的大端字节序。

小端字节序:当一个数的高字节序放在低地址处,或者低字节序的放在高地址处时,就是我们所说的小端字节序。

放在倒着就是小端字节序,记住它即可。

为什么数据要分大小端字节序呢?

大小端字节序来源于于乔纳森·斯威夫特的小说《格列佛游记》,这是因为在计算机系统中,我们都是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit,但是在c语言中除了8bit的char之外,还有16bit的short型,32bit的long型(看具体编译器),另外,对于位数大于8位的处理器,例外16位的或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节序排序的问题。因此就导致了大端存储模式,和小端存储模式。

那么怎么判断大小端字节序呢?

下面由一个例题来讲解:(这是百度2015年系统工程师的笔试题)

用代码来判断系统大小端字节序:

int a; char*pa=(char*)&a; if(*pa==1) printf("小端字节序“); el printf(“大端字节序”);

2.3 练习

题一:

//输出结果是什么#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}

输出的结果分别是-1 -1 255

前面两个很容易理解 signed char与char意思都是有符号的整数,所以打印的结果都是-1.

都是对于无符号来说这时候就要进行整形提升了

当char型以整形来打印时过程如下:

原码:10000001

反码:11111110

补码:11111111

unsigned整形提升后:0000 00000000 0000 1111 1111

这是的补码同样也是:0000 00000000 0000 1111 1111

就是最终c的值。

题二:

​#include<stdio.h> int main(){char a=-128;printf(%u\n",a);  //u就是以无符号的类型打印出来return 0;}

-128的原码: 1000 00000000 0000 1000 0000

反码1111 11111111 1111 0111 1111

补码1111 11111111 1111 1000 0000

因为是char型 补码提取后:10000000

正进行整形提升,因为char是无符号整形,所以提升后:

1111 11111111 1111 1000 0000

再以无符号整形形式打印后原反补相同即:1111 11111111 1111 1000 0000

再转化成十进制:4294967169

运行证明以如下

数据的范围是多少呢?unsigned char与char存放的数据是否相等呢?

事实证明char与unsigned char数据范围并不一样

char的整形数据范围是-128~127,而unsigned char的范围是0~255;

(short 与unsigned short的整形取值范围也不一样

short的整形数据范围是-32768~32767,而unsigned short能存储的数据范围则是0~65535

3.浮点型在内存中的存储

首先列出一个常见浮点数表示方法:

1e10 可能你并不知道这是什么意思;

实际上他的意思是1.0*10^10;

3.1 先举一个例子

#include<stdio.h>int main(){int n=9;float*pfloat=(float*)&n;printf("n的值为:%d\n",n);printf("*pfloat的值为:%f\n",pfloat);*pfloat=9.0;printf("num的值为:%d\n",n);printf("*pfloat的值为:%f\n",*pfloat);return 0;}

n的值为:9

*pfloat的值为:0.00

num的值为:1091567616

*pfloat的值为:9.000000

这个结果是否跟你想的一样呢?

其实n的值与最后一个*pfloat的值可能我们很容易知道(也可能是猜的 哈哈)

在求解这道题之前让我们先了解这个题的知识吧~

3.2 浮点数储存的规则

ieee(电气和电子工程协会754标准)标准规定:

任何二进制的浮点数都可以以这种标准表示出来:

基本公式是:(-1)^s*m*2^e;(这里的e是无符号类型)

其中m是有效数子,e是指数,s用六三三学制来表示正负;

举个栗子:

5.5——10进制的表示

转化为二进制的结果是:101.1;

用公式表示为:(-1)^0 (1.011)*2^2 此时s=0,m=1.011,e=2;

对于64位浮点数,最高位1位是符号位s,接着是11位是指数e, 剩下的52位是有效数字。

如果e为八位,他的取值范围0~255,如果e为11为,他的取值范围0~2047;

有两个极限

当e为0时,此时的真实的e为1-127=-126;此时的数值根据公式,也就是无限接近与0;

当e为254时,此时的真实的e为254-127=127;此时的数值根据公式,也就是无穷大。

说到这里,你可能有一点疑惑,为什么都要减一个127,这是因为避免出现e为负数的情况(因为这里的e是无符号整形),在真实的e的基础上加了127,所以为了得到求出真实的e,就需要减去一个12党在我心中演讲稿7.

现在回到原来的题目之上

0000 00000000 00000000 00000000 1001–九的原码反码与补码。

这里的0 是 s;00000000为e;0000000000000000001001为m

此时(-1)^0*0.00000001*10*2^(-126)

由于float默认只打印小数点后六位,所以最终打印0.000000;

九的转化位二进制:1.001;

1.001*2^3

=0 m=1.001 e=3;

0100 0001 0001 0000 0000 0000 0000 0000

再以整形的形式打印的话,此时的值就是0100 0001 0001 0000 0000 0000 0000 0000就是num的补码,由于符号位是0,所以最终的原码等于补码。也就是1091567616

如果以浮点型打印的话也就是9.000000

结语:

写的很长时间,如果有用就收藏吧

到此这篇关于c语言 数据存储与原码 反码 补码详细解析的文章就介绍到这了,更多相关c语言 数据存储内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 23:43:03,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/ed7be3320203afdfec9f4d0e0f0e0b41.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:c语言 数据存储与原码 反码 补码详细解析.doc

本文 PDF 下载地址:c语言 数据存储与原码 反码 补码详细解析.pdf

标签:反码   补码   字节   原码
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图