素数计划

时间:2013-10-16 12:40:29

标签: c numbers

我想用C语言创建一个用户输入的程序,我无法理解循环的逻辑。

for ( c = 2 ; c <= n - 1 ; c++ )

程序代码如下: -

#include<stdio.h>
#include<conio.h>

void main()
{
   int n, c;

   printf("Enter a number to check if it is prime\n");
   scanf("%d", &n);

   for ( c = 2 ; c <= n - 1 ; c++ )
   {
      if ( n % c == 0 )
      {
         printf("%d is not prime.\n", n);
         break;
      }
   }
   if ( c == n )
      printf("%d is prime.\n", n);

   getch();
}

我使用了for循环,它将在for循环中结束n - 1的语句。如果我将提供输入11,那么它最终会在11 - 1 = 10上,然后它将如何放弃if(c == n) { printf("%d", n);的逻辑?

4 个答案:

答案 0 :(得分:6)

  

如果我将提供输入11,那么它最终会在11 - 1 = 10上结束,那么它将如何放弃if(c == n) { printf("%d", n);的逻辑?

现在正确理解你的for循环条件:

for ( c = 2 ; c <= n - 1 ; c++ )
              ^^^^^^^^^^^^
              2 <= 11 - 1  -> True   // {for block executes }
              3 <= 11 - 1  -> True   // {for block executes }
                 :
                 :
              9 <= 11 - 1  -> True   // {for block executes }
              10 <= 11 - 1  -> True  // {for block executes }
              11 <= 11 - 1  -> False  breaks //{And Now for block NOT executes}

if (c == n)
    ^^^^^^
   11 == 11 -> True  // {if block executes} 

根据for循环条件c <= n - 1,当c值等于n时,循环中断。因此,如果n等于11c = 2c = 10的循环条件为真,则每次迭代c增加1(使用c++增量)当c变为11(或者说n)时,条件c <= n - 1变为false并且循环中断。

如果条件(for循环后)c值与n进行比较。那就是:

if ( c == n )
//   11 == 11  that is true

对于n = 11,如果条件评估为真,则变为c = 11,如果执行则与printf()相关联。


同样重要的是要理解,当c = n是素数时,for循环仅终止n,但如果假设n是非素数,那么 - 由于for循环中嵌套c块中的n - 1语句,循环将因break;值小于if而中断。

for( c = 2; c <= n - 1; c++ ) 
{
  if(n % c == 0)<=="for Non-prime `n`, if condition will be true for some `c < n - 1`"
  {  ^^^^^^^^^^^ True 
     printf("%d is not prime.\n", n);
     break; <== "move control outside for-loop"
  }  //      | 
}    //      |
// <---------+ // if break; executes control moves here with c < n - 1
if (c == n)<== "this condition will evaluates FALSE"  
   ^^^^^^^^ False

例如,如果n = 8,那么在for循环的第一次迭代中,如果条件c = 2的计算结果为if(n % c == 0) == if(8 % 2 == 0),那么值为if( 0 == 0)的for循环if-block中的true和break;语句将控制移到for-loop之外(如图所示)。

因为此循环时间因c <= n - 1条件而未终止但由于if(n % c == 0)而被制止,因此外部for循环c值小于n因此{ {1}}评估为False。

答案 1 :(得分:2)

for循环从c = 2循环到c = n - 1,除了命中break语句。如果是这样,它将跳出循环。如果你从未破坏,那么在循环之后你的c实际上将是n

这就是原因。循环的工作方式如下:

  1. 使用c = 2
  2. 初始化for循环
  3. 检查条件(c <= n - 1) 如果为true:执行循环体 if false:跳过循环
  4. c增加一个
  5. 转到2。
  6. 示例:假设您的n为3。

    1. 我们将c设置为2,现在为c == 2n == 3
    2. 2 <= 3 - 1为真,因此循环体将被执行
    3. 我们将c增加1,现在为c == 3n == 3
    4. 我们在说明中回到2.
    5. 3 <= 3 - 1是假的,所以我们现在不执行循环体并跳出循环
    6. 我们离开循环c == 3n == 3以及c == n 之后
    7. 因此,如果我们从未点击break语句c将在循环后等于n。如果 n不是素数,我们点击中断语句。如果我们中断c将错过至少一个增量,因此在循环后将c < n。现在c == n将评估为false,并且if ( c == n )的if语句主体将不会被执行。

      现在到if ( n%c == 0 )n%c表示nc,因此n的剩余部分由c表示。如果此余数为0,则cn的整数除数。因此,在循环中,您对任何大于1且小于n的除数进行n测试。

      如果n的除数除了1和它本身,n不能是素数。因此,如果您使用c点击任何1 < c < nn%c等于0 n就不能成为素数。

      提示:您不必测试大于√n的除数。

答案 2 :(得分:1)

您假设c最终为n - 1 不正确。如果您使用调试器逐步执行程序,则应该在循环结束时看到n == 11c == 11

如果我们没有提前中断那么循环体执行的最后一次确实是c == n - 1然后c然后递增并且循环不变测试失败所以在循环c == n之后。

答案 3 :(得分:0)

当你说一个数字是素数时,请考虑它意味着什么。 对于每个n>1, n<pr = 0的余数p/n = r,数字p为素数。

因此,这个循环遍历每个值(c)范围[2..p-1],测试剩余部分。

int isprime = 1; //use a flag to indicate prime, assume prime until proven otherwise
for ( c = 2 ; //initialize c=2, the first value in the range [2..p-1]
      c <= n - 1 ; //check whether c is still in the range [2..p-1]
      c++ ) //increment c to the next value in the range [2..p-1]
{
    if ( n % c == 0 ) //modulo '%' is the remainder of the integer division
    {
        isprime = 0;
        break;
    }
}
printf("%d %s prime.\n", n, isprime?"is":"is not");

不是通过检查循环计数器的副作用来测试数字是素数,为什么不在循环之前设置一个标志,然后在最后测试它作为素数的决定?结果是代码不那么脆弱,容易出错,而且更清晰。

想要节省大约一半的工作量?测试n%2后,我们知道没有数字k,k*2=n,对吗?所以检查范围[2..p/2],并将循环更改为,

for( c = 2; c <= n/2; c++ )

你能想到一个小于n/2的数字吗?

查找多个素数的有趣算法是Sieve of Erastosthenes