有没有更好的方法来反转内存中的字节数组?

Posted

技术标签:

【中文标题】有没有更好的方法来反转内存中的字节数组?【英文标题】:Is there a better way to reverse an array of bytes in memory? 【发布时间】:2009-02-25 09:10:46 【问题描述】:
typedef unsigned char Byte;

...

void ReverseBytes( void *start, int size )

    Byte *buffer = (Byte *)(start);

    for( int i = 0; i < size / 2; i++ ) 
        std::swap( buffer[i], buffer[size - i - 1] );
    

这个方法现在所做的就是反转内存中的字节。我想知道的是,有没有更好的方法来获得相同的效果?整个“size / 2”部分似乎是一件坏事,但我不确定。

编辑:我刚刚意识到我给这个问题的标题是多么糟糕,所以我[希望]修正了它。

【问题讨论】:

您的示例似乎有缺陷,您如何在没有位置的情况下交换两个字符?我怀疑你需要传递地址。 【参考方案1】:

标准库有一个std::reverse函数:

#include <algorithm>
void ReverseBytes( void *start, int size )

    char *istart = start, *iend = istart + size;
    std::reverse(istart, iend);

【讨论】:

谢谢。我应该在自己写之前先查一下。 反向函数的描述表明它的实现方式与提问者的实现方式完全相同,并且具有相同的复杂性。这并不是一个更好的方法。一种更清洁的方式可能充其量是..【参考方案2】:

不使用 STL 的高性能解决方案:

void reverseBytes(void *start, int size) 
    unsigned char *lo = start;
    unsigned char *hi = start + size - 1;
    unsigned char swap;
    while (lo < hi) 
        swap = *lo;
        *lo++ = *hi;
        *hi-- = swap;
    

虽然这个问题是 3 ½ 年的问题,但很可能其他人会搜索相同的内容。这就是为什么我仍然发布这个。

【讨论】:

机会已经实现:)【参考方案3】:

如果您需要逆向,您可以改进算法并使用逆向迭代器。

【讨论】:

用于从使用不同字节序的文件中读取数据。 @kitchen,这似乎更像是反转整数的字节,而不是整个数组的字节......【参考方案4】:

如果您要从具有不同字节顺序的文件中反转二进制数据,您可能应该使用 ntoh* 和 hton* 函数,它们将指定的数据大小从网络顺序转换为主机顺序,反之亦然。例如,ntohl 将 32 位无符号长整数从大端(网络顺序)转换为主机顺序(x86 机器上的小端)。

【讨论】:

这个问题涉及交换数组,所以上面提供的解决方案专门回答了需要。 如果您使用的是 glib,请参阅 endian.h【参考方案5】:

我会检查 stl::swap 并确保它已优化;在那之后,我会说你非常适合空间。我有理由确定这也是最佳时间。

【讨论】:

远未达到最佳时间。 size/2 计算可能 被优化为在每个循环中运行,但 size-i-1 计算不会,数组索引的成本也不会。也就是说,一个完美优化的循环不会比他所得到的快那个

以上是关于有没有更好的方法来反转内存中的字节数组?的主要内容,如果未能解决你的问题,请参考以下文章

C语言08-数组

如何在java中反转字节数组? [复制]

从 C# 中的字节数组中删除尾随空值

在java中,如何清除每个方法中的字节[]数组以保护值免受内存转储?

比较两个字节数组的最快方法是啥?

Java 迭代字节数组中的位