c/c++语言开发共享打印值0x89时的奇怪输出(-119)

正如标题所说,运行以下代码时,我得到一个“奇怪”的结果:

#include  int main() { char buff[4] = {0x17, 0x89, 0x39, 0x40}; unsigned int* ptr = (unsigned int*)buff; char a = (char)((*ptr <> (3*8)); char b = (char)((*ptr <> (3*8)); char c = (char)((*ptr <> (3*8)); char d = (char)((*ptr <> (3*8)); printf("0x%xn", *ptr); printf("0x%xn", a); printf("0x%xn", b); printf("0x%xn", c); printf("0x%xn", d); return 0; } 

输出:

 0x40398917 0x40 0x39 0xffffff89 0x17 

为什么我没有得到0x89

    这是因为您的char变量已签名,并且在升级时它们正在进行符号扩展(在这种情况下升级为更宽的类型)。 符号扩展是一种在执行此促销时保留符号的方式,因此-119保持为-119无论是8位,16位还是更宽的类型。

    您可以通过显式使用unsigned char来修复它,因为至少在C中, char是有符号还是无符号是特定于实现的。 从C11 6.2.5 Types /15

    实现应将char定义为具有与signed char或unsigned char相同的范围,表示和行为。

    对于无符号类型,符号扩展不起作用,因为它们是……好吧,未签名:-)

    默认情况下,char是签名的 – 这意味着数字从-128到127运行。除此之外的任何数字都不适合。 如果您将char更改为unsigned char ,您将获得所需的数字。

    使用memcpy而不是强制转换

     char buff[4] = {0x17, 0x89, 0x39, 0x40}; unsigned int* ptr = (unsigned int*)buff; 

    这是不正确的buff不指向int对象或数组,因此未定义(unsigned int*)buff

    buff重新解释为unsigned int的安全方法是使用memcpy

     char buff[4] = {0x17, 0x89, 0x39, 0x40}; unsigned int ui; assert (sizeof ui == sizeof buff); memcpy (buff, &ui, sizeof ui); 

    使用memcpy ,您无法确保复制的位表示对目标类型有效,当然。

    一种可移植但退化的方法是检查表示是否与现有对象匹配(注意,以下是愚蠢的代码):

     char *null_ptr = 0; char null_bytes[sizeof null_ptr] = {0}; if (memcmp (null_ptr, null_bytes, sizeof null_bytes)==0) { char *ptr2; memcpy (null_bytes, ptr2, sizeof null_bytes); assert (ptr2 == 0); } 

    此代码使用memcpy并具有完全定义的行为(即使无用)。 OTOH,行为

     int *ptr3 = (int*)null_bytes; 

    未定义,因为null_bytes不是intunsigned int的地址。

    需要了解更多c/c++开发分享打印值0x89时的奇怪输出(-119),也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)

      以上就是c/c++开发分享打印值0x89时的奇怪输出(-119)相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(计算机技术网)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ctvol.com/c-cdevelopment/980587.html

      (0)
      上一篇 2021年12月14日
      下一篇 2021年12月14日

      精彩推荐