2012-02-10 2 views
0

Итак, я хочу сохранить информацию двух short в одну int для последующей отправки по сети (это просто демонстрация, здесь нет кода сети). Я скопировал два байта каждого номера short в переменную prim (примитив).Копирование байтов из меньших типов в более крупный тип

#include <iostream> 
#include <stdio.h> 
#include <string.h> 
#include <string> 

int main() 
{ 
    unsigned int prim = 0; 
    short major = 0x0001; 
    short minor = 0x0000; 
    prim = 0; 
    memcpy(&prim, &major, 2); 
    memcpy(&prim+2,&minor, 2); 
    std::cout << "Prim: " << prim << std::endl; 

    return EXIT_SUCCESS 
} 

Если я копирую major, а затем minor (как написано в коде выше) позже, я получить правильный вывод:

Prim: 1 

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

10000000 00000000 00000000 00000000 

Однако, если изменить порядок, то есть minor первый тогда major лат эээ, как это:

memcpy(&prim, &minor, 2); 
memcpy(&prim+2,&major, 2); 

я получаю 0.

Prim: 0 

Почему? Оно должно быть:

00000000 00000000 10000000 00000000 

Который равен 65536.

+0

Рядом с уже дал ответ: Если вы хотите быть уверены в размере байта типы, по крайней мере, используйте uintXX_t. Существует никаких гарантий относительно размера int и short. – stefaanv

+0

'00000000 00000000 10000000 00000000' is 65536. – kennytm

+0

@stefaanv Проблема не в размере такого типа. Не работали с размером указателя в течение длительного времени, я забыл каждый тип указателя на разные размеры и предположил, что он всегда указывает на один байт. – Amumu

ответ

4

&prim + 2 Поскольку указывает на 8 байт (2 × SizeOf (INT)) после &prim.

Чтобы увеличить число указателей на байты, необходимо направить его на char*.

memcpy((char*)&prim+2, &major, 2); 
+0

А, я должен бросить его в указатель на символ. Благодарю. – Amumu

5

Более переносимый способ поместить целые числа в большие целые числа сдвигается.

uint16_t lo = 1; 
uint16_t hi = 2; 
uint32_t all = (hi << 16) + lo; 
2

Помимо исправления ошибки при расчете правильного poiters вы можете избежать всего этого указателя расчеты с помощью союзов:

#include <iostream> 

    union two_shorts_t { 
     unsigned int prim ; 
     struct shorts_t { 
      short major; 
      short minor; 
     } shorts; 
    } ; 

int main() 
{  
    two_shorts_t values; 

    values.shorts.major=1; 
    values.shorts.minor=0; 
    std::cout << "Prim: " << values.prim << std::endl; 

    values.shorts.major=0; 
    values.shorts.minor=1; 
    std::cout << "Prim: " << values.prim << std::endl; 

    return 0; 
} 
+0

Это на самом деле NICE. Благодарю. – Amumu

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