一篇文章带你了解C语言中数据的存储

您所在的位置:网站首页 c语言数据类型详解 一篇文章带你了解C语言中数据的存储

一篇文章带你了解C语言中数据的存储

#一篇文章带你了解C语言中数据的存储| 来源: 网络整理| 查看: 265

目录

1.数据类型介绍

1.1类型的基本归类

2.整形在数据中的存储

2.1原码,反码,补码

 2.2 大小端的介绍

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

3.1 一个例子

3.2 浮点数存储规则

1.数据类型介绍

                                                        他们的内存中所占的大小是

char                   字符数据类型        1个字节

shory                  短整型                  2个字节

int                       整形                      4个字节

long                    长整型                   4个字节

long long            更长整形                8个字节

float                    单精度浮点型         4个字节

double                双精度浮点型         8个字节

类型的意义:

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

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

1.1类型的基本归类

整形家族:

char       

(字符里面存储的时候存储的是ASCVII码值,ASCVII码是整数,所以属于整形家族)

        unsigned char

        signed char

short

        unsigned short [int]

        signed short [int]

int

        unsigned int

        signed int

long

        unsigned long [int]

        signed long [int]

long long

        unsigned long long [int]

        signed long long[int]

浮点数家族:

float double

自定义类型:

数组类型        

结构体类型        sturct

枚举类型            enum

联合类型            union

指针类型:

int *p;

char *p;

float *p;

void *p;

空类型:

void 表示空类型(无类型)通常应用于函数的返回类型、函数的参数、指针类型 2.整形在数据中的存储

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

例如:

int a=20; int b=-10;

我们只知道为a,b分配四个字节大小的空间,想知道如何储存,我们就要了解原码,反码,补码的概念。

2.1原码,反码,补码

计算机中的整数有三种2进制表示方法,分别是原码,反码,补码。

三种表示方法均有符号位和数值位两部分

第一位被称为符号位,符号位用“0”表示“正”,用“1”表示“负”

后面的被称为数值位

正数的原码,反码,补码相同。

负整数的三种表示的方法各不同,要通过计算得到。

原码:直接将数值按照正负数的新式翻译成二进制就可以得到原码。反码:原码的符号位不变,其他位以此按位取反就可以得到反码。补码:反码+1就得到补码。

整形在内存中存的是二进制的补码

为什么不存原码,反码呢?

在计算机系统中,数值一律用补码来表示和存储。

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

这里我们定义一个正数

#include int main() { int a=20; return 0; }

首先20是个正数,他的符号位是 0 ,它的二进制序列是 10100,而整数占4个字节,一个字节又是8个bit位,所以一共32个bit位,所以我们写出20的二进制序列因该写够32个bit位,所以整体如下图:

 内存中存储的是二进制的补码,但是在窗口中是用16进制展示,因为如果用二进制展示的话数字太长了,不利于我们观察,我们取出a的地址,如下图:

这里我们定义一个负数

#include int main() { int b=-10; return 0; }

首先-10是一个负数,所以它的符号位为 1 ,10的二进制序列是1010,它的原码,反码,补码如下图。

 然后我们取出b的地址,看看他在内存中存储的是什么,当然,我们还是要把它转换成十六进制,这样方便我们观察。

 

上面我们提到过,CPU只有加法器,那如果碰到了减法怎么计算呢?看完下面这个例子大家就明白了,同时大家也能更清楚的理解为什么数据存放内存中要放补码。

#include int main() { int a = 1; int b = 1; int c = a - b; return 0; }

因为CPU只有加法器,所以它会把1-1转换成1+(-1)

首先我们先用它的原码计算一遍看看

 既然证明的原码相加是行不通的,我们再来看看补码相加

 2.2 大小端的介绍

 在上面我们发现数据在内存中是倒着存放的,为什么呢?继续往下看就会明白了。

什么是大小端;

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

概念看起来还是有点模糊,下面我还是画图为大家展示。

为什么有大端和小端:

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

 总结:正着放是大端存储,倒着放是小端存储,没有优劣之分,只是选择的不同。

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

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

(10分)

关于第一问我们只要理解了大小端的概念就很容易,有难度的是怎么写出这个小程序。

思路:

        首先我们发现大端存储和小段存储的区别非常明显,我们只需要对比第一个字节就能知道,具体思路如下图。

 完整代码:

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

运行结果:

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

常见的浮点数:

3.14159

1E10

浮点数家族包括: float、double、long double 类型。

浮点数表示的范围:float.h中定义

3.1 一个例子 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; }

运行结果:

这个例子告诉我们:

当一个数义整数的形式存进去,再以整形的形式往外拿是没有问题的,

但是以整形的形式存进去,浮点型的形式往外拿就不一样了。 

而当一个数以浮点数的形式存进去,再以浮点数的形式往外拿是没有问题的,

但是以浮点数的形式存进去,再以整数的形式往外拿就不一样的。

也间接的告诉了我们整形的存储方式和浮点型的存储方式是大不一样的。

3.2 浮点数存储规则

详细解读:

根据国际标准IEEE(电器和电子工程协会) 757 ,任意一个二进制浮点数V可以表示成下面的形式:

(-1)^S * M * 2^E

(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。

M表示有效数字,大于等于1,小于2。

2^E表示指数位。

举个例子:5.5的换算

 这时我们再套入公式:

然后我们发现任何一个浮点数只是 S M E在发生变化,所以我们只需要存储这三个数就行了。

IEEE 754规定:

对于32位的浮点数,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。

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

 IEEE 754对有效数字M和指数E,还有一些特别规定。

前面说过, 1≤M



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3