2016-10-08 12 views
0

Проблема: своп альтернативные байт, как показано ниже:своп альтернативные байт в целое число

Входной сигнал: uint8_t ЬиЕ [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 no, типы символов могут использоваться для чтения и записи других типов –

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); 

 Смежные вопросы

  • Нет связанных вопросов^_^