【问题标题】:Infinite while loop issue with a conditional operation function带有条件操作函数的无限while循环问题
【发布时间】:2021-11-26 15:54:29
【问题描述】:

我的代码陷入了无限循环。当前数字减半,当下一个数字为偶数时,该函数应执行 2n+1。如果奇数,它应该执行 3n + 1。一旦执行任何一个操作,它应该再次减半并循环直到 n = 1。这是代码:

#include "stdio.h"
#include "assert.h" // ?

long int hailstone(long int k);

int main(void) {
  long int n = 77;
  hailstone(n);
  
  return 0;
}

long int hailstone(long int k) {
  while (k != 1) {
    k = k/2;
    if (k % 2 == 0) {
          k = 2 * k + 1;
          printf("%lu", k);
    
    } else if (k % 2 != 0) {
          k = 3 * k + 1;
          printf("%lu", k);
      
    } else if (k == 1) {
          printf("blue sky!");
    }
  }
}

特定的断言会帮助编译器按预期执行代码吗?

【问题讨论】:

  • 您是否意识到您在while (k != 1) 中有一个if (k == 1)?而且同样的if (k == 1)else 分支中既是偶数​​又是奇数?
  • kwhile(k != 1) 循环中测试时永远不会是1,而另一个测试if(k == 1) 永远不会到达。
  • 使用非常基本的 printf 调试(基本上只是查看您的输出)您应该注意到k 在 77 和 38 之间波动。77 除以 2 得到 38。然后计算 2 * 38 + 1 让你回到 77。你的算法有问题。
  • ref 可能会有所帮助。我怀疑“当下一个数字是偶数时,该函数应该执行 2n+1。”不正确。
  • 当我注意到我的评论错误地引用了您的代码时,我不得不眨眼:回滚。请不要问流沙问题!

标签: c loops while-loop conditional-statements assert


【解决方案1】:

据我了解您的代码

如果 n 的值是 pair ,你做这个 n/2 ,如果不是你显示 3*n+1

我的代码:

输出:116,58,29,44,22,11,17,26,13,20,10,5,8,4,2,1

#include "stdio.h"
#include "assert.h" // ?


long int hailstone(long int k);

int main(void)
{
    long int n = 77;
    hailstone(n);
    return 0;
}

long int hailstone(long int k)
{
    while (k != 1)
    {
       if ( k % 2 ==0)
       {
           printf("k = %lu\n",k/2);
           k/=2;   // k=k/2
       }
       else
       {
           k = 3 * k + 1;
       }
    }
        printf("blue sky!\n");
    
}

【讨论】:

  • 最后的测试是不必要的。只有k == 1 才能到达那里。
  • @cornuz :完成了
【解决方案2】:

您的代码过于复杂和错误。

基本上可以归结为这个(试试看):

long int hailstone(long int k) {
  while (k != 1) {
    k = k/2;
    printf("k divided by 2: %lu\n", k);
    if (k % 2 == 0) {
      k = 2 * k + 1;
      printf("k after k = 2 * k + 1 %lu\n", k);
    }
  }
}

输出:

k divided by 2: 38
k after k = 2 * k + 1 77
k divided by 2: 38
k after k = 2 * k + 1 77
k divided by 2: 38
k after k = 2 * k + 1 77
...

只是盲目地应用definitions

#include <stdio.h>

void hailstone(long int k);

int main(void) {
  long int n = 77;
  hailstone(n);    
  return 0;
}

long int func(long int k)
{
  if (k % 2 == 0)
    return k / 2;
  else
    return 3 * k + 1;
}

void hailstone(long int k) {
  while (k != 1)
  {
    printf("k = %d\n", k);
    k = func(k);
  }
}

【讨论】:

  • 感谢您的回答。我测试了这段代码,它按预期运行。我的过于复杂。使用编译器标志运行代码时:Wall、Wpedantic、Wextra,我在第 25 行收到警告:控制到达非空函数的结尾 [-Wreturn-type] 25 | }
  • @JoeP 警告是正常的,应该是void hailstone(long int k) 而不是long int hailstone(long int k)
【解决方案3】:

特定的断言会帮助编译器按预期执行代码吗?

没有

断言用于停止某些事件的执行。

【讨论】:

    猜你喜欢
    • 2014-06-07
    • 2020-08-18
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多