有人可以向我解释在这种情况下“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
答案 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: