需要帮助理解C中的左移操作符

时间:2017-01-20 19:50:39

标签: c bit-manipulation

我有一些理解左移操作符的问题。我知道如果向左移位x位,那么将数字乘以2就可以将位数乘以移位的位数。

但考虑一下这个程序:

int a=4,*pA=&a,r3;
printf("%d\n",pA);
printf("%d\n",(*pA<<2));
r3=pA-(*pA<<2);
printf("%d",r3);

它分别打印出pA和(* pA <&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; 2)是int的大小。但是你需要考虑int的大小,因为你同时具有pA和(* pA <&lt;&lt; 2),并且它们的减法不等于它应该的范围。

感谢任何帮助...

为了记录,我对打印出指针的实际值不感兴趣,但实际上它的地址被移位了2位。而且我不了解正在发生的具体过程。

2 个答案:

答案 0 :(得分:5)

指针上的算术按其指向的大小进行缩放。因此,当您执行pA - 80时,您的代码实际上会pA - 80*sizeof(*pA)。这与<<无关。

您还应使用%p格式说明符打印地址。要将指针值存储为整数类型,请使用intptr_tuintptr_t(来自stdint.h)。在您的编译器上启用警告,如果您不这样做,它应该抱怨。

答案 1 :(得分:1)

取消引用运算符*的优先级高于左移运算符<<。因此,表达式*pA<<2实际上评估为(*pA)<<2。这会为pA提供指向的值,即a左移2。

看起来你想要的是pA<<2,但是指针不是<<运算符的有效操作数。没有定义指针值的乘法,也没有意义。但是,您可以添加或减少指针。

索引运算符[]是添加到指针和解除引用的语法糖,因此您可以使用它。但是,pA指的是单个int,而不是数组,所以这样做是undefined behavior