概念
数据的低字节存放在内存的低地址处,称为小端模式
数据的低字节存放在内存的高地址处,称为大端模式
cpu读取数据的顺序是从低字节向高字节进行的。比如
int i = 0x12345678
从左向右依次为数据的高字节 -> 低字节
检测方法,按照定义来
void func1() {
union W{
int i;
char ch;
}w;
w.i = 1;
if (w.ch == 1) {
puts("little endian");
}
else {
puts("big endian");
}
}
void func2() {
int a = 0x12345678;
char *p = reinterpret_cast<char *>(&a);
// 输出 a 的每个字节数据
for (int i = 0; i < 4; ++ i)
printf("%x\n", p[i]);
if (p[0] == 0x78) {
puts("little endian");
}
else {
puts("big endian");
}
}
void func3() {
int a = 1;
char *p = reinterpret_cast<char *>(&a);
if (*p == 1) {
puts("little endian");
}
else {
puts("big endian");
}
}
int main() {
func1();
func2();
func3();
return 0;
}
检测方法涉及到的类型转换
数据类型转换(static_cast<>())
printf("%d\n", static_cast<int>(10.2));
指针类型转换 (reinterpret_cast<>() )
int *p = new int (0x12345678);
char *c = reinterpret_cast<char *>(p);
printf("%x\n", *c);
涉及到const的指针类型转换(const_cast<>())
const int num[] = {1,2};
const int *cp = num;
int *pp = const_cast<int *>(cp);
父类转化为子类(dynamic_cast<>())
如果只知道父类指针,不知道子类指针,但是想调用子类的非虚拟函数,用此转化
#include <bits/stdc++.h>
using namespace std;
class Base {
public:
Base() = default;
virtual ~Base() = default;
};
class Derived : public Base {
public:
Derived() = default;
void test() {
cout << "Derived" << endl;
}
~Derived() { };
};
int main() {
Base *b = new Base();
Derived *d = dynamic_cast<Derived *>(b);
d->test();
return 0;
}
网络字节序与主机字节序
- 网络字节序
网络字节序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节序采用big
endian排序方式。
- 主机字节序
不同的机器主机字节序不相同,与CPU设计有关,数据的顺序是由cpu决定的,而与操作系统无关。我们把某个给定系统所用的字节序称为主机字节序(host
byte order)。比如x86系列CPU都是little-endian的字节序。
- 由于这个原因不同体系结构的机器之间无法通信,所以要转换成一种约定的数序,也就是网络字节顺序。
为了进行转换 bsd socket提供了转换的函数 有下面四个
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序