c - 使用 memcpy 从数组转换为 int

标签 c pointers memory byte memcpy

我正在试验指针操作,并决定尝试通过使用 memcpy 从内存中直接复制来将数字数组转换为整数。

char aux[4] = {1,2,3,4}; 
int aux2 = 0;
memcpy((char*) &aux2, &aux[0], 4);
printf("%X", aux2);
我预计结果是 0x1020304,因为我将确切的字节从一个复制到另一个,但是 printf 给了我结果 0x4030201,这几乎是我想要的输出,只是倒退。为什么会发生这种情况,有没有办法以“正确”的顺序获得结果?

最佳答案

您的代码最多具有实现定义的行为,在某些情况下具有未定义的行为。
类型 int大小可能与 4 不同:在 16 位系统上,int通常只有 2 的大小字节。你会在这样的系统上有未定义的行为。
在常规 32 位系统上,int有 4 个字节,但是这 4 个字节在内存中的存储顺序是实现定义的,这个问题称为 endianness :

  • 一些系统使用大端表示,其中第一个字节是整数的最重要部分。字节 01 02 03 04表示值 0x01020304在大端系统上,例如较旧的 Mac、一些手机和嵌入式系统。
  • 相反,今天的大多数个人计算机使用小端表示,其中第一个字节包含整数的最低有效部分。字节 01 02 03 04表示值 0x04030201在小端系统上,比如你的。
  • C 标准不排除其他表示,其中字节将按其他顺序排列。一些古老的 DEC 系统就是这种情况:PDP-11,最初开发 C 语言(中端或混合端)。

  • 尽管令人惊讶,但小端顺序非常合乎逻辑,因为偏移量 处的字节包含表示 之间的值的位2n*8 2n*8+7 .字节顺序是一个文化问题,对于长期用户来说,这两种选择似乎都很自然。
    在其他上下文中可以找到相同的变化,例如日期组件的排序:
  • 日本使用大端表示: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) 和阿拉伯语 (أنا ٤٢ سن​​ة) 都使用小端,因为它们是从右到右阅读的左。

  • 这是一个更便携的版本来测试内存表示:
    #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;
    }
    

    关于c - 使用 memcpy 从数组转换为 int,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66125278/

    相关文章:

    c - 指针和数组—艰苦学习C

    java - 如何为java进程分配合适的RAM量?

    c - 我的链表库不工作

    c - C 中#define 预处理器的作用域

    简而言之结合 MSB 和 LSB

    C:匿名数组是分配在堆还是栈上?

    debugging - 什么可以在 Linux 中执行类似 Cheat-Engine 的任务?

    c - 访问数据的最佳实践

    C位域/数组

    c - 如何从C中的.txt文件读取和打印前5个整数?