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

Ciò che questo metodo fa ora è invertire i byte in memoria. Quello che mi piacerebbe sapere è, c'è un modo migliore per ottenere lo stesso effetto? L'intera parte "size/2" sembra una brutta cosa, ma non ne sono sicuro.Esiste un modo migliore per invertire una matrice di byte in memoria?

EDIT: Ho appena realizzato quanto fosse pessimo il titolo che ho inserito per questa domanda, quindi l'ho riparato.

+0

Il tuo esempio sembra imperfetto, come puoi scambiare due caratteri senza una posizione? Sospetto che tu debba passare l'indirizzo. – leppie

risposta

23

La libreria standard ha una funzione std::reverse:

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

Grazie. Avrei dovuto cercarlo prima di scriverlo da solo. – xian

+0

La descrizione della funzione inversa afferma che è implementata esattamente nel modo in cui la persona che ha posto la domanda lo ha implementato e che ha la stessa complessità. Non è davvero un modo migliore. Un modo più pulito forse al meglio .. – Julius

1

Se è necessario invertire c'è una possibilità che è possibile migliorare gli algoritmi e basta usare iteratori inverso.

+0

È per la lettura di dati da file che utilizzano endianness diversi. – xian

+0

@kitchen, questo sembra più come invertire i byte di un intero, non i byte di un intero array ... –

1

Se si stanno invertendo dati binari da un file con endianness differente, è consigliabile utilizzare le funzioni ntoh * e hton *, che convertono le dimensioni dei dati specificate dall'ordine di rete a quello host e viceversa. ntohl per esempio converte un long senza segno a 32 bit da big endian (ordine di rete) a ordine host (little endian su macchine x86).

+0

Questa domanda riguarda lo scambio di un array, quindi le soluzioni fornite sopra rispondono in modo specifico del necessario. – Xofo

0

Vorrei rivedere lo stl :: swap e assicurarmi che sia ottimizzato; dopo dirò che sei abbastanza ottimista per lo spazio. Sono ragionevolmente sicuro che anche il tempo sia ottimale.

+0

Da nessuna parte vicino al tempo ottimale. Il calcolo 'size/2' * potrebbe * essere ottimizzato per essere eseguito su ogni ciclo, ma il calcolo' size-i-1' non sarebbe, né il costo dell'indicizzazione dell'array. Detto questo, un ciclo perfettamente ottimizzato non sarebbe * quello * molto più veloce di quello che ha. –

+0

E 'il "non * che * molto più veloce" che mi ha spinto a dirlo ... –

17

Una soluzione performante senza utilizzare lo 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; 
    } 
} 

Anche se la questione è di 3 anni e mezzo, è probabile che qualcun altro si ricerca per la stessa cosa. Ecco perché lo postò ancora.

+5

La possibilità ha capito :) –

Problemi correlati