C 字节数组和无符号长数组之间的复制
在C中,在字节数组和整数之间复制数据的最佳/推荐方法是什么?目前我使用的是C 字节数组和无符号长数组之间的复制,c,casting,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_arra
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));
}
我假设我想以某种方式使用强制转换,但我不确定强制转换和指针(取消)引用是如何相互作用的,特别是当涉及数组时。我觉得这完全正确。也就是说,当我不得不这样做的时候,我就是这样做的。我觉得这样做完全正确。也就是说,当我不得不这样做时,我就是这样做的。memcpy是做这类事情最安全的方式。但是,如果速度很重要,您可以执行一些强制转换魔术,让编译器以本机方式为您处理副本:
*((unsigned long *)&st->byte_array[0]) = num;
num = *((unsigned long *)&st->byte_array[0]);
这两者都将使用内置寄存器类型的副本,而不是4字节的函数调用。如果要进一步读取字节数组,则必须小心字节对齐问题。memcpy是最安全的方法。但是,如果速度很重要,您可以执行一些强制转换魔术,让编译器以本机方式为您处理副本:
*((unsigned long *)&st->byte_array[0]) = num;
num = *((unsigned long *)&st->byte_array[0]);
这两者都将使用内置寄存器类型的副本,而不是4字节的函数调用。如果要进一步读取字节数组,则必须小心字节对齐问题。这没有错,除非您知道将数据写入数组的“谁”以不同于系统上使用的尾数写入数据。例如,如果这些数据来自“某人”通过网络发送的“流”。然后,如果协议使用所谓的“网络字节顺序”(即big-endian),并且您的机器不是big-endian,那么您将获得错误的值。这没有错,除非您知道将数据写入数组的“谁”以与系统上使用的不同的endian写入数据。例如,如果这些数据来自“某人”通过网络发送的“流”。然后,如果协议使用了所谓的“网络字节顺序”(即big-endian),而您的机器不是big-endian,那么您会得到错误的值。是否有任何特殊原因需要复制,而不仅仅是混淆两者?e、 g: 联合XXX{ 字符字节_数组[20]; 无符号长num; };
从理论上讲,当您向联盟中的一个成员写入数据,然后从另一个成员读取数据时,不会得到定义的结果。实际上,基本上不可能得到与您现在得到的不同的东西——当然,除了(当然)您不必复制数据从一个视图到另一个视图之外——您只需使用
x.num
将其视为无符号长字符,和x.byte\u array
将其视为一个字节数组。有什么特别的原因需要复制而不是将两者混淆?e、 g:
联合XXX{
字符字节_数组[20];
无符号长num;
};
从理论上讲,当您向联盟中的一个成员写入数据,然后从另一个成员读取数据时,不会得到定义的结果。实际上,基本上不可能得到与您现在得到的不同的东西——当然,除了(当然)您不必复制数据从一个视图到另一个视图之外——您只需使用
x.num
将其视为无符号长字符,和x.byte\u array
将其视为一个字节数组。对于此要求,我更喜欢一些默认函数
将字符串转换为整数
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;
}
我希望有帮助
谢谢
Alok.kr.对于这个需求,我更喜欢一些默认函数 将字符串转换为整数
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;
}
我希望有帮助
谢谢
Alok.kr.
memcpy
是实现这一效果的标准便携工具。现代优化编译器会将此调用内联到适合您的情况的内容中,例如数据类型、对齐方式、大小(如果在编译时已知)、处理器。。。因此,我认为您应该坚持这一点,而不是搞一些手工优化。memcpy
是实现这一效果的标准便携工具。现代优化编译器会将此调用内联到适合您的情况的内容中,例如数据类型、对齐方式、大小(如果在编译时已知)、处理器。。。因此,我认为您应该坚持这一点,而不是胡乱进行一些手工优化。以下是如何使用强制转换:
/* Do some stuff */
*(unsigned long *)st = num;
/* Do more stuff */
num = *(unsigned long *)st;
您正在将结构指针强制转换为指向无符号long的指针,然后在赋值语句中取消对该指针的引用。下面介绍如何使用强制转换:
/* Do some stuff */
*(unsigned long *)st = num;
/* Do more stuff */
num = *(unsigned long *)st;
您正在将结构指针强制转换为指向无符号long的指针,然后在赋值语句中取消对该指针的引用。这与我的预期类似,但是
st->byte\u数组[0]
是否与*(st->byte\u数组)
相同,后者是字节,而不是指针?(unsigned long*)
强制转换似乎是将一个字节强制转换为(指向unsigned long的指针),而我原以为我想将(指向字节的指针)强制转换为(指向unsigned long的指针)…该死-忘了带符号。希望这个地方有一个快速语法编译器:)[0]下标不正确。正确的转换是将字节数组转换为无符号长指针;如果需要将k个字节索引到其中,*((unsigned long*)(st->byte\u array+k))=num;或者,如果需要将k个长单词索引到其中,((unsigned long*)st->byte_array)[0]=num;这与我所期望的差不多,但是st->byte\u数组[0]
与*(st->byte\u数组)
不一样吗,后者是字节,而不是指针?(unsigned long*)
强制转换似乎是将一个字节强制转换为(指向unsigned long的指针),而我原以为我想将(指向字节的指针)强制转换为(指向unsigned long的指针)…该死-忘了带符号。希望这个地方有一个快速语法编译器:)[0]下标不正确。合适的演员是b