摘要:
  本文主要是记录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)

1641269764160

二、数据类型

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
## 3.不同系统中数据类型长度
常用数据类型 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