代码之家  ›  专栏  ›  技术社区  ›  me_and

字节数组与无符号long之间的复制

  •  1
  • me_and  · 技术社区  · 14 年前

    在C中,在字节数组和整数之间复制数据的最佳/推荐方法是什么?目前我正在使用 memcpy ,我觉得不对劲。下面是我正在做的这类事情的一个例子。

    struct alpha {
            unsigned char byte_array[20];
    }
    
    void function(struct alpha *st) {
            unsigned long num;
    
            /* Do some stuff */
    
            memcpy(st->byte_array, &num, sizeof(unsigned long));
    
            /* Do more stuff */
    
            memcpy(&num, st->byte_array, sizeof(unsigned long));
    }
    

    我假设我想以某种方式使用强制转换,但是我不确定强制转换和指针(反)引用是如何相互作用的,特别是当涉及数组时。

    7 回复  |  直到 14 年前
        1
  •  6
  •   Jens Gustedt    14 年前

    memcpy 是实现这一效果的标准便携式工具。现代的优化编译器会将这个调用内联到一些非常适合您的情况,例如数据类型、对齐方式、大小(如果在编译时已知)、处理器。。。所以我认为你应该坚持这一点,而不是乱搞一些手工优化。

        2
  •  1
  •   Brian Hooper    14 年前

        3
  •  1
  •   tomlogic    14 年前

        /* Do some stuff */
    
        *(unsigned long *)st = num;
    
        /* Do more stuff */
    
        num = *(unsigned long *)st;
    

    将结构指针强制转换为指向无符号long的指针,然后在赋值语句中取消对该指针的引用。

        4
  •  0
  •   ShinTakezou    14 年前

    这并没有错,除非您知道“谁”将数据写入数组,并以不同于系统上使用的endianness写入它们。例如,如果这些数据来自“某人”通过网络发送的“流”。然后,如果协议使用所谓的“网络字节顺序”(即big-endian),并且您的机器不是big-endian,那么您将获得错误的值。

        5
  •  0
  •   Jerry Coffin    14 年前

    工会XXX{ 字符字节数组[20]; 无符号长num; };

    从理论上讲,当您向联合的一个成员写入数据,然后从另一个成员读取数据时,不会得到已定义的结果。实际上,基本上不可能得到与您现在得到的不同的东西——当然,除了从一个视图到另一个视图不必复制数据——您只需使用 x.num 把它看作是一个无符号的长 x.byte_array 把它看作一个字节数组。

        6
  •  0
  •   Michael Dorgan    14 年前

    memcpy是做这类事情最安全的方法。但是,如果速度很重要,您可以执行一些强制转换,让编译器以本机方式为您处理副本:

    
    *((unsigned long *)&st->byte_array[0]) = num;
    
    num = *((unsigned long *)&st->byte_array[0]);
    

    这两个都将使用内置的寄存器类型副本,而不是4字节的函数调用。如果您想进一步读入byte\u数组,那么必须小心这个数组的字节对齐问题。

        7
  •  0
  •   me_and    13 年前

    对于这个要求,我更喜欢一些默认函数,

    将字符串转换为整数

    int atoi ( const char * str );
    

    和 对于整数到字符串

    char *  itoa ( int value, char * str, int base );
    
    
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
     unsigned long int number;
     unsigned char string[256];
    
     printf ("Enter a number: ");
     fgets ( string, 256, stdin );
     number = atoi (string);
     printf("number = %d\n",number);
    
     //converting int to string
     itoa (number,string,10);    //10 is base here for decimal, 16 is used for Hex and 2 for Binary
     printf ("string = %s\n",string);
    
     return 0;
    }
    

    据我所知,atoi()函数很好。但是如果您不想使用itoa()或者它对您不可用,那么您可以使用sprintf()

    sprintf (string,"%ld",number);
    

    希望对你有帮助

    谢谢 好的,韩国。