2012-04-25 3 views
14

У меня есть неподписанный номер int (2 байт), и я хочу преобразовать его в unsigned char type. Из моего поиска я считаю, что большинство людей рекомендуют сделать следующее:C - unsigned int to unsigned char array преобразование

unsigned int x; 
... 
unsigned char ch = (unsigned char)x; 

Правильный подход? Я спрашиваю, потому что unsigned char 1 байт, и мы передали из двух байтовых данных в 1 байт.

Чтобы предотвратить потерю данных, я хочу создать массив unsigned char [] и сохранить отдельные байты в массиве. Я застрял на следующее:

unsigned char ch[2]; 
unsigned int num = 272; 

for(i=0; i<2; i++){ 
     // how should the individual bytes from num be saved in ch[0] and ch[1] ?? 
} 

Кроме того, как бы мы преобразовать символ без знака [2] обратно без знака Int.

Большое спасибо.

+0

Возможный дубликат [подписанного short by byte in C++] (http://stackoverflow.com/questi ons/10288109/signed-short-to-by-in-c) –

ответ

16

Вы можете использовать memcpy в этом случае:

memcpy(ch, (char*)&num, 2); /* although sizeof(int) would be better */ 

Кроме того, как бы преобразовать символ без знака [2] обратно без знака междунар.

Точно так же просто измените аргументы memcpy.

15

Как насчет:

ch[0] = num & 0xFF; 
ch[1] = (num >> 8) & 0xFF; 

Обратная операция остается в качестве упражнения.

7

Как насчет использования союза?

union { 
    unsigned int num; 
    unsigned char ch[2]; 
} theValue; 

theValue.num = 272; 
printf("The two bytes: %d and %d\n", theValue.ch[0], theValue.ch[1]); 
4

Конечно, массив символов, достаточно большой, чтобы содержать большее значение, должен быть таким же большим, как и это значение. Таким образом, вы можете просто сделать вид, что это большее значение уже является массив символов:

unsigned int x = 12345678;//well, it should be just 1234. 
unsigned char* pChars; 

pChars = (unsigned char*) &x; 

pChars[0];//one byte is here 
pChars[1];//another byte here 

(После того, как вы понимаете, что происходит, это может быть сделано без каких-либо переменных, все просто литье)

+2

Если '12345678' вписывается в' unsigned int' и 'sizeof (unsigned int) == 2', то' CHAR_BIT' больше, чем обычно ;-) –

+0

Я обвиняю 32-битное общество за то, что он испортил мне! –

2

Вы просто необходимо извлечь эти байты, используя bitwise & operator. OxFF - это шестнадцатеричная маска для извлечения одного байта. Пожалуйста, посмотрите на различных битовых операций здесь - http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/

Пример программы выглядит следующим образом:

#include <stdio.h> 

int main() 
{ 
    unsigned int i = 0x1122; 
    unsigned char c[2]; 

    c[0] = i & 0xFF; 
    c[1] = (i>>8) & 0xFF; 

    printf("c[0] = %x \n", c[0]); 
    printf("c[1] = %x \n", c[1]); 
    printf("i = %x \n", i); 

    return 0; 
} 

Выход:

$ gcc 1.c 
$ ./a.out 
c[0] = 22 
c[1] = 11 
i = 1122 
$ 
+1

Вы хотели сдвинуть num & 0xFF00 на 8, верно? (num & 0xFF00) >> 8. В противном случае у вас есть только 16-разрядное целое число, где младший байт оказывается равным нулю. У вас все еще нет байта. В качестве альтернативы вы можете просто сдвинуть: num >> 8; – abelenky

+0

@abelenky Вы правы .. упустили это! –

4

Это действительно зависит от вашей цели: почему вы хотите, чтобы преобразовать это до unsigned char? В зависимости от ответа на что есть несколько способов сделать это:

  • Округление: Это то, что было порекомендовано.Если вы просто пытаетесь сжать данные в функцию, которая требует unsigned char, просто введите uchar ch = (uchar)x (но, конечно, остерегайтесь того, что произойдет, если ваш int слишком велик).

  • Специфический endian: Используйте это, когда для назначения требуется определенный формат. Обычно сетевому коду нравится все преобразованное в массивы большого числа символов:

    int n = sizeof x; 
    for(int y=0; n-->0; y++) 
        ch[y] = (x>>(n*8))&0xff; 
    

    будет делать это.

  • Конечный аппарат машины. Используйте это, когда нет требования к требованию, и данные будут возникать только на одной машине. Порядок массива будет изменяться в разных архитектурах. Люди, как правило, заботиться об этом с union с:

    union {int x; char ch[sizeof (int)];} u; 
    u.x = 0xf00 
    //use u.ch 
    

    с memcpy:

    uchar ch[sizeof(int)]; 
    memcpy(&ch, &x, sizeof x); 
    

    или с вечно опасной простой отливки (что неопределенное поведение, и аварий на многочисленных системах):

    char *ch = (unsigned char *)&x; 
    
Смежные вопросы