鉴于此字段:
char lookup_ext[8192] = {0}; // Gets filled later
这句话:
unsigned short *slt = (unsigned short*) lookup_ext;
幕后会发生什么?
lookup_ext [1669]返回67 = 0100 0011(C),lookup_ext [1670]返回78 = 0100 1110(N)并且lookup_ext [1671]返回68 = 0100 0100(D);但是slt [1670]返回18273 = 0100 0111 0110 0001.
我正在尝试将其移植到C#,所以除了一个简单的方法之外,我还想知道这里到底发生了什么。我经常使用C ++已经有一段时间了。
谢谢!
答案 0 :(得分:6)
您显示的语句不会将char转换为unsigned short,它会将指针转换为char,将指针转换为unsigned short。这意味着指向数据的通常算术转换不会发生,并且当通过slt
变量访问时,底层char数据将被解释为unsigned short。
请注意sizeof(unsigned short)
不一定是{1},因此slt[1670]
不一定与lookup_ext[1670]
对应。如果(例如,sizeof(unsigned short)
为2),则更有可能与lookup_ext[3340]
和lookup_ext[3341]
对应。
您知道为什么原始代码使用此别名吗?如果没有必要,可能值得尝试使C ++代码更清晰,并在移植之前验证行为是否保持不变。
答案 1 :(得分:2)
如果我理解正确,那么类型转换将把一个大小为8192的char数组转换为一个大小为一半的short int数组,即4096。
所以我不明白你在问题中所做的比较。 slt [1670]应对应于lookup_ext [1670 * 2]和lookup_ext [1670 * 2 + 1]。
答案 2 :(得分:1)
好吧,这句话
char lookup_ext[8192] = {0}; // Gets filled later
在本地或非本地创建数组,具体取决于定义的位置。像这样初始化它,使用聚合初始值设定项将其所有元素初始化为零(第一个显式,其余的隐式)。因此我想知道为什么你的程序输出非零值。除非在读取之前发生填充,否则这是有道理的。
unsigned short *slt = (unsigned short*) lookup_ext;
当您从该指针的目标读取时,这将把构成数组的字节解释为无符号短对象。严格地说,上面是未定义的行为,因为你不能确定数组是否适合对齐,你会从不指向原始指向类型的指针读取(unsigned char< - > unsigned short )。在C ++中,从其他一些pod中读取值的唯一可移植方式(普通旧数据。这也是C中可能的所有结构和简单类型(如简称)),通过使用这样的库函数memcpy
或memmove
。
因此,如果您阅读上面的*slt
,您将解释数组的第一个sizeof(*slt)
字节,并尝试将其读作无符号短(称为type pun
)。
答案 3 :(得分:0)
当您执行“unsigned short slt =(unsigned short )lookup_ext;”时,请执行此操作。从lookup_ext给出的位置中拾取等于(unsigned short)大小的字节,并将其存储在slt指向的位置。由于unsigned short是2个字节,所以lookup_ext中的前两个字节将存储在slt给出的位置。