2015-01-06 2 views
0

Я прочитал некоторые коды ниже:что это означает литье символ * беззнаковое Int

typedef unsigned int uint32_t;  
typedef unsigned short uint16_t; 

inline uint16_t NS(uint16_t i16) 
{ 
    return((i16 << 8) | (i16 >> 8)); 
} 

inline uint32_t NL(uint32_t i32) 
{ 
    return((uint32_t(NS(i32)) << 16) | NS(i32>>16)); 
} 

char* data = (char*) malloc(10); 

strcpy(data, "123456789"); 
const char *m_data = (const char *)data; 
uint32_t i32 = *((uint32_t*)m_data); 
i32 = NL(i32); 
m_data += 4u; 

Я не понимаю uint32_t i32 = *((uint32_t*)m_data);, что это значит?

И не понимаю i32 = NL(i32); m_data += 4u; и функции NS и NL.

может мне сказать кто-нибудь?

+1

@Kevin. Помимо прошивки наложения, проблем нет. – 2501

+0

@ 2501 Неплохо, я читал это как хранение указателя в uint32 в какой-то момент, а не uint32 *. – Kevin

ответ

1

Код ошибки (это утечка памяти):

char* data = (char*) malloc(10); 
data="123456789\0"; 

должно быть:

char* data = (char*) malloc(10); 
strcpy(data, "123456789"); 

Это также означает, что вы ничего не можете сказать о выравнивании указателя в data, тогда как назначение от malloc() гарантирует, что данные достаточно хорошо выровнены для любого базового типа. Однако, это частично по касательной к вопросу о следующих двух строках:

const char *m_data = (const char *)data; 
uint32_t i32 = *((uint32_t*)m_data); 

Бросок в первой из этих линий не является необходимым, но не делает никакого вреда. Следующая строка обрабатывает указатель, хранящийся в m_data, как указатель uint32_t, разыгрывает его и присваивает результат i32. Если значение в m_data поступило из data, которое исходило от malloc(), данные были бы достаточно хорошо выровнены, чтобы это не было проблемой. При назначении строки нет гарантии, что указатель в m_data достаточно хорошо выровнен для использования в качестве указателя uint32_t. Так что все ад может сломаться, или, может быть, все в порядке. Поведение не определено из-за утечки памяти.

Байт функции NS() байтов - 16-разрядное целое число. Функция NL() меняет 16-разрядные значения в 32-битовом целое. Это означает, что вы начинаете со значения, показанного на диаграмме «Пуск», и заканчиваетесь значением, показанным на диаграмме «Готово».

+------+------+------+------+ 
| MSB | NMSB | NLSB | LSB | Start 
+------+------+------+------+ 

+------+------+------+------+ 
| LSB | NLSB | NMSB | MSB | Finish 
+------+------+------+------+ 

m_data += 4u; добавляет 4 к указателю m_data, поэтому вместо того, чтобы указывать на 1 строки, она указывает на 5.

+0

[литье возвращаемого значения 'malloc()'] (http://stackoverflow.com/q/605845/2173917) может быть удалено. –

+0

uint32_t i32 = * ((uint32_t *) m_data); Что в итоге? – heida

+0

Это зависит от платформы - вы получаете разные результаты по сравнению с Intel, по сравнению с SPARC или Power (little-endian vs big-endian). На big-endian вы получаете 0x31323334; на little-endian, вы получите 0x34333231. Что вы получили, когда запустили его? Или это случилось? –

0
uint32_t i32 = *((uint32_t*)m_data); 

Это буквально означает взять интерпретировать указатель m_data как указатель uint32_t и разыменования его. Цель состоит в том, чтобы интерпретировать символы, указанные data, как uint32_t.

Функции NS и NL, по-видимому, принимают побитовое ИЛИ левой и правой половин своих параметров и возвращают его.

m_data += 4u; 

Это должно быть эквивалентно тому же самому утверждению без суффикса без знака. Он просто увеличивает указатель m_data, чтобы указать на символ по адресу четыре символа выше, где он указывал раньше.

0

Когда NS дается 16-битное значение i16 а, таким образом, (каждый символ быть один бит):

aaaaaaaabbbbbbbb 

то выражение i16 << 8 (бит-сдвиг влево на 8 бит, подавая в нулевых битов на вправо) даст вам bbbbbbbb00000000 и i16 >> 8 даст 00000000aaaaaaaa. ORing вместе дает:

bbbbbbbb00000000 
OR 00000000aaaaaaaa 
    ---------------- 
    bbbbbbbbaaaaaaaa 

Другими словами, он заменяет два байта.

То же самое для N32 функции свопинга 16-битные половинки в пределах 32-битное значение, но, поскольку она также вызывает N16 на каждой из этих половин, он выполняет следующее преобразование:

aaaaaaaabbbbbbbbccccccccdddddddd 
       || 
       VV 
ddddddddccccccccbbbbbbbbaaaaaaaa 

Это обычно используется при преобразовании в или из порядка сетевого байта, когда порядок отличается от вашей конкретной архитектуры.


серии заявление:

const char *m_data = somethingOrOther; 
uint32_t i32 = *((uint32_t*)m_data); 

работает следующим образом. Сначала он преобразует указатель на указатель 32-битного значения. Затем, это разыгрывает указатель на извлечение 32-битного значения.

Что это означает, что первые четыре символа строки (предполагается, что тип данных char составляет восемь битов) "1234" будут рассматриваться как целое значение 32-битной, и передается N32 пройти вышеупомянутый байт- своп.

И, наконец, m_data += 4u просто добавляет значение без знака 4 указателя символа так, что он переходит к следующему 32-битное значение "5678").

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