char // 字符数据类型 short // 短整型 int // 整形 long // 长整型 long long // 更长的整形 float // 单精度浮点数 double // 双精度浮点数
1.1.类型的基本归类c99中引入了布尔类型: _Bool,其作用是存储真假值,如下图所示(图中true就是1,false就是0)(其实基本上用不到布尔类型,因为int类型完全能够解决,并且布尔类型本质上就是对int类型进行了重命名)
需要引用stdbool.h头文件
1.整形家族:
char unsigned char char到底是signed char还是unsigned char是取决于编译器实现的 signed char 常见的编译器下:char就是unsigned char short unsigned short [int] 无符号短整型 signed short [int] 有符号短整型 short与signed short等价 int unsigned int 无符号整型 signed int 有符号整型 int与signed int等价 long unsigned long [int] 无符号长整型 signed long [int] 有符号长整型 long与signed long等价 longlong注: 1.上面[ ]里的内容可以省略 2.%d打印有符号整型,%u打印无符号整型 2.浮点数家族
float double
3.构造类型 /自定义类型
> 数组类型: 数组名去掉,其余的就是数组的类型( int a[10]类型是int [10] ) > 结构体类型 struct > 枚举类型 enum > 联合类型 union
4.指针类型
int* pi ; char* pc ; float* pf ; void* pv ;5.空类型
void 表示空类型(无类型) 通常应用于函数的返回类型、函数的参数、指针类型
2.整形在内存中的存储 2.1.原码、反码、补码 2.1.1.原码、反码、补码介绍
整数的二进制表示有三种表示形式:原码、反码、补码 内存中存储的是二进制的补码
整数分为正整数和负整数 正整数:原码、反码、补码相同 15的原码: 00000000 00000000 00000000 00001111 15的反码: 00000000 00000000 00000000 00001111 15的补码: 00000000 00000000 00000000 00001111 负整数:原码、反码、补码需要计算,如下 原码:按照一个数的正负直接写出来的二进制就是原码 -15的原码:10000000 00000000 00000000 00001111 反码:符号位不变,其他位按位取反就是反码 -15的反码:11111111 11111111 11111111 11110000 补码:反码的二进制序列加一就是补码 -15的补码:11111111 11111111 11111111 11110001注: 1.32位二进制数中,第一位是符号位,符号位是0表示整数,符号位是1,表示负数 2.反码不是对原码按位取反,因为按位取反是连符号位也取反了 2.1.2.内存中为什么存的是补码
在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。
计算机计算1-1,因为计算机中只有加法器,所以是1+(-1),下面我们尝试用原码和补码计算1.使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理 原码计算: 1的原码:00000000 00000000 00000000 00000001 -1的原码:10000000 00000000 00000000 00000001 1+(-1)的原码:10000000 00000000 00000000 00000010 数值为-2(结果错误) 补码计算: 1的补码:00000000 00000000 00000000 00000001 -1的原码:10000000 00000000 00000000 00000001 -1的反码:11111111 11111111 11111111 11111110 -1的补码:11111111 11111111 11111111 11111111 1+(-1)的补码:1 00000000 00000000 00000000 00000000 最前面进上去的1在实际中就丢了因此应该为00000000 00000000 00000000 00000000 ,而该值为0(结果正确) 2.补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路 -1的原码:10000000 00000000 00000000 00000001 -1的反码:11111111 11111111 11111111 11111110 -1的补码:11111111 11111111 11111111 11111111 此时想将-1的补码转换成-1的原码有两种方法:1.逆着计算,将补码-1变成反码,在对反码符号位不变其他位取反。2.继续对补码求补码,即对补码符号位不变其他位取反,然后所得值+1,如下: -1的补码:11111111 11111111 11111111 11111111 -1的补码的反码:10000000 00000000 00000000 00000000 -1的补码的补码:10000000 00000000 00000000 00000001 可以看出此值就是-1的原码 2.2.大小端介绍 10的补码:00000000 00000000 00000000 00001010 10的补码转换为16进制:0x 00 00 00 0a -10的原码:10000000 00000000 00000000 00001010 -10的反码:11111111 11111111 11111111 11110101 -10的补码:11111111 11111111 11111111 11110110 -10的补码转换为16进制:0x ff ff ff f6
总结:我们发现内存中的数字总是倒着存的
2.2.1.大端和小端int a = 0x11223344;
大端字节序存储:当一个数据的低字节数据存放在高地址处,高字节序的内容放在了低地址处,这种存储方式就是大端字节序存储 内存: 11 22 33 44
小端字节序存储:当一个数据的低字节数据存放在低地址处,高字节序的内容放在了低高地址处,这种存储方式就是小端字节序存储 内存:44 33 22 112.2.2.为什么有大端和小端
为什么会有大小端模式之分呢?这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为8bit。但是在C语言中除了8 bit的char之外,还有16 bit的short型,32 bit的long型(要看具体的编译器),另外,对于位数大于8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。 例如:一个 16bit 的 short 型 x ,在内存中的地址为 0x0010 , x 的值为 0x1122 ,那么 0x11 为高字节, 0x22 为低字节。对于大端模式,就将 0x11 放在低地址中,即 0x0010 中,0x22 放在高地址中,即 0x0011 中。小端模式, 刚好相反。我们常用的 X86 结构是小端模式,而 KEIL C51 则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以由硬件来选择是大端模式还是小端模式。3.3.3.设计一个小程序来判断当前机器的字节序
代码1:
代码2:
代码3:



