Dan*_*ris 6 c memory byte pointers memcpy
我正在试验指针操作,并决定尝试通过使用 memcpy 从内存中直接复制来将数字数组转换为整数。
char aux[4] = {1,2,3,4};
int aux2 = 0;
memcpy((char*) &aux2, &aux[0], 4);
printf("%X", aux2);
Run Code Online (Sandbox Code Playgroud)
我预计结果是 0x1020304,因为我将确切的字节从一个复制到另一个,但是 printf 给了我结果 0x4030201,这几乎是我想要的输出,只是倒退。为什么会发生这种情况,有没有办法以“正确”的顺序获得结果?
您的代码最多具有实现定义的行为,在某些情况下具有未定义的行为。
类型int的大小可能不同于4: 在 16 位系统上,int通常只有2字节的大小。你会在这样的系统上有未定义的行为。
在常规 32 位系统上,int有 4 个字节,但 4 个字节在内存中的存储顺序是实现定义的,这个问题称为字节序:
一些系统使用大端表示,其中第一个字节是整数的最重要部分。字节01 02 03 04表示0x01020304大端系统上的值,例如较旧的 Mac、某些手机和嵌入式系统。
相反,今天的大多数个人计算机使用小端表示,其中第一个字节包含整数的最低有效部分。字节01 02 03 04表示0x04030201little-endian 系统上的值,例如您的系统。
C 标准不排除其他表示,其中字节将按其他顺序排列。一些古老的 DEC 系统就是这种情况:PDP-11,最初开发 C 语言(中端或混合端)。
尽管令人惊讶,小端顺序非常合乎逻辑,因为偏移量n处的字节包含表示2 n*8和2 n*8+7之间的值的位。字节顺序是一个文化问题,对于长期用户来说,这两种选择似乎都很自然。
在其他上下文中可以找到相同的变化,例如日期组件的排序:
日本使用 big-endian 表示法:2021 年 2 月 17 日是这样写的2021.02.17,
欧洲使用小端表示法:2021 年 2 月 17 日是这样写的17/02/2021,
美国使用中端表示法:2021 年 2 月 17 日写成02/17/2021。
21在英语中发音为21(大端),而德国人说einundzwanzig(一加二十,小端,实际上是 3 位数字的中端)。但是 17 是17(小端)和法语dix-sept(大端)。
西方语言以大端格式(我 42 岁)写数字,但闪族文字使用小端顺序:希伯来语 ( ??? ?? 42 ) 和阿拉伯语 ( ??? ?? ??? ) 都使用小端endian,因为它们是从右到左读取的。
这是一个更便携的版本来测试内存表示:
#include <stdio.h>
#include <string.h>
int main() {
unsigned int aux2 = 0x01020304;
unsigned char aux[sizeof(unsigned int)];
memcpy(&aux, aux2, sizeof(aux));
printf("%X is represented in memory as", aux2);
for (size_t i = 0; i < sizeof(aux); i++)
printf(" %02X", aux[i]);
printf("\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
163 次 |
| 最近记录: |