C语言中的位移操作

3
int x = 2;

x = rotateInt('L', x, 1); // should return 4

x = rotateInt('R', x, 3); // should return 64

这里是代码,请有人检查一下并让我知道错误在哪里?

编译成功,但在执行时出现分段错误

int rotateInt(char direction, unsigned int x, int y)
{
  int i;

  for(i = 0; i < y; i++)
  {  

    if(direction == 'R')
    {
       if((x & 1) == 1)
       {
         x = x >> 1;
         x = (x ^ 128);     
       }
       else    
         x = x >> 1;
     }
     else if(direction == 'L')
     {
       if((x & 128) == 1)  
       {
         x = x << 1;
         x = (x ^ 1);     
       }  
       else
       x = x << 1;
     }
   }
   return x;   
 }

3
如果您已经解决了10分钟前的相关问题http://stackoverflow.com/questions/3928659/rotating-bits-of-any-integer-in-c,您可能希望在继续之前接受一个答案。 - Dusty
4个回答

9

现在就开始磨练你的调试技能吧。如果你想成为任何形式的工程师,你都需要编写各种程序,并且一生都会进行调试。

一个简单的调试方法是插入打印语句,以查看代码在哪里出错并停止运行。我建议你先从隔离错误开始。


它仅打印分段错误,就是这样。 - Tim
这意味着在你的第一个 print 语句之前就已经崩溃了。将打印语句移到更早的位置并重试。重复此操作,直到确定哪一行导致了段错误。 - Josh
1
@Josh,这正是我要说的,谢谢。别忘了在你的printf语句中加入\n来刷新流。 - San Jacinto
为了额外的加分,请学习如何使用调试器。使用调试器通常比使用printf快速地找到问题。 - bstpierre
@bstpierre 确实,但我觉得如果我们还没有发现 printf 调试的话,那么我们还没有准备好理解调试器的概念 :) - San Jacinto

2

我不确定段错误的原因,但我认为

if((x & 128) == 1)  

应该是

if((x & 128) == 128)

或者只是

if(x & 128)  

1

我在我的电脑上尝试了一下(MacBookPro / Core2Duo),它可以工作。 顺便问一下,你的目标架构是什么?有些(很多)处理器在使用C运算符">>"和"<<"时执行旋转而不是移位。


好的,我假设这是一台英特尔机器,它不会旋转(至少不是我的英特尔Core2Duo的情况)。然而,在整数旋转的情况下,它会使用0xff来掩盖参数(即“0xff00 >> 16 = 0”,但“0xff00 >> 40 = 0xff”)。 - Antoine Trouve
一个编译器如果在 <<>> 运算符中执行实际的位旋转而不是纯移位,那么它将不符合标准。我在运算符的定义中没有看到任何余地。它们是移位而不是旋转,自语言诞生以来就是这样。请参阅 C99,第6.5.7节,其中写道:“E1 << E2 的结果是 E1 左移 E2 个位位置;空出的位用零填充。” 它继续详细描述了定义行为的边界。右移类似地描述,但具有略微不同的边界。 - RBerteig
不是编译器的问题,而是处理器的问题。例如,PowerPC的移位指令可以进行旋转。 - Antoine Trouve
1
@Antoine,旋转在<<运算符的实现中是不允许的。标准语言非常明确。它继续说,只要值在范围内,E1<<E2等同于乘以2的幂次方。同时,向左移动零位或负数位和超过整数类型位数的位数都是未定义行为。 - RBerteig
@Antoine 在 Suse x86_64 上使用 gcc 对我来说产生了 0 的结果,我非常怀疑 gcc 会为 PowerPC 架构而打破标准。 - San Jacinto
显示剩余2条评论

0
当你使用 ^ 的时候,你是不是指的是或运算符 |

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接