一. 数据存储
大端序和小端序:
Big Endine and Little Endine
-
Little Endian
- 最低位的字节地址也是最小的(写在最前面)
- 看上去是倒序的
- intel的x86框架
-
Big Endian
- 最低位的字节地址是最大的(写在最后面)
- 看上去是正序的
- Sun, IBM
- 用于网络传输数据(如TCP/IP),因此通常要进行大小端转换
下面举个栗子:
#include <stdio.h>
int main()
{
char str[4] = {0x12,0x34,0x56,0x78};
int *p = (int *)str;
printf("%x\n", *p);
}
输出结果是78563412,可见确实是小端序存储的.
printf(“%x\n”, *p);中 %x
是以16进制输出的意思
再举一个汇编中的例子:
80483bd: 01 05 64 94 04 08->add %eax, 0x8049464
二. 类型转换
1. unsigned & signed
转换公式:
对应关系:
默认情况下,定义的变量都是有符号的
如果要申明无符号变量,要以U作后缀: 4294967259U
Attention: 当进行关系比较时,也会进行隐式转换, 有符号变量会转换为无符号
举个例子:
另一个例子:
这个程序中由于strlen返回无符号,因此strlen(s) - strlen(t)
结果是一个无符号数,一定比0U
来得大
2. 长度变化
short -> long
- unsigned: 填0
- signed: 根据最高位符号,0则填0,1则填1
这样负数增长后大小不变
long -> short
直接暴力截断
signed正数可能会变为负数
integer promotion
在C语言中,当进行关系比较或运算时,char
和short
类型会被隐式转换为int
型。这种转换称为 integer promotion(整数提升)。
因此在下面这个例子中:
unsigned short c = 65535;
short d = -1;
if (c == d) {
cout << "c == d" << endl;
} else {
cout << "c != d" << endl;
}
在判断c==d时, d被转换为unsigned int型, c被转换为unsigned int, 故c = 0x00001111, d = 0x11111111, 输出 c!=d
总结
本文介绍了C语言中类型转换遵循的规则。
更多文章:
数据在内存中的对齐问题
计算机编译程序的原理
函数调用的汇编原理
汇编语句详解(持续更新)
关于位运算必须记住的事