【问题标题】:Explicit casting problems, C显式铸造问题,C
【发布时间】:2012-01-12 19:44:31
【问题描述】:

我在 C 中有这个 case 语句:

case GOTO: {
    int o1 = (int)P[pc+1];
    unsigned int o2 = (unsigned)P[pc+2];
    int offset =(o1<<8) | o2;
    pc = pc + (int)offset;
    break;
}

现在关于代码: P[pc+x] 将给出一个 1 字节整数。 基本上在这结束时,我想将pc 设置为有符号的4 字节int。然而,它并没有这样做。它正在做的是获取1 字节,将其移动,然后获取第二个字节,然后按位或,然后简单地添加它。它没有考虑 o1 的符号。所以,如果P[pc+1] = FFP[pc+2] = E1,发生的是offset = 0000FFE1。然而,我想要的是offset = FFFFFFE1。基本上,第一个2 字节应该采用P[pc+1] 的符号。但这并没有发生。我做错了什么?

【问题讨论】:

  • 你还能显示数组 P 的类型吗?也许添加以下演员可能会有所帮助: int o1 = (int)(int8_t)P[pc+1];无符号整数 o2 = (无符号)(uint8_t)P[pc+2]; int 偏移量 = (int)((o1
  • 请贴出Ppc的声明,以及INT()的定义。
  • 糟糕,INT() 不应该存在,假装它不存在。而P是字节数组,pc是访问其索引的一种方式。
  • 如果它不应该存在,请将其编辑掉。编辑所有声明。

标签: c casting unsigned signed


【解决方案1】:

我没有看到P的声明,但是当你说它是一个字节数组时,我假设它的具体类型是无符号字符。

如果它是有符号的,则强制转换将按照您想要的方式运行,因为例如,-1 char 将变为 -1 int,符号位移动,其余位根据需要反转。但是,当您从 unsigned char 转换为 signed int 时,结果将始终为正 int。

所以,要解决这个问题,一种方法是在解除引用之前强制转换指针/数组,它会给出想要的结果:

int o1 = (int)(((char *)P)[pc+1]);

另一件事:位移不适用于有符号值,因为它只会转移符号位。它适用于您的示例,因为您有 0xFF,但如果您有 0x80,它将是 0x80000000 作为 int,并在移位后变为 0x00000000。

因此,不要进行 8 位移位,而是进行乘法运算:

int offset =(int)( (o1 * 256) + o2 );

【讨论】:

  • 非常有趣,你能解释一下 Char* 的转换是如何工作的吗?
  • 好吧,基本上你是在对编译器说“看看这个数组,就好像它包含有符号的字符,并做出相应的行为”。因此,如果 P[pc+1] 包含 0xFF,则强制转换使其被“视为”为 -1。这可确保提升为 int 仅在获取该值之后发生。如果您只是对 P[pc+1] 的结果进行强制转换,编译器将在强制转换之前获得(无符号字符)255,并且会(至少)发出警告,说明强制转换正在丢失有效数字;它不知道高位最初是作为标志的。投射指针就是对他说。
【解决方案2】:

看看这是否对您有意义: #包括

int main(void) {
  short pc1= 0xFF;
  short pc2= 0xE1;
  int pc = 0;

  unsigned int highbits = 0xFFFFFFFF;

  // Check for sign bit, if true OR with highbits
  // to set all remaining bits to high
  int o1 = pc1 & 0xF0 ? pc1 | highbits : pc1;
  int offset = (int)( (o1<<8) | pc2 );
  pc = pc + (int)offset;
  printf("\npc1=%x pc2=%x pc=%x", pc1, pc2, pc);
  printf("\n");

  return 0;
}

输出:

pc1=ff pc2=e1 pc=ffffffe1

【讨论】:

    【解决方案3】:

    您应该检查您的编译器如何在 C 中执行无符号转换,反之亦然。 如果我没记错的话(对不起,如果我错了),一旦你在像 A = B 这样的操作中至少有一个 UNSIGNED 变量(其中 A 接收 B 的值),编译器会将这两个值都作为 UNSIGNED 值处理。

    这可能会影响您的代码。 让我以一种或另一种方式知道答案,如果我弄清楚为什么会发生这种情况,我会在这里发表评论

    【讨论】:

    • 是的,我认为你是对的。我不得不做一个非常老套的解决方案。我基本上把所有东西都变成了短整数,然后就成功了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 2023-04-04
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    相关资源
    最近更新 更多