我的代码中有一些错误的递归素数函数

时间:2014-02-07 19:31:01

标签: c recursion goto

我应该输入一个正数,终端应该打印它是否为素数。此外,它应该要求用户重复输入一个数字,直到用户按下“q”。它没有goto循环工作正常,即一次一个。

有人可以说出我的代码有什么问题吗?

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

prime(int a, int b) {
  if (a == 1) {
    printf("neither prime nor composite\n");
    return;
  } else if ((a % b) == 0) {
    printf("composite no.\n");
    return;
  } else if (b >= a) {
    printf("prime no.\n");
    return;
  } else
    prime(a, (b + 1));
}

main(void) {
  int x, y = 0, z;
  char a[10], b;
  loops: printf("enter an integer:\t");
  do {
    b = getchar();
    if (b == 'q')
      exit(1);
    x = atoi(&b);
    y = (10 * y) + x;
  } while (b != '\n');
  z = y / 10;
  printf("num is %d and it's\t", z);
  prime(z, 2);
  goto loops;
  return 0;
}

4 个答案:

答案 0 :(得分:1)

在循环开始时不要将y初始化为0

答案 1 :(得分:1)

1.我们应该避免使用goto,因为它就像跳转指令一样。单个goto指令可以正常但是当你有多个指令时很难调试代码。

2.条件(a == 1,我们应该检查主函数,如果它是真的那么返回。鉴于CPU使用情况很好。

3.应该使用最小变量,因为它会占用内存。所以我删除'b'和'y'变量。

无论如何,我对您的示例代码进行了一些修改,它可以为您提供帮助。

 #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    prime(int a, int b){
    if(b==a){printf("prime no.\n");    return;}
    else if(((a%b) == 0) ){printf("composite no.\n");  return;}
    else    prime(a, (b+1));
    }

    main(void){
    int x, y = 0, z;
    char a[10], b;
    loops:
    printf("enter an integer:\t");
    scanf("%d",&x);
    if(x == -1)    exit(1);
    if( x == 1){printf("neither prime nor composite\n"); return;}
    z=x;
    printf("num is %d and it's\t", z);
    prime(z, 2);
    goto loops;
    return 0;
    }

答案 2 :(得分:0)

如果你真的不需要,请避免使用goto

要围绕不使用goto构建代码,请尝试以下操作:

// ...
char userInput;
do
{
    printf("enter an integer:\t");
    userInput = getchar();
    if (userInput == 'q')
    {
        break;
    }
    // ... perform prime number calculation ...
} while (true); // Continue to loop until the user enters 'q'.
// ...
return 0;

这应该一直提示用户输入一个字符,直到用户输入'q'。

答案 3 :(得分:0)

你有三个问题。首先 - 每个循环需要将y的值重置为零 - 将行更改为:

main(void) {
  int x, y, z;
  char a[10], b;
  loops: printf("enter an integer:\t");
  y = 0;    // <<<< add this line
  do {

其次,prime函数会在(a%b==0)之前调用一个数字“复合”,然后才会意识到a==b(从中你可以正确地得出这个数字是素数)。按如下方式更改测试顺序:

prime(int a, int b) {
  if (a == 1) {
    printf("neither prime nor composite\n");
    return;
  } else if (b >= a) {         // <<<<< do this test first
    printf("prime no.\n");
    return;
  } else if ((a % b) == 0) {
    printf("composite no.\n");
    return;
  } else
    prime(a, (b + 1));
}

第三 - 您正在将值读入char,然后使用atoi(&b)将其转换为int。这充满了危险 - 你侥幸逃脱它,因为事实证明之后的空间里没有任何东西,并且这个角色“意外地被终止”。为了安全起见,你想做

x = b - '0';
if(x >= 0 && x <= 9) {
  y = (10 * y) + x;
}

这会将b中的字符转换为数字 - 如果字符不是数字,它将跳过它并转到下一个。这也意味着您不再需要在循环后将y除以10。

如果您发现它仍然无效,则可能输入缓冲区出现问题。有时回车中有一个备用字符(CRLF实际上是两个字符......)

您可以添加

fflush(stdin);

开始阅读输入之前(y=0;之后)。

所有这些事情共同导致以下结果:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

prime(int a, int b) {
  if (a == 1) {
    printf("neither prime nor composite\n");
    return;
  } else if (b >= a) {
    printf("prime no.\n");
    return;
  } else if ((a % b) == 0) {
    printf("composite no.\n");
    return;
  } else
    prime(a, (b + 1));
}

main(void) {
  int x, y = 0, z;
  char a[10], b;
  loops: printf("enter an integer:\t");
  y = 0;
  fflush(stdin);
  do {
    b = getchar();
    if (b == 'q')
      exit(1);
    x = b - '0';
    if(x >= 0 && x <= 9) {
      y = (10 * y) + x;
    }
  } while (b != '\n');
  printf("num is %d and it's\t", y);
  prime(y, 2);
  goto loops;
  return 0;
}

仍然不漂亮(你真的不想/在这种代码中需要goto)但它应该适合你。对于您的下一个项目,请了解使用while循环而不是goto的正确方法......