大端小端,有符号无符号

学习目标:

`数据在内存中的存储


学习内容:

1.大端存储模式:数据的低位保存在内存的高位地址,数据的高位保存在内存的低位地址。
2.小端存储模式:数据的低位保存在内存的低位地址,数据的高位保存在内存的高位地址。
例如:0x11223344,这一个16进制数的最高位是1,最低位是8
在这里插入图片描述
3.百度笔试题:设计一个小程序判断当前机器的字节序

#include <stdio.h>
int main()
{
	int a = 1;
//char*类型指针一次访问一个字节,判断大端小端只要判断访问的这个字节上存的是01,还是00
	char* p =(char*)&a;//&a得到的地址是int*类型的,一次访问四个字节,为了访问一个字节,需要强制转换成char*类型
	if (*p == 1)
	{
		printf("小端\n");
	}
	else
		printf("大端\n");
	return 0;
}

以此为基础还可以将其改为更为简便的函数返回值形式

#include <stdio.h>
int da()
{
	int a = 1;
	return *(char*)&a;
}
int main()
{
	if (da() == 1)
	{
		printf("小端\n");
	}
	else
		printf("大端\n");
	return 0;
}

4.有符号位进行高位提升,补的是符号位;无符号位进行高位提升,统一补0。
例如:在这里插入图片描述由这个结果可以看出char a是默认为有符号类型的。
高位提升:有符号位进行高位提升,补的是符号位;无符号位进行高位提升,统一补0。
-1的原码为:10000000000000000000000000000001
补码为:11111111111111111111111111111111
此后在补码上进行char类型变量赋值,只能赋值后八位(截断了),得到11111111
打印a的整数类型,整数类型是32位,现在char类型后只有8位了,所以需要“高位提升”。
提升后得到11111111111111111111111111111111(补码),因为打印出的是原码,所以把补码转换成原码,得到-1。由此可得b也是-1。
char c 的补码也是11111111,但是它高位提升后为00000000000000000000000011111111,转换成原码就是255。
5. %u是打印无符号整形,认为内存中存放的是一个无符号整形的补码。

### 大端字节中的无符号整数解析方法 大端字节(Big-Endian)是指多字节数据在内存中存储时,高位字节位于低地址位置,低位字节位于高地址位置。这种字节广泛应用于网络协议(如TCP/IP),因此理解如何正确解析大端字节中的无符号整数对于跨平台通信和二进制文件处理尤为重要。 #### 1. 手动拼接字节 当需要从一组字节中提取一个32位无符号整数(`uint32_t`)时,可以使用位运算将各个字节按照大端组合起来。例如: ```c #include <stdint.h> uint32_t parse_be_uint32(const uint8_t *data) { return ((uint32_t)data[0] << 24) | ((uint32_t)data[1] << 16) | ((uint32_t)data[2] << 8) | (uint32_t)data[3]; } ``` 此函数接受一个指向四个字节的指针,并将其解释为一个大端格式的32位无符号整数[^4]。 #### 2. 使用标准库函数 在网络编程中,C语言提供了标准库函数来转换字节。例如 `ntohl()` 函数用于将32位大端整数转换为主机字节(通常是小): ```c #include <arpa/inet.h> uint32_t network_value = ...; // 假设这是从网络接收的大端整数 uint32_t host_value = ntohl(network_value); ``` 这种方式适用于从网络接收的数据流,确保数据在不同字节系统上的一致性[^3]。 #### 3. 使用宏定义简化操作 为了提高代码可读性和复用性,可以定义宏来封装字节拼接逻辑。例如: ```c #define LOAD32B(x, y) \ (x) = ((uint32_t)((y)[0]) << 24) | \ ((uint32_t)((y)[1]) << 16) | \ ((uint32_t)((y)[2]) << 8) | \ (uint32_t)((y)[3]) ``` 该宏接受两个参数:目标变量 `x` 和源字节数组 `y`,并按大端方式加载数据到 `x` 中[^4]。 #### 4. 字节转换工具类(C++ 示例) 如果使用 C++,可以封装一个简单的工具类来处理不同大小的整数: ```cpp #include <cstdint> #include <vector> class EndianConverter { public: static uint32_t load_u32be(const std::vector<uint8_t>& data, size_t offset) { return (static_cast<uint32_t>(data[offset + 0]) << 24) | (static_cast<uint32_t>(data[offset + 1]) << 16) | (static_cast<uint32_t>(data[offset + 2]) << 8) | static_cast<uint32_t>(data[offset + 3]); } }; ``` 此类提供了一个静态方法 `load_u32be`,用于从给定偏移量处加载一个32位大端无符号整数[^3]。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值