这篇文章主要讲解了“C/C++字节序实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C/C++字节序实例分析”吧!
字节序
最近在看 redis 的内存编码,里面涉及到字节序相关的内容。这里就当复习一下,做个简单的回顾。
数据存储在内存中,是以字节为单位的,如果是单字节数据(如char、unsigned char、int8)就不会有字节序的问题。但是多字节数据(如 int、float、double)就要考虑字节序的问题了。字节序共分为两种:大端序 和 小端序。
大端序
数据的高位字节存储在地址的低端;低位字节存储在地址的高端。如图所示,值为 0x12345678 的四字节整数在大端序的主机上的内存排布。
小端序
数据的高位字节存储在地址的高端;低位字节存储在地址的低端。如图所示,值为 0x12345678 的四字节整数在小端序的主机上的内存排布。
主机字节序和网络字节序
除了主机字节序,还有网络字节序。主机字节序由CPU决定,Intel Core 经测试都是小端字节序。而网络字节序采用的是大端序。测试字节序可以通过一段 C 的源码搞定。
#include <stdio.h>
int main(int argc, char *argv[]) {
int i;
int x = 0x12345678;
for (i = 0; i < sizeof(int); ++i) {
unsigned char *p = ((unsigned char *)(&x)) + i;
unsigned char v = *p;
printf("%p 0x%d%d\n", p, v>>4, v & 0xf );
}
return 0;
}
取得整数 x 的首地址转换成 unsigned char* 指针后再向前偏移 i 个单位,分别得到这 sizeof(int) 个字节的地址,然后用 * 取得每个地址上的值,通过位运算转换成 16进制 输出。
Linux 系统可以通过指令获取 CPU 的类型:
cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
4 Intel(R) Core(TM) i3-2120 CPU @ 3.30GHz
大端序和小端序的互转
大端序和小端序的互相转换,其实就是内存翻转,在知道一个整数或者一个指针的字节数的时候,就是做一个镜像的交换。这里以 64位 整型为例:
void memrev64(void *p) {
unsigned char *x = p, t;
t = x[0];
x[0] = x[7];
x[7] = t;
t = x[1];
x[1] = x[6];
x[6] = t;
t = x[2];
x[2] = x[5];
x[5] = t;
t = x[3];
x[3] = x[4];
x[4] = t;
}
uint64_t intrev64(uint64_t v) {
memrev64(&v);
return v;
}
64位整数的字节数为8,所以在字节序进行转换的时候:
第0个字节和第7个字节交换;
第1个字节和第6个字节交换;
第2个字节和第5个字节交换;
第3个字节和第4个字节交换;
对于 32位整数、16位整数的情况,就更加简单了,不再累述。
感谢各位的阅读,以上就是“C/C++字节序实例分析”的内容了,经过本文的学习后,相信大家对C/C++字节序实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是天达云,小编将为大家推送更多相关知识点的文章,欢迎关注!