在字节数组和无符号长整型之间复制

时间:2010-07-06 14:12:40

标签: c casting

在字节数组和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));
}

我假设我想以某种方式使用强制转换,但我对投射和指针(de)引用的交互方式没有信心,特别是在涉及数组时。

7 个答案:

答案 0 :(得分:6)

memcpy是此效果的标准便携式工具。现代优化的编译器会将这个调用内联到适合您情况的内容,例如数据类型,allignement,大小(如果在编译时已知),处理器......所以我认为你应该明确坚持这一点并且不要乱用一些手工制作优化

答案 1 :(得分:1)

它看起来对我来说是正确的方式。也就是说,当我必须这样做时,就是我这样做的方式。

答案 2 :(得分:1)

以下是使用强制转换的方法:

    /* Do some stuff */

    *(unsigned long *)st = num;

    /* Do more stuff */

    num = *(unsigned long *)st;

您将结构指针转换为指向unsigned long的指针,然后在赋值语句中取消引用指针。

答案 3 :(得分:0)

memcpy是最安全的做这种事情的方法。如果速度很重要,你可以做一些魔术让编译器本身为你处理副本:


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

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

这两个都将使用内置寄存器类型副本而不是4字节的函数调用。如果你想进一步阅读byte_array,你必须注意字节对齐问题。

答案 4 :(得分:0)

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

答案 5 :(得分:0)

是否有任何特殊原因需要复制而不仅仅是将两者混叠? e.g:

union XXX {     char byte_array [20];     unsigned long num; };

理论上,当您写入联合的一个成员然后从另一个成员读取时,您不会得到定义的结果。实际上,基本上没有可能与你现在得到的东西有任何不同 - 除了(当然)你不必复制数据从一个视图到另一个视图 - 你只需使用{{1将它看作无符号长整数,x.num将其视为一个字节数组。

答案 6 :(得分:0)

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

表示字符串为整数

int atoi ( const char * str );

和 for integer to string

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);

我希望它有所帮助

由于 Alok.kr。