这是什么意思?将char *转换为unsigned int

时间:2015-01-06 04:09:27

标签: c

我在下面阅读了一些代码:

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。

有人可以告诉我吗?

3 个答案:

答案 0 :(得分: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()函数在32位整数内交换16位值。这意味着您要从“开始”中显示的值开始。图表并以&#39;完成&#39;中显示的值结束。图。

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

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

m_data += 4u;为指针m_data添加了4,因此它不是指向字符串的1,而是指向5

答案 1 :(得分:0)

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

这实际上意味着将指针m_data解释为指向uint32_t的指针并取消引用它。目的是将data指定的字符解释为uint32_t

函数NS和NL似乎采用其参数左右两半的按位OR并返回它。

m_data += 4u;

这应该等同于没有无符号后缀的相同语句。它只是将指针m_data递增为指向前面指向的四个字符的地址处的字符。

答案 2 :(得分:0)

NS给出16位值i16时(每个字符为一位):

aaaaaaaabbbbbbbb

然后表达式i16 << 8(由8位向左移位,右边为零位)将为您提供bbbbbbbb00000000i16 >> 8将给出00000000aaaaaaaa 。将这些组合在一起给出了:

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

换句话说,它正在交换两个字节。

同上,N32函数在32位值内交换16位半,但由于它还在每一半上调用N16,因此执行以下转换:

aaaaaaaabbbbbbbbccccccccdddddddd
               ||
               VV
ddddddddccccccccbbbbbbbbaaaaaaaa

当您的特定架构的顺序不同时,这通常用于转换为网络字节顺序或从网络字节顺序转换。


陈述系列:

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

的工作原理如下。首先,它将字符指针转换为32位值指针。然后,它取消引用该指针以提取32位值。

这意味着char字符串的前四个字符(假设"1234"数据类型是8位)将被视为32位整数值,并传递给{{ 1}}进行上述字节交换。

最后,N32只是将无符号值m_data += 4u添加到字符指针,以便它前进到 next 32位值({{1} }})。