将给定大小的char数组复制到C中的整数的正确方法是什么? [英] What's the proper way to copy a char array of a given size to an integer in C?
问题描述
假设我有一个char数组和一个关联的长度: Arr
和 Len
。不是字符串,是char数组。没有空终止符。但是我必须将数组数据复制到 int64_t
类型的整数中。这是完成的过程,出于这个问题的目的,我假设 Len
不会超过8:
Suppose I have a char array and an associated length: Arr
and Len
. Not a string, a char array. There is no null terminator. Yet I have to copy the array data into an integer of type int64_t
. Here's how it's done, and for the purpose of this question I'm assuming Len
will not exceed 8:
int64_t Word = 0;
memcpy(&Word, Arr, Len);
这实际上是执行此操作的正确方法吗?我正在复制内存,但是有没有更快的方法来内联,例如?因此, Word
可以注册
?
Is this actually the proper way to do this? I am copying memory, but is there a faster way to do it inline, for example? So Word
can be register
?
双关语类型的问题是假定 Arr
分配了8个字节。不, Arr
最多分配了 8个字节。它可能有5个,因此将 Arr
强制转换为 int64_t *
然后取消引用它可能会尝试访问目录中的三个非法字节。
The problem with a type pun is it assumes that Arr
has 8 bytes allocated. No, Arr
has at most 8 bytes allocated. It could have 5, so casting Arr
to a int64_t *
then dereferencing it could try to access three illegal bytes at the end, resulting in segfault.
是执行我描述的 memcpy()
调用的正确方法,还是有更快的方法?还是更好的方法?
Is the proper way to do what I describe a memcpy()
call, or is there a faster or better way?
推荐答案
由于您指定 Len
是最多 (8)
,假设使用低位字节存储,即 Arr [0]的最低有效字节是合理的
。
Since you specify Len
is at most (8)
, it's reasonable to assume little-endian storage, i.e., the least-significant byte at Arr[0]
.
如果 Len
固定为(8)
,编译器也许可以简单地通过从内存中加载值来替换 memcpy
。这也取决于平台是否可以执行未对齐的读取-如果编译器无法证明对齐-并可能涉及x86-64上的 bswap
指令,如果
If Len
was fixed at (8)
, the compiler might be able to replace memcpy
simply by loading the value from memory. That would also be dependent on whether the platform can do unaligned reads - if the compiler can't prove alignment - and may involve something like the bswap
instruction on x86-64 if the architecture is big-endian.
Len
是运行时值这一事实很可能会生成对<$ c的调用$ c> memcpy 。通话本身的开销并不小。考虑所有因素,最好是使用字节算术以与字节序无关的方式处理此问题。该代码假定8位字节,这似乎与您的问题相符。
The fact that a Len
is a run-time value will likely generate a call to memcpy
. The overhead of the call itself is not trivial. All things considered, it's probably best just to handle this in an endian-independent way using byte arithmetic. The code assumes 8-bit bytes, which seems consistent with your question.
uint64_t Word = 0;
while (Len--)
Word = (Word << 8) | Arr[Len];
在其他平台上,其中(CHAR_BIT> 8)
,则可以将 OR
表达式的右侧替换为(Arr [Len]& 0xff)
。实际上,在具有8位(标准)字节的平台上对此进行了优化,因此您也可以添加它以提高完整性。或者只是记住这些问题。
On more exotic platforms, where (CHAR_BIT > 8)
, you can replace the right-hand side of the OR
expression with (Arr[Len] & 0xff)
. In fact, this is optimised away on platforms with 8-bit (normative) bytes, so you might as well add it for completeness. Or just keep these issues in mind.
有 个带有合法C实现的平台,其中 char
,<例如,code> short , int
是32位值。这些在嵌入式世界中很常见。
There are platforms with legal C implementations where char
, short
, int
are 32-bit values, for example. These are quite common in the embedded world.
这篇关于将给定大小的char数组复制到C中的整数的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!