C语言修炼之路数据类型悟正法 解析存储定风魔下篇

目录
  • (壹)大端小端藏端倪
    • 1.1 什么是大端小端
    • 1.2 大端小端模式
      • 1)大端模式:
      • 2)小端模式:
    • 1.3 为什么有大端和小端
    • 1.4 如何判断机器的字节序
  • (二) 浮点型在内存中的存储
    • 2.1 浮点数在内存中的储存
    • 2.2 题目解释

(壹)大端小端藏端倪

1.1  什么是大端小端

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

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

1.2  大端小端模式

1)大端模式:

低地址 -----------------> 高地址

0x0A  |  0x0B  |  0x0C  |  0x0D

2)小端模式:

低地址 ------------------> 高地址

0x0D  |  0x0C  |  0x0B  |  0x0A

1.3  为什么有大端和小端

为什么会有大小端模式之分呢?

这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。

但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如果将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。

例如:

一个 16bit 的 short 型 x ,在内存中的地址为 0x0010,x 的值为0x1122,那么0x11为高字节,0x22为低字节。对于大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小

端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。

1.4  如何判断机器的字节序

一般都是通过 union 来测试的,下面这段代码可以用来测试一下你的编译器是大端模式还是小端模式:

 union 型数据所占的空间等于其最大的成员所占的空间。

对 union 型的成员的存取都是相对于该联合体基地址的偏移量为 0 处开始,也就是联合体的访问不论对哪个变量的存取都是从 union 的首地址位置开始。

联合是一个在同一个存储空间里存储不同类型数据的数据类型。这些存储区的地址都是一样的,联合里不同存储区的内存是重叠的,修改了任何一个其他的会受影响。那么通过强制类型转换,判断其实存储位置,也可以测试大小端了:

(二) 浮点型在内存中的存储

常见的浮点数:

3.14159 1E10

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

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

浮点数存储的例子:

 输出的结果是什么呢?

num和*pFloat在内存中明明是同一个数,为什么浮点数和整数的解读结果会差别这么大?

要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。

2.1  浮点数在内存中的储存

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

举例来说:

十进制的 5.0 ,写成二进制是101.0,相当于 1.01×2^2 。 那么,按照上面V的格式,可以得出 s=0,M=1.01,E=2。 

十进制的 - 5.0,写成二进制是 -101.0,相当于 -1.01×2^2。那么,s=1,M=1.01,E=2。 

IEEE 754规定:

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

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

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

前面说过,1≤M<2,也就是说,M可以写成1.xxxxxx的形式,其中xxxxxx表示小数部分。

IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。

比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。 

至于指数E,情况就比较复杂。

首先,E 为一个无符号整数(unsigned int) 这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。

但是,我们知道,科学计数法中的 E是可以出现负数 的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。比如,2^10的E是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

然后,指数E从内存中取出还可以再分成三种情况:

①E不全为0或不全为1

 ②E全为0

 ③E全为1

2.2  题目解释

下面,让我们回到一开始的问题:为什么0x00000009还原成浮点数,就成了0.000000?

首先,将0x00000009拆分,得到第一位符号位s=0,后面8位的指数E=00000000,最后23位的有效数字M=000 0000 0000 0000 00001001。

由于指数E全为0,所以符合上一节的第二种情况。因此,浮点数V就写成:

V=(-1)^0 ×0.00000000000000000001001×2^(-126)=1.001×2^(-146)

显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000。 

再看例题的第二部分。 请问浮点数9.0,如何用二进制表示?还原成十进制又是多少? 首先,浮点数9.0等于二进制的1001.0,即1.001×2^3。

那么,第一位的符号位s=0,有效数字M等于001后面再加20个0,凑满23位,指数E等于3+127=130,即10000010。 所以,写成二进制形式,应该是s+E+M,即

这个32位的二进制数,还原成十进制,正是1091567616。 

