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

17
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”部分似乎不太好,但我不确定。

编辑:我刚意识到我为这个问题设置的标题有多糟糕,所以我[希望]已经修正了它。


你的例子似乎有缺陷,你如何在没有位置的情况下交换两个字符?我怀疑你需要传递地址。 - leppie
5个回答

32

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

#include <algorithm>
void ReverseBytes( void *start, int size )
{
    char *istart = start, *iend = istart + size;
    std::reverse(istart, iend);
}

谢谢。在自己编写代码之前,我应该先查找资料。 - xian
1
reverse函数的描述说明它的实现方式与提问者实现的方式完全相同,并且具有相同的复杂度。这并不是一种更好的方式,最多可能只是一种更简洁的方式。 - Jules G.M.

27

不使用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年半,但仍有可能有其他人在搜索同样的问题。这就是为什么我仍然发布这个回答。


8
机会已经实现了 :) - Aviad P.
要完成代码,只需添加强制转换:(unsigned char*)start + size - 1; - Ilan

2
如果需要反转,您有机会改进算法并使用反向迭代器。

1
它用于从使用不同字节序的文件中读取数据。 - xian
@kitchen,这似乎更像是颠倒整数的字节,而不是整个数组的字节... - Hosam Aly

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

这个问题涉及到交换一个数组,所以上面提供的解决方案特别回答了这个需求。 - Xofo
如果您正在使用glib,请查看endian.h - davidbak

0

我会检查 stl::swap 并确保它已经被优化;之后,我会说你在空间上非常优化。我相信这也是时间最优的。


远远不是时间最优的。size/2 的计算可能会在每次循环中被优化掉,但是 size-i-1 的计算以及数组索引的成本则无法被优化。话虽如此,一个完全优化的循环也不会比他目前的快多少。 - Head Geek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接