【C】LV1-01-C语言-1数据类型
摘要:
本文主要是记录C语言
笔记——数据类型。
一、数据表示
1.数值数据
十进制 | 二进制 | 八进制 | 十六进制 |
0 | 0000 | 0 | 0 |
1 | 0001 | 1 | 1 |
2 | 0010 | 2 | 2 |
3 | 0011 | 3 | 3 |
4 | 0100 | 4 | 4 |
5 | 0101 | 5 | 5 |
6 | 0110 | 6 | 6 |
7 | 0111 | 7 | 7 |
8 | 1000 | 10 | 8 |
9 | 1001 | 11 | 9 |
10 | 1010 | 12 | a |
11 | 1011 | 13 | b |
12 | 1100 | 14 | c |
13 | 1101 | 15 | d |
14 | 1110 | 16 | e |
15 | 1111 | 17 | f |
2.非数值数据(ASCII
)
二、数据类型
1.原码、反码、补码
- 机器数
机器数就是一个数在计算机中的二进制表示,计算机中机器数的最高位是符号位,正数符号位为0
,负数符号位为1
。机器数包含原码、反码和补码三种表示形式。
如:数字3
若用8
位二进制数表示,则机器数为0000 0011
,数字-3
若用8
位二进制数表示,则机器数为1000 0011
。
- 机器数的真值
真值就是带符号位的机器数对应的真正数值。
如:机器数为0000 0011
则,真值为3
,机器数为1000 0011
,则真值为-3
。
- 原码
若机器字长为n
,那么一个数的原码就是用一个n
位的二进制数表示出来的机器数,其中最高位为符号位:正数为0
,负数为1
,位数不够的用0
补全。其实就是原码 = 符号位(0或1) + 真值的绝对值
。
如(假设机器字长为8
):3
的原码为0000 0011
,-3
的原码为1000 0011
。
【注意】0
的原码有两个:[+0]
原码为0000 0000
;[-0]
原码为1000 0000
。
- 反码
正数的反码就是其本身,负数的反码为除了符号位不变外,其他各位取反。
如(假设机器字长为8
):3
的反码为0000 0011
,-3
的反码为1111 1100
。
【注意】0
的反码有两个:[+0]
反码为0000 0000
;[-0]
反码为1111 1111
。
- 补码
正数的补码就是其本身,负数的补码则是反码加一。
如(假设机器字长为8
):3
的补码为0000 0011
,-3
的补码为1111 1101
。
【注意】:
1.0
的补码只有一个:[0]
补码为0000 0000
。
2.(8
位数据长度下)-128
,没有原码和反码,补码为10000000
。
- 为什么使用反码和补码
在使用原码进行计算的时候,对于人来说,可以轻易识别符号位,轻松知道正负,然后再对其他位来进行计算,对于计算机的设计来说,识别符号位就是一项复杂的工程了,若是能让符号位直接参与计算,那么这样就可以忽略符号位的识别了。
对于加法来说,符号位有没有影响不大,但是对于减法来说,计算机是将其转换为加法来进行运算,所以若是通过原码来进行计算(符号位直接参与计算)则:
$$
\begin{align}
5 - 3 =& 2 \
=& 5 + (-3) \
=& 0000 \text{ } 0101(原码) + 1000 \text{ } 0011(原码) \
=& 1000 \text{ } 1000(原码) \
=& -8
\end{align}
$$
显然,计算结果理论上为2
,但是计算机按照原码计算出来的数值为-8
,所以对减法来说,原码计算的方式不行,于是引入反码,若通过反码进行减法计算,则有:
$$
\begin{align}
5 - 3 =& 2 \
=& 5 + (-3) \
=& 0000 \text{ } 0101(原码) + 1000 \text{ } 0011(原码) \
=& 0000 \text{ } 0101(反码) + 1111 \text{ } 1100(反码) \
=& 1 \text{ } 0000 \text{ } 0001(反码) \
=& 0000 \text{ } 0001(反码) + 0000 0001(高位进位,结果要加1)\
=& 0000 \text{ } 0010(反码,符号位为0,为正数)\
=& 0000 \text{ } 0010(原码)\
=& 2
\end{align}
$$
【注意】反码计算的运算规则:从低到高位逐列进行计算。0+0=0,0+1=1,1+1=0(向高位进1)
。若最高位产生了进位,则最后得到的结果要加1。
但是,有一个问题出现了对于相同两个数相减,如:
$$
\begin{align}
1 - 1 =& 0 \
=& 1 + (-1) \
=& 0000 \text{ } 0001(原码) + 1000 \text{ } 0001(原码) \
=& 0000 \text{ } 0001(反码) + 1111 \text{ } 1110(反码) \
=& 1111 \text{ } 1111(反码) \
=& 1000 \text{ } 0000(原码) \
=& -0
\end{align}
$$
显然,计算出的结果的真值是对的,但是结果却是-0
,通过上边已经知道0
的原码和反码都有2个,所以,用反码进行计算时遇上了0
,这样的结果就是不合理的了,于是,又引入了补码,则:
$$
\begin{align}
1 - 1 =& 0 \
=& 1 + (-1) \
=& 0000 \text{ } 0001(原码) + 1000 \text{ } 0001(原码) \
=& 0000 \text{ } 0001(反码) + 1111 \text{ } 1110(反码) \
=& 0000 \text{ } 0001(补码) + 1111 \text{ } 1111(补码) \
=& 1 \text{ } 0000 \text{ } 0000(补码) \
=& 0000 \text{ } 0000(补码,最高位进位,舍去进位) \
=& 0000 \text{ } 0000(最高位为0,是正数) \
=& 0
\end{align}
$$
【注意】补码计算时,若最高位产生进位,则舍去进位,注意与反码相区别。
2.数据类型及标识符
分类 | 数据类型 | 标识符 |
基本类型 | 整型 | int |
字符型 | char | |
浮点型 | float(单精度) | |
double(双精度) | ||
枚举型 | enum | |
指针型 | 无 | |
构造类型 | 结构体 | struct |
共用体 | union | |
数组 | 无 | |
空类型 | 空类型 | void |
常用数据类型 | 16位平台 | 32位平台 | 64位平台 | |||
字节数 | 位数 | 字节数 | 位数 | 字节数 | 位数 | |
char unsigned char |
1 | 8 | 1 | 8 | 1 | 8 |
short unsigned short |
2 | 16 | 2 | 16 | 2 | 16 |
int unsigned int |
2 | 16 | 4 | 32 | 4 | 32 |
long unsigned long |
4 | 32 | 4 | 32 | 8 | 64 |
long long | --- | --- | 8 | 64 | 8 | 64 |
指针 | 2 | 16 | 4 | 32 | 8 | 64 |
bool | 1 | 8 | 1 | 8 | 1 | 8 |
float | 4 | 32 | 4 | 32 | 4 | 32 |
double | 8 | 64 | 8 | 64 | 8 | 64 |