C语言位操作疑问:Skinny分组密码实现中的两类问题
问题解答
问题1:位操作与类型转换的疑问
- 位操作不需要手动把char转int:C语言会自动对char(包括unsigned char)做整数提升,运算时自动转成int类型。所以不管你手动转不转,运算过程都会用int来计算。
- 用unsigned char做位操作的结果:unsigned char提升为int时高位补0,不会出现符号位扩展的问题,位操作结果是正确的无符号扩展值。
- 关于存储结果的差异:
你的计算式four ^ ~(seven | six)中,seven和six是值为1的unsigned int,seven | six结果为int类型的1。按位取反~1在32位int中是0xFFFFFFFE(除最低位外所有位都是1),和值为0的four异或后得到0xFFFFFFFE。- 存入unsigned int时,这个值就是完整的
0xFFFFFFFE,你看到的fe只是它的低8位,这不是你想要的单个bit结果(问题出在你用了按位取反~而非逻辑取反!,或者没对结果取低1位)。 - 存入unsigned char时,会截断为低8位
0xFE。如果你用%d格式符打印,编译器会把它当作有符号char处理,0xFE作为有符号char的补码对应-2——这只是显示问题,unsigned char实际存储的是254,用%u或%hhx格式符才能看到正确的无符号值。
- 存入unsigned int时,这个值就是完整的
问题2:指针数组的报错原因
最初的unsigned char *bits[8]是指针数组,每个元素是指向unsigned char的指针(存储的是内存地址),而不是存储bit值的普通char数组。你用bits[4]取到的是一个内存地址,不是'0'或'1'这样的字符值。
- 做
bits[4] - '0'时,是把一个地址(比如0x00123456)减去字符'0'的ASCII值(48),得到的是一个毫无意义的大整数,完全不是你要的bit值。 - 指针类型不允许直接参与位运算,所以VSCode会报错。
Python里没有指针概念,所有数组直接存值,这是你用Python知识迁移到C时容易混淆的点——C里unsigned char bits[8]是存8个char值的数组,unsigned char *bits[8]是存8个指针的数组,两者本质完全不同。
内容的提问来源于stack exchange,提问作者O_o
相关产品推荐
相关产品推荐

