Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 字节数组和无符号长数组之间的复制_C_Casting - Fatal编程技术网

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

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

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

我觉得这完全正确。也就是说,当我不得不这样做的时候,我就是这样做的。

我觉得这样做完全正确。也就是说,当我不得不这样做时,我就是这样做的。

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