到此这篇关于C语言修炼之路数据类型悟正法 解析存储定风魔下篇的文章就介绍到这了,更多相关C语言 数据类型内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言中的浮点数据类型

    目录 1. 处理带小数的数值 2. 浮点类型 3. 浮点类型的sizeof 1. 处理带小数的数值 我们来讨论一下类似于1.234567,0.00001,这类非整数的数据.我们先试试看,int能不能装这些数据呢? #include <stdio.h> int main() { int a = 1.234567; int b = 0.00001; int c = 365.12345; printf("%d\n", a); printf("%d\n", b)

  • C语言实现 数据类型占多少字节指针占多少字节

    具体代码如下所示: #include<stdio.h> void main() { //使用sizeof验证数据类型在内存中占用的空间大小 // char // int // short // long // unsigned int // float // double // long double printf("在64位机器中:\n"); printf(" char类型占%d个字节\n",sizeof(char)); printf(" s

  • 详解C语言的基本数据类型

    目录 1.C语言基本数据类型 2.计算机中的单位 3.各数据类型的大小及字取值大小 总结 1.C语言基本数据类型 2.计算机中的单位 3.各数据类型的大小及字取值大小 对于short int .int .long int.long long int,虽然都为整形数据类型,但是在存储像年龄.特定的尺寸及尺寸等数值比较小的整型数据时,没必要用long long int 甚至是int去存储该类数据,因为这样会浪费计算及的存储的内存,但是当需要存储相当大的数据时,就需要用到long longint这样的

  • C语言自定义数据类型的结构体、枚举和联合详解

    结构体基础知识 首先结构体的出现是因为我们使用C语言的基本类型无法满足我们的需求,比如我们要描述一本书,就需要书名,作者,价格,出版社等等一系列的属性,无疑C语言的基本数据类型无法解决,所以就出现了最重要的自定义数据类型,结构体. 首先我们创建一个书的结构体类型来认识一下 struct Book { char name[20]; char author[20]; int price; }; 首先是struct是结构体关键字,用来告诉编译器你这里声明的是一个结构体类型而不是其他的东西,然后是Boo

  • C语言入门之浅谈数据类型和变量常量

    目录 1.变量的作用域: 2.变量的生命周期: 1.字面常量,如:100,‘v’: 2.define宏定义的标识符常量 3.const修饰的常变量 4.枚举常量 总结 首先我们来罗列一下C语言的基本数据类型(未提及的后续将在关键字专题讲解): 类型名称 所占字节 char(字符型) %c 2 short(短整形) %d 2 int(整形) %d 4 long int(长整形) %ld 4 long long int(长整形) %lld 8 float(单精度浮点型) %f 4 double(双精

  • C语言关于自定义数据类型之枚举和联合体详解

    目录 前言 枚举 枚举类型的定义 枚举类型的优点 枚举类型的使用 枚举中需要注意的点 联合体 联合体类型的定义 联合体的特点 联合体的使用 联合体存在内存对齐 结语 前言 在C语言的自定义数据类型中,除了我们最为常用的结构体之外,还有两个比较少用的自定义数据类型,分别为枚举和联合体(也可以称为共用体). 今天,我们一起看学习一下相关的知识吧! 枚举 什么是枚举? 顾名思义,就是一一列举,把所有的情况,所有的取值,一一列举出来. 在我们生活中,有不少的东西是可以全部列举出来的. 如一个星期有七天,

  • C语言入门篇--初识C语言及数据类型

    目录 1. 什么是C语言? 2.第一个C程序&&知识点 2.1 头文件 2.2 main函数 2.3 函数调用 2.4 return 0; 3. 数据类型 3.1 C语言数据类型 3.2 为什么有这么多数据类型? 3.3 各个数据类型的大小 1. 什么是C语言? (1)C语言是面向过程.编译型的编程语言(与C++.Java等面向对象的编程语言有所不同,ps:C与C++是兼容的),经过编译后最终形成可执行程序(即exe,可直接运行). (2)C语言非常经典,一般会在底层开发使用,Linux.

  • C语言数据类型枚举enum全面详解示例教程

    目录 一.枚举类型的定义 二.枚举类型的使用 2.1创建变量 2.2一些优点 总结 一.枚举类型的定义 enum Day//enum Day是一种类型 { Mon,//周一到周日这些叫枚举的可能取值,也叫枚举常量 Tue, Wed, Thur, Fri, Sat, Sun, }; 上述代码定义的enum Day是一种枚举类型,{}中内容是枚举类型的可能取值,也可叫作枚举常量. 这些枚举常量都是有值的,默认从0开始,依次往后递增1,如果你愿意赋值也是可以的. 代码如下: #include<stdi

  • C语言菜鸟基础教程之数据类型

    C语言的数据类型有整型.浮点型(就是小数).字符.字符串.数组.结构体等.刚开始学的时候,不要一下子学太多.先学最基本的整型.浮点型和字符. 对于学习程序来说,最重要的是动手操作. 先编写程序: #include <stdio.h> int main() { int a = 1; printf("a = %d\n", a); float b = 2.2; printf("b = %f\n", b); char c = 'A'; printf("

  • C语言修炼之路数据类型悟正法 解析存储定风魔下篇

    目录 (壹)大端小端藏端倪 1.1 什么是大端小端 1.2 大端小端模式 1)大端模式: 2)小端模式: 1.3 为什么有大端和小端 1.4 如何判断机器的字节序 (二) 浮点型在内存中的存储 2.1 浮点数在内存中的储存 2.2 题目解释 (壹)大端小端藏端倪 1.1  什么是大端小端 大端(存储)模式,是指数据的低位保存在内存的高地址中,而数据的高位,保存在内存的低地址中: 小端(存储)模式,是指数据的低位保存在内存的低地址中,而数据的高位,,保存在内存的高地址中. 1.2  大端小端模式

  • C语言修炼之路数据类型悟正法 解析存储定风魔上篇

    目录 (壹) 数据类型介绍 1.1  类型的基本归类 (贰)整形在内存中的存储 2.1  原码.反码.补码 2.2  深入解析 举例解析1: 举例解析2 (壹) 数据类型介绍 前面我们已经学习了基本的内置类型,以及他们所占存储空间的大小.: 类型的意义: 使用这个类型开辟内存空间的大小(大小决定了使用范围). 如何看待内存空间的视角. 1.1  类型的基本归类 整形家族: 浮点数家族: 构造类型: 指针类型 空类型: (贰)整形在内存中的存储 我们之前讲过一个变量的创建是要在内存中开辟空间的.

  • C语言修炼之路悟彻数组真妙理 巧用下标破万敌下篇

    目录 (壹)冒泡排序 1.1冒泡排序的设计 1.2冒泡排序的步骤 1.3冒泡排序的实现 (贰)数组作为函数参数 2.1冒泡排序函数的错误设计 2.2冒泡排序函数的正确设计 (叁)对数组名的拓展解析 (壹)冒泡排序 1.1冒泡排序的设计 冒泡排序(Bubble Sort)也是一种简单直观的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢

  • C语言修炼之路灵根孕育源流出 初识C言大道生上篇

    目录 试问C语言为何物 壹 贰 叁 你好世界 巧手独创C世界 创建新项目 创建源文件 main函数 第一个程序 运行代码 初悟数据类型 前置知识 数据概念初识 变量?常量? 本文Gitee仓库地址:文章源代码 试问C语言为何物 壹 C语言是一门通用计算机编程语言,广泛应用于底层开发.C语言的设计目标是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言. 贰 尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的

  • C语言修炼之路初识指针阴阳窍 地址还归大道真上篇

    目录 (壹) 敢问指针为何物 1.1 指针的概念 1.2 指针的背后 (贰) 指针和指针类 2.1 指针的类型 2.2 指针类型的意义 2.3 指针的解引用 (壹)  敢问指针为何物 1.1  指针的概念 在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值.由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元.因此,将地址形象化的称为“指针”.意思是通过它能找到以它为地址的内存单元. 那我们就可以这样

  • C语言修炼之路初识指针阴阳窍 地址还归大道真下篇

    目录 (壹) 行经旅途遇猛虎--“野指针” 1.1野指针成因 1.指针未初始化 2.指针越界访问 3. 指针指向的空间释放 1.2 巧法规避野指针 (贰) 指针之运算 2.1 指针+-整数 2.2 指针-指针 课堂小补充 (利用指针-指针实现strlen) (叁) 指针和数组 3.1 数组名 3.2 二级指针 3.3 指针数组 (壹)  行经旅途遇猛虎 -- “野指针” 概念:野指针就是指针指向的位置是不可知的(随机的.不正确的.没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变

  • C语言修炼之路灵根孕育源流出 初识C言大道生下篇

    目录 变量的作用域和生命周期 作用域 生命周期 常量 字面常量 const修饰的常变量 #define定义的标识符常量 枚举常量 字符串 初始字符串 库函数 转义字符 笔试题 注释 注释风格 往期文章:C语言修炼之路灵根孕育源流出 初识C言大道生上篇 变量的作用域和生命周期 作用域 作用域(scope),程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域. 局部变量的作用域是变量所在的局部范围. 全局变量的作用域是整个工程.

  • C语言修炼之路初识分支句 循环助本心下篇

    目录 前引 (壹)while语句 1.1while的执行流程 1.2while语句中的break和continue 1.2.1 break介绍 1.2.2 continue介绍 (贰)for循环 2.1语法 2.1.1  实际的问题: 2.2执行流程 2.3while和for对比 2.4break和continue 2.5小建议 一道笔试题 (叁)do...while()循环 3.1do语句的语法: 3.2执行流程 3.3do语句的特点 课后小练习 C语言修炼之路初识分支句 循环助本心上篇 前引

  • C语言修炼之路初识分支句 循环助本心上篇

    目录 何为语句 分支语句(选择结构) if语句 多条语句的if结构 悬空else if书写形式的对比 课堂练习 Switch语句 语句项 在switch语句中的break 编程好习惯 default子句 编程好习惯 练习 C语言修炼之路灵根孕育源流出 初识C言大道生下篇 C语言修炼之路灵根孕育源流出 初识C言大道生下篇 C语言修炼之路灵根孕育源流出 初识C言大道生上篇 C语言修炼之路灵根孕育源流出 初识C言大道生上篇 何为语句 C语言中由一个分号;隔开的就是一条语句. printf("hehe&

  • C语言修炼之路函数篇真题训练下

      本文的Gitee地址:文章源代码 第壹题 :字符串逆序(递归实现) 方法一,非递归实现 main主体部分 数组名是首元素的地址 首元素是char类型,对应的传参元素过去就是  char*  类型 采用两个指针不断移动,然后交换两个位置的元素来实现逆序 方法贰,递归实现 大致思路 代码实现 (推荐自己手动模拟一下) void reverse_string(char* str) { int len = strlen(str); char tmp = str[0]; str[0] = str[le

随机推荐