2016-10-08 53 views
0

问题:交换替代字节如下:交换整数中的交替字节

输入:uint8_t buf [4] = {0xab,0xcd,0xef,0xba};

输出:0xcdababef

我有这样做,下面的代码,但我想知道是否有什么更好的办法来缩短代码。

#include <stdint.h> 
#define SWAP_16(buf) (((buf & 0xFF00) >> 8) | ((buf & 0x00FF) << 8)) 
int main() 
{ 
    unsigned int value; 
    int i, j=0; 
    uint8_t buf[4] = {0,4,0,0}; 
    unsigned int mask = 0xFFFF; 
    unsigned int tmp_value; 
    unsigned int size = 4; 

    for (i = size - 1 ;i >= 0; i--) { 
     tmp_value |= (buf[j] << 8*i); 
     j++; 
    } 

    value = SWAP_16((tmp_value & (mask << 16)) >> 16) << 16 | 
     SWAP_16(tmp_value & mask); 
    return 0; 
} 
+0

为什么使用'int'?只需交换数组中的字节.... – 4386427

+1

'#define SWAPPED(b){b [1],b [0],b [3],b [2]}'...'uint8_t bswap [4] = SWAPPED(buf);'..? – txtechhelp

+2

你的意思是'0xcdabbaef'作为预期的输出?如果不是,那么目前还不清楚你的规定是 –

回答

1

假设unsigned int是32位,则可以简单地使用:

value = ((value & 0xff00ff00) >> 8) | ((value & 0x00ff00ff) << 8); 

交换字节中的每个字节对中value。它与您的宏SWAP_16()类似,不同之处在于它同时执行了这两个值的一半。

+0

这对uint8_t buf [4] = {0xab,0xcd的规定输入格式不起作用,0xef,0xba};' –

+0

@MM它执行字节交换,它只是不会将数组的字节放入'unsigned int'中,他的代码在交换字节之前已经做到了(尽管在那里当然还有其他方法) – Dmitri

+0

@Dmitri:如http://ideone.com/kVBZPH? – user3053970

0

使用工会

#include <stdint.h> 


#define SWAP_VAR(T, v1, v2) do { \ 
    T v = (v1); \ 
    (v1) = (v2); \ 
    (v2) = v; \ 
} while (0); 

union U32 
{ 
    uint32_t u; 
    unsigned char a[4]; 
}; 

uint32_t swap32(uint32_t u) 
{ 
    union U32 u32 = {u}; 

    SWAP_VAR(unsigned char, u32.a[0], u32.a[1]); 
    SWAP_VAR(unsigned char, u32.a[2], u32.a[3]); 

    return u32.u; 
} 

使用方法如下:

#include <stdint.h> 

uint32_t swap32(uint32_t u); 


int main(void) 
{ 
    uint32_t u = 0x12345678; 
    u = swap32(u); 
} 
+0

你运行过这个程序吗? – user3053970

+0

http://ideone.com/mHl2BC输出错误。 – user3053970

+0

'a [2] = c;'应该是'a [3] = c;' –

1
unsigned int forward = 0x12345678; 
unsigned int reverse; 

unsigned char *f = &forward; 
unsigned char *r = &reverse; 

r[0]=f[3]; 
r[1]=f[2]; 
r[2]=f[1]; 
r[3]=f[0]; 

现在扭转将是0x78563412

+0

这是不是违反了严格的锯齿规则? – alk

+0

这是错误的!你没有正确地看到问题。 – user3053970

+0

@alk不,字符类型可能会用于读取和写入其他类型 –

0

这里有一种方法:

#include <stdio.h> 
#include <stdint.h> 

int main(void) 
{ 
    uint8_t buf[4] = {0xab,0xcd,0xef,0xba}; 

    unsigned int out = buf[1] * 0x1000000u + buf[0] * 0x10000u + buf[3] * 0x100u + buf[2]; 
    printf("%x\n", out); 
} 
+0

介意解释逻辑? – user3053970

+0

您是否了解地点价值系统十进制数字123表示100 + 20 + 3.十六进制表示相同,0x123表示0x100 + 0x20 + 0x3。在这种情况下,我们一次处理两个数字:0x12345678表示0x12000000 + 0x340000 + 0x5600 + 0x78。 –

0

这不是立即从你的问题清楚,如果它不是一个选项,但你可以仅仅只是交换的字节数组中,如果你知道的大小不会改变:

#include <stdio.h> 
#include <stdint.h> 
#define SWAPPED(b) { b[1], b[0], b[3], b[2] } 
#define PRINT(b) printf("0x0%x\n", *((uint32_t*)b)); 

int main() 
{ 
    uint8_t buf[4] = {8,4,6,1}; 
    uint8_t swapped[4] = SWAPPED(buf); 
    PRINT(buf); 
    PRINT(swapped); 
    return 0; 
} 

这种情况的输出我的机器上是:

0x01060408 
0x06010804 

这是因为字节序和印刷铸造到一个整数类型的数组的,但是当你在你的问题问的字节交换。

希望有所帮助。

+0

好狡猾的逻辑。你从哪里得到这个想法? – user3053970

+0

@ user3053970,我一直在做C :) – txtechhelp

+0

请注意,这有一个别名问题 – 4386427

0
unsigned int n = ((unsigned int)buf[0] << 16) | 
       ((unsigned int)buf[1] << 24) | 
       ((unsigned int)buf[2] << 0) | 
       ((unsigned int)buf[3] << 8);