2009-02-25 25 views
9
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]); 
    } 
} 

Lo que hace este método ahora es invertir bytes en la memoria. Lo que me gustaría saber es si hay una mejor manera de obtener el mismo efecto. Toda la parte "tamaño/2" parece algo malo, pero no estoy seguro.¿Hay alguna forma mejor de invertir una matriz de bytes en la memoria?

EDIT: Me acabo de dar cuenta de lo malo que era el título que puse para esta pregunta, así que [con suerte] lo solucioné.

+0

Su ejemplo parece defectuoso, ¿cómo puede cambiar dos caracteres sin una ubicación? Sospecho que necesita pasar la dirección. – leppie

Respuesta

23

La biblioteca estándar tiene una función std::reverse:

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

Gracias. Debería haberlo buscado antes de escribirlo yo mismo. – xian

+0

La descripción de la función inversa indica que se implementa exactamente de la misma manera que la persona que realizó la pregunta lo implementó y que tiene la misma complejidad. No es realmente una mejor manera. Una manera más limpia, tal vez en el mejor de los casos ... – Julius

1

Si necesita revertir hay una posibilidad de que pueda mejorar sus algoritmos y sólo usar iteradores inversa.

+0

Es para leer datos de archivos que usan endiancias diferentes. – xian

+0

@kitchen, esto parece más revertir los bytes de un entero, no los bytes de una matriz completa ... –

1

Si está invirtiendo datos binarios de un archivo con endianness diferente, probablemente debería usar las funciones ntoh * y hton *, que convierten los tamaños de datos especificados de la red al orden de host y viceversa. ntohl, por ejemplo, convierte un largo sin firmar de 32 bits de Big Endian (orden de la red) a una orden de host (little endian en máquinas x86).

+0

Esta pregunta se refiere al intercambio de una matriz, por lo que las soluciones proporcionadas anteriormente responden específicamente a las necesidades. – Xofo

0

Revisaría el stl :: swap y me aseguraré de que esté optimizado; después de eso, diría que eres bastante óptimo para el espacio. Estoy razonablemente seguro de que también es óptimo en el tiempo.

+0

En ninguna parte cerca del tiempo óptimo. El cálculo de 'size/2' * podría * optimizarse para que no se ejecute en cada ciclo, pero el cálculo de' size-i-1' no lo sería, ni el costo de la indexación de la matriz. Dicho esto, un bucle perfectamente optimizado no sería * eso * mucho más rápido que lo que tiene. –

+0

Es el "no * que * mucho más rápido" que me llevó a decirlo ... –

17

Una solución performant sin utilizar la 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; 
    } 
} 

Aunque la pregunta es de 3 ½ años de edad, lo más probable es que alguien más va a ser la búsqueda de la misma cosa. Es por eso que todavía publico esto.

+5

La oportunidad se ha dado cuenta :) –

Cuestiones relacionadas