将“无符号字符”数组转换为“无符号短”数组的有效方法是啥?

Posted

技术标签:

【中文标题】将“无符号字符”数组转换为“无符号短”数组的有效方法是啥?【英文标题】:What's an efficient way to convert "unsigned char" array to its "unsigned short" counterpart?将“无符号字符”数组转换为“无符号短”数组的有效方法是什么? 【发布时间】:2011-06-13 08:32:31 【问题描述】:

将“无符号字符”数组转换为“无符号短”数组的有效方法是什么?我通常使用下面的代码sn -p来做。

#define CH_LINE_PIXELS       2291
#define SCANLINE_SIZE        57301
#define CH1_INDEX            2297
#define CH2_INDEX            4592
#define CH3_INDEX            6887
#define CH4_INDEX            9182

unsigned char* pUChar = new unsigned char[SCANLINE_SIZE];

unsigned short *pUS1, *pUS2, *pUS3, *pUS4;
pUS1 = reinterpret_cast<unsigned short *>(&pUChar[CH1_INDEX]);
pUS2 = reinterpret_cast<unsigned short *>(&pUChar[CH2_INDEX]);
pUS3 = reinterpret_cast<unsigned short *>(&pUChar[CH3_INDEX]);
pUS4 = reinterpret_cast<unsigned short *>(&pUChar[CH4_INDEX]);

unsigned short us1, us2;

for (unsigned int i = 0; i < CH_LINE_PIXELS; i++) 
   
    us1 = pUChar[CH1_INDEX + 2 * i];
    us2 = pUChar[CH1_INDEX + 2 * x + 1];
    pUS1[x] = us1 * 0x100 + us2;

    us1 = pUChar[CH2_INDEX + 2 * i];
    us2 = pUChar[CH2_INDEX + 2 * i + 1];
    pUS2[x] = us1 * 0x100 + us2;

    us1 = pUChar[CH3_INDEX + 2 * i];
    us2 = pUChar[CH3_INDEX + 2 * i + 1];
    pUS3[x] = us1 * 0x100 + us2;

    us1 = pUChar[CH4_INDEX + 2 * i];
    us2 = pUChar[CH4_INDEX + 2 * i + 1];
    pUS4[x] = us1 * 0x100 + us2;

【问题讨论】:

我看到您忘记阅读标题为“如何格式化”的巨大侧边栏。请注意,它没有说明使用 html 标记... 具体来说,它说*只需选择所有代码并按下 按钮。请在以后这样做。 请注意,以这种方式使用reinterpret_cast依赖于实现:也就是说,您不能期望您的代码在不同的编译器/平台上编译时的行为方式相同。 亲爱的jalf 感谢您对代码格式的好意提醒,我以后会这样做。 亲爱的ereOn,您对删除编译器/平台依赖的“cast”操作有何建议? 【参考方案1】:

首先你应该做的:

us1 &lt;&lt; 8 + us2而不是乘以0x100,因为你想移动高位的前8位,移位比乘法快。

例如你有us1 = aaaaaaaa(8位)和us2 = bbbbbbbb(另外8位)。将这些字符扩展到短裤将只是在左侧用 8 个零填充它们。

那么上面的公式会给你:

00000000aaaaaaaa
<< 8
aaaaaaaa00000000
+ 00000000bbbbbbbb
aaaaaaaabbbbbbbb

另一方面,您应该为您的结果分配一个新的短裤数组

【讨论】:

“移位比乘法快” - 如果你的编译器很垃圾。 亲爱的史蒂夫,在这种情况下,我会听取你的建议。谢谢。 亲爱的 Matyas,感谢您的回答。使用移位而不是乘法,不要让短指针直接指向 char 数组,而是使用单独的短数组。您的建议与 littleadv 的建议几乎相同。英雄所见略同!我会接受你的建议。谢谢大家。【参考方案2】:

在字节边界上寻址short 可能(也可能不会)导致对齐问题,具体取决于平台。

另外,乘法是很无效的,为什么不用移位来代替呢? (一些编译器可能会优化 x * 0x100,但如果他们不这样做 - 当你想要的只是 x &lt;&lt; 8... 时,这会对性能造成巨大影响......)

另外,如上所述,reinterpret_cast 可能无法按您的预期工作。

我建议,因为无论如何你都要做分配,将值从char 的数组复制到short 的单独数组中。它会消耗一些内存,但会为您节省很多意外崩溃和其他问题的麻烦。

【讨论】:

亲爱的 littleadv,感谢您的回答。为避免边界对齐问题,使用vector 和vector 代替unsigned char* 和unsigned short* 数组是否更好、更安全? "如果他们不这样做" - 那么他们通常不会产生高效的代码,所以如果你关心性能,你需要打开优化,或者获得更好的编译器。 为什么投反对票?我是不是写错了什么? @Steve - 你的评论:我只是在陈述一个事实。有时程序员可能无法更改编译器。 我不认为“乘法非常无效”或“某些编译器可能会优化”是对这种情况的非常准确的描述,所以我认为这些不是事实。有可能有一天您会发现自己手动优化乘法以转换 C++ 代码,并看到显着的改进,但这不是常态。我也不认为值得投反对票——对我来说,移位表示这种比特旋转操作以及或比乘法更好。所以我会使用它,只是不是因为你给出的原因。 @Steve - 当你换档时 - 使用换档。除了乘法开销(我不同意你,分别在解雇),这仅仅是代码可读性和减少错误可能性的事情(想象写x * 100而不是x * 0x100,稍后再找)。

以上是关于将“无符号字符”数组转换为“无符号短”数组的有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在C中将无符号短数组转换为字节数组

上证所加转转换

如何将十六进制字符串转换为无符号字符数组?

将 VARIANT 转换为无符号字符数组

如何将字符串转换为无符号字符数组 [关闭]

将 std::string 转换为无符号字符数组