没有*运算符的演员

时间:2013-10-04 17:20:47

标签: c compiler-construction

有人可以向我解释在这种情况下“n”发生了什么事吗?

的main.c

unsigned long temp0;
PLLSYS0_FWD_DIV_A_DECODE(n);

main.h

#define PLLSYS0_FWD_DIV_A_DECODE(n) ((((unsigned long)(n))>>8)& 0x0000000f)

我知道n被移位8位然后用0x0000000f移位。那么(unsigned long)(n)究竟做了什么?

#include <stdio.h>

int main(void)
{
    unsigned long test1 = 1;
    printf("test1 = %d \n", test1);
    printf("(unsigned long)test1 = %d \n", (unsigned long)(test1));

return 0;
}

输出:

test1 = 1 
(unsigned long)test1 = 1

5 个答案:

答案 0 :(得分:2)

在您的代码示例中,强制转换没有多大意义,因为test1已经是unsigned long,但是当宏用于unsigned char之类的其他类型时,这是有意义的等

此外,您应该使用%lu中的printf来打印unsigned long

printf("(unsigned long)test1 = %lu\n", (unsigned long)(test1));
//                              ^^

答案 1 :(得分:1)

  

有人可以向我解释在这种情况下“n”发生了什么?

您正在向n投射unsigned long

  

那么(unsigned long)(n)究竟做了什么?

它会将n提升为unsigned long

答案 2 :(得分:1)

它将它扩大为unsigned long的大小。想象一下,如果你用char调用它并将它向右移动8位,那么anding将不会起作用。

同样只是found this(在右移运算符下看)为什么它是无符号的。显然无符号强制进行逻辑移位,其中对于每个移位的位置,最左边的位被替换为零。有符号值移位执行算术移位,其中最左边的位被丢弃的最右边的位替换。

示例:

11000011 ( unsigned, shifted to the right by 1 )
01100001

11000011 ( signed, shifted to the right by 1 )
11100001

答案 3 :(得分:0)

输入输入就是它在位移和和之前所做的一切。如果运营商的操作和优先权,请注意订单。这很难看。

但看起来他们正在避免碰到符号位,而是通过这样做而不是函数,没有类型检查n。

这只是丑陋的。

更好的形式是拥有一个具有输入类型检查的干净清除功能。

答案 4 :(得分:0)

确保n具有适当的大小(以位为单位),最重要的是被视为无符号。当移位运算符执行符号扩展时,当一个数字被签名为负数时,扩展将以1而不是零完成。这意味着移位的负数将始终导致负数。

例如:

int main()
{
        long i = -1;
        long x, y;

        x = ((unsigned long)i) >> 8;
        y = i >> 8;

        printf("%ld %ld\n", x, y);
}

在我的机器上输出:

  

72057594037927935 -1

由于y中的符号扩展名,数字仍为-1: