一、数据类型:
整形家族:
- char:unsigned char / signed char
- short:unsigned short [int] / signed short [int]
- int:unsigned int / signed [int]
- long:unsigned long [int] / signed long [int]
- long long:unsigned long long [int] / signed long long [int]
tips:字符类型在内存中的存储,是存储的字符类型对应的ASCII码,所以字符类型算作整形。
浮点型家族:
- float:
- double:
构造类型(自定义类型):
- 数组:
- 结构体:
- 枚举:
- 联合体:
指针类型:
空类型:
二、整形在内存中的存储:
计算机中的整数有三种二进制表示方法,即:原码、反码、补码。
三种表示方法均有符号位和数值位,符号位用0表示“正”,用1表示“负”。正数的原、反、补相同,负数的原、反、补不同。而整形在内存中存储的就是整数的二进制补码,这样的作用是可以将符号位和数值位统一计算,省去硬件中多余的逻辑电路。
整形在内存中占4个字节,下面举例整形的二进制表示:
255的原码、反码、补码:
00000000 00000000 00000000 11111111 —— 原码
00000000 00000000 00000000 11111111 —— 反码
00000000 00000000 00000000 11111111 —— 补码
-1的原码、反码、补码:
10000000 00000000 00000000 00000001 —— 原码
11111111 11111111 11111111 11111110 —— 反码:符号位不变,其余位按位取反
11111111 11111111 11111111 11111111 —— 补码:反码+1
虽然整数在内存中以补码存储,但是读取时还是要转换回原码。补码转换为原码有两种方式:1. 补码 - 1,符号位不变,其余位按位取反;2. 符号位不变,其余位按位取反得到的二进制再 + 1
三、大小端字节序存储模式:
什么是大小端字节序存储模式?
大端(存储)模式:数据的低位字节存放在内存的高地址处,数据的高位字节存放在内存的低地址处。
小端(存储)模式:数据的高位字节存放在内存的高地址处,数据的低位字节存放在内存的高地址处。
如图:num = 0x11223344,在内存低地址处存放的是num的低位字节44,高地址处存放的num的高位字节11,可见此系统是以小端模式进行数据的存储的。
四、隐式类型转换:
这部分内容不算是数据在内存中存储的范畴,但是部分计算需要理解数据怎么在内存中进行存储的,才能知道结果是怎么得出的。
整形提升:
C语言中的整形运算符总是至少以缺省整形类型的精度来进行计算的,为了获得这个精度,表达式中的字符和短整形操作数在使用之前要被转换为普通整形,这种转换被成为整形提升。
如何进行整形提升?
整形提升是按照变量自身的数据类型的符号位来操作的,如果是有符号数:补齐符号位;如果是无符号数:补齐0。
算术转换:
如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换:当处于列表下方的操作数类型较低时,需向上转换。
long double
double
float
unsigned long int
long int
unsigned int
int
五、一些例题:
1.如何判断当前系统为大端存储模式还是小端存储模式,请写程序判断:
#include <stdio.h>
int judge_sys(int *value) {
return *(char*)value;
}
int main() {
int num = 1;
if (judge_sys(&num)) {
printf("小端\n");
}
else {
printf("大端\n");
}
return 0;
}
2.请写出下列程序的输出:
#include <stdio.h>
int main() {
char x = -128;
printf("%u\n", x);
return 0;
}
上面程序结果为:4294967168,计算过程如下:
(1)-128的补码:
10000000 00000000 00000000 10000000 —— 原码
11111111 11111111 11111111 01111111 —— 反码
10000000 00000000 00000000 10000000 —— 补码
(2)x为字符类型,只能访问一个字节的内存空间,所以x的值为:10000000。这过程也叫整形截断。
(3)以%u也就是无符号整形形式打印,x需要整形提升,x自身为有符号数,所以补齐符号位。
11111111 11111111 11111111 10000000 —— 补码
11111111 11111111 11111111 01111111 —— 反码
10000000 00000000 00000000 10000000 —— 原码
(4)以无符号形式打印原码,最后得到4294967168