【问题标题】:C programming - Checking prime numberC 编程 - 检查素数
【发布时间】:2021-01-12 02:02:46
【问题描述】:

我正在尝试检查给定数字是否为素数,但我遇到了问题。这是代码:

#include <stdio.h>
#include <math.h>
#include <stdbool.h>

bool isPrime(int input)
{
    for (int i = sqrt(input); i >= 2; i--)
    {
        if (input % i == 0)
        {
            return false;
        }
    return true; 
    }
    
}

int main()
{
    int input;
    scanf("%d", &input);
    
    if (isPrime(input))
    {
        printf("Is prime number");
    } else
    {
        printf("Is not prime number");
    }
    
    return 0;
}

在我的isPrime函数的代码块中,如果我像上面一样将return true;放在for循环中,这在某些情况下会出错(例如,当input为10时,它将声明为10是素数)。但是,如果我将return true; 放在 for 循环之外,它就可以正常工作。那么有什么区别呢?

【问题讨论】:

  • return true; 立即结束函数,返回值为true。所以当你输入 10 时,函数会检查 10 / 3,然后返回true
  • 确实,如果您只在检查所有潜在除数后才返回 true,而不是在第一个除数之后,它会返回正确结果,真是令人惊讶。
  • 编译器警告:isPrime:并非所有控制路径都返回值。请将return true 移到循环外。编译器警告可以帮助您。
  • 这不是 Python。即使您没有缩进 return true; 行并不意味着它不在循环块内。在 C 中,缩进与编译器无关。

标签: c loops for-loop primes function-definition


【解决方案1】:

让我们来看看你的循环:

for (int i = sqrt(input); i >= 2; i--)
{

如果输入是10,则i3 开头(请记住,将浮点值分配给int 时,小数部分将被丢弃)。 3 大于等于2,所以循环体执行。

    if (input % i == 0)
    {

10 除以3 的余数不为零,因此我们进入if 语句的主体。

        return false;
    }
return true; 
}

然后我们立即返回true

因此,无论您提供什么输入,您的循环都只会迭代 1 次。如果input被其平方根的整数值整除(例如91625),则执行if语句的主体并返回false,否则它无条件返回true

为了让您的函数正常工作,您必须将 return true; 语句移到循环体之外 - 只有在用尽 i 的所有值时才应该返回 truesqrt(input)2 之间。

【讨论】:

    【解决方案2】:

    如果for循环中的第一个除数不除目标数,则函数返回true。

    因为这个return语句

        return true; 
    

    在 for 循环内。

    bool isPrime(int input)
    {
        for (int i = sqrt(input); i >= 2; i--)
        {
            if (input % i == 0)
            {
                return false;
            }
        return true; 
        }
        
    } 
    

    此外,如果为素数 23 调用该函数或将非正数传递给该函数,则该函数具有未定义的行为。

    放置return语句

    return true; 
    

    在循环之外不会使你的函数正确。

    注意除了2以外的偶数是素数还是非素数,是没有意义的。

    函数可以这样写

    bool isPrime( unsigned long long n )
    {
        bool prime = n % 2 == 0 ? n == 2 : n != 1;
    
        for ( unsigned long long int i = 3; prime && i <= n / i; i += 2 )
        {
            prime = n % i != 0;
        }
    
        return prime;  
    } 
    

    函数可以这样调用

    unsigned int input;
    scanf("%u", &input);
    
    if (isPrime(input))
    {
        printf("Is prime number");
    } else
    {
        printf("Is not prime number");
    }
    

    【讨论】:

      【解决方案3】:

      当您将return true; 放入循环中时,只要前面的if 条件为假,就会执行该语句。一旦你完成了for 循环并且没有找到除数,你只想返回true。这就是为什么return 语句需要在循环之外的原因。

      【讨论】:

        【解决方案4】:

        发生这种情况是因为你的 for 循环没有在 i 的完整遍历中结束,但是 return true 语句告诉代码在你的 if 条件第一次变为 false 时执行它,然后退出循环。所以,想象一下我给你 10 块巧克力棒,告诉你每个都咬一口,只收集深色的。你先咬一口,它很甜,你把它收起来。你咬第二口,天就黑了。你收集它并告诉我你已经完成了,虽然你实际上没有(你没有检查其余的巧克力棒,看看那里是否有更多的黑色巧克力棒)。这就是您在代码中所做的。希望这个例子清晰且有帮助:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-08-20
          • 2016-11-03
          • 1970-01-01
          • 2013-05-21
          • 1970-01-01
          • 1970-01-01
          • 2013-09-29
          • 1970-01-01
          相关资源
          最近更新 更多