5.4_C语言类型转换

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 计算机组成原理之C语言类型转换

这个小结我们要探讨一个相对来说简单的问题,就是 c 语言里边的那些定点整数是如何进行强制类型转换的。

一、案例一

来看这样的一个例子。

首先需要跟大家声明的是, c 语言当中的定点整数,大家熟悉的什么 Int 还有什么 short 还有long,这些定点整数都是用补码的形式来存储的。

另外, c 语言里还有一个关键字叫unsigned,如果用 unsigned 来修饰 short 或者 Int 或者long,那就意味着这个定点整数它是一个无符号数。

现在有一个 short 型的短整数x,它的值是-4321。如下:
image.png

由于是采用补码表示的,并且短整形是占两个字节,也就是 16 个比特,所以 16 个比特的补码表示- 4321 应该是这样的一个值(如下)。这些大家可以自己转换一下。
image.png

原码补码如何转换,我们之前已经强调过,不熟悉的同学可以再自己动手试一下。

现在我们把 x 这个短整形的数强制转换成 unsigned short,也就是无符号的短整形y。这种强制转换的规则是,会把 x 的补码形式的数完整不变的复制给 y 变量

由于 y 也是占两个字节,所以 y 的机器代码其实和 x 是一模一样的。只不过由于 y 是一个无符号的短整形,因此计算机在解析 y 的真值的时候,会按照无符号整数来进行解析。所以把二进制无符号数转换成真值应该是对应值61215。如下:
image.png

这是一个有符号的定点整数,转换成长度相同的无符号定点整数的规则。不改变数据的二进制内容,但是会改变它的解释方式。

二、案例二

再看第二个例子。

如果我们把一个更长的数据,变成一个更短的数据,比如我们定义了两个 Int 型的变量 a 和b。

大多数情况下, c 语言里边 Int 型的数据占 4 个字节。
image.png

现在 a 和 b 是两个有符号的数,都用补码的形式来保存。当我们把 a 和 b 这两个数强制转换成short,也就是由 4 个字节变成 2 个字节的时候,计算机的做法是,直接把高位截断,只保留低位

①a对应的 16 进制应该是这样的(如下),把后四个字节的内容截断,只保留最低两个字节的内容,也就是 86A1。
image.png

更低的两个字节就是 c 变量的值。由于 c 是一个有符号的短整形,所以计算机会用补码的规则来对它进行解析。与之对应的真值应该是-31071这样的值,这是一个 16 比特 16 位的补码。
image.png

②对于 b 和 d 也是一样的, b这个数它用补码表示如下:
image.png

把 b 转换成只有两个字节的 d short 类型,只保留更低的两个字节7751。

同样的,由于 d 它是一个有符号的短整形,所以计算机会用 16 比特补码的方式来对它进行解析,与之对应的真值如下:
image.png

这是更长的数据转换成更短的数据的处理方式。很残暴,直接截断,只保留更低的字节。

三、案例三

最后再来看更短的数据转换成更长的数据。这个问题其实我们之前聊过,也就是所谓符号扩展的问题
image.png

x 原本是一个两个字节的补码,总共占 16 位。

把 short 型的 x 转换成 4 字节的 Int 型。计算机做的事情就是符号扩展

①先来看m变量

之前我们说过,对于一个定点整数的补码来说,如果它是一个负数,我们需要在高位,也就是符号位和原有的数值位之间添1,用这样的方式扩展得到的补码,你把它解析为真值,这个真值是不会变的,只不过是补码的整体长度拓展了而已。
image.png

②再来看n 变量

我们把 x 强制的转换为无符号类型,把它赋值给无符号的短整形n。

之前我们说过,这种强制转换会把二进制代码原封不动的复制给n,只不过计算机会以无符号数的规则来解析这一串机器数,这是 n 所对应的一个真值(如下)。
image.png

③变量p

最后把无符号数 n 变成 4 个字节的无符号数p。

由于是无符号数到无符号数的转变,因此直接在高位填 0 就可以了

p 和 n 的真值,这个真值是保持不变的。如下:
image.png

四、总结

这就是 c 语言里边定点整数相关的一些强制类型转换。
image.png

第一个部分探讨的是在转换的两种数据长度相同的情况下,无符号数和有符号数之间的一种转换规则。

第二个部分探讨的是从长数据强转成短数据的一个处理方式。

第三个部分探讨的是从短数据转为长数据的一个转变方式。

相关文章
|
7月前
|
程序员 编译器 C语言
『C语言进阶』隐式类型转换规则
『C语言进阶』隐式类型转换规则
|
7月前
|
安全 程序员 C语言
从C语言到C++_37(特殊类设计和C++类型转换)单例模式(下)
从C语言到C++_37(特殊类设计和C++类型转换)单例模式
59 5
|
7月前
|
设计模式 编译器 Linux
从C语言到C++_37(特殊类设计和C++类型转换)单例模式(中)
从C语言到C++_37(特殊类设计和C++类型转换)单例模式
47 0
|
7月前
|
安全 编译器 C语言
从C语言到C++_37(特殊类设计和C++类型转换)单例模式(上)
从C语言到C++_37(特殊类设计和C++类型转换)单例模式
44 0
|
存储 C语言
C语言入门(2)——数据类型、运算符、类型转换、控制语句
char short int long flout(默认保存小数点后6位,并且可以四舍五入) double 输出int类型的值%d 输出字符用%c 输出long用%ld 输出float用%f 输出double用%lf
143 0
|
7月前
|
存储 物联网 编译器
详解【C语言】类型转换--整型提升,算术
详解【C语言】类型转换--整型提升,算术
118 0
|
7月前
|
存储 编译器 C语言
C 语言:类型转换与常量的细致理解
有时,您必须将一种数据类型的值转换为另一种类型。这称为类型转换
153 0
|
编译器 C语言 C++
09 C++ - 更严格的类型转换(比较C语言)
09 C++ - 更严格的类型转换(比较C语言)
45 0
|
存储 程序员 编译器
【C语言】你不知道的隐式类型转换规则
本文接着C语言中的操作符(万字详解)讲解隐式类型转换规则,还有没学操作符的老铁可以回头看看。 在 C 语言中,类型转换的方式一般可分为隐式类型转换和显示类型转换(也称为强制类型转换)。 其中隐式类型转换由编译器自动进行,不需要程序员干预。 隐式类型转换通常有两种情况:整形提升和算术转换。
453 0
|
存储 编译器 C语言
【C语言初阶】表达式求值(隐式类型转换,算术转换)
目录 表达式求值 一、先补充一点(为下文做准备) 1.首先,要了解原码、反码、补码(简单说一下) 2.有符号(signed)与无符号(unsigned)的区别 二、隐式类型转换(整型提升) 1.什么是整型提升? 2.整型提升的意义 3.有符号(signed)类型的整型提升 3.无符号(unsigned)整形提升 4.简而言之 5.例子 三、算术转换 四、
244 0
【C语言初阶】表达式求值(隐式类型转换,算术转换)