【问题标题】:Prime numbers using Sieve of erastosthenes in C在 C 中使用埃拉托色尼筛法的素数
【发布时间】:2012-12-21 01:41:27
【问题描述】:

我编写了以下程序来显示最多 150 的所有素数。它根本没有执行。它有什么问题?

# include <stdio.h>
int main(void)
{
    int p[150], i, j;

    for (i = 2; i < 150; i++)
        p[i] = 0;

    i = 2;


    while (i < 150){

        if (p[i] == 0)
            printf("%i ", i);

        for (j = 1; i*j <= 150; j++)
            p[i*j] = 1;

        i++;
    }

    return 0;
}

【问题讨论】:

    标签: c primes sieve-of-eratosthenes


    【解决方案1】:
    1. 您正在访问p[i*j],它超出了有效的[0-149] 范围。当 i*j 等于 150 时,条件 i*j &lt;= 150 将评估为真,即相差一。应该是i*j &lt; 150
    2. 标准输出流被缓冲。您需要在循环结束时刷新。尝试添加fflush(stdout)
    3. 可能不太重要,但是如果您关心结果数组(例如:想稍后使用它),p[2] 的值会错误地设置为 1。但是,您的程序仍会打印 2,但那是因为您的循环会在更改 p[i*j] 的值之前打印数字。总之,数字打印正确,但数组中的值并不完全正确。

    【讨论】:

    • 是的,逻辑给出了正确的答案。唯一的错误是 ij j
    • @user1825355 抱歉,我的回答不正确。逻辑上没有错误。这个答案是正确的。随意更改答案(我无法删除它,因为它已被接受)。
    • @jweyrich 是的,你说得有道理。我正在从这本“C 语言编程”中学习 C,这是书中的一个练习。虽然我让代码运行了,但我还是想知道“=”的存在是如何阻碍整个代码的。它本来可以给出一些输出,直到事情发生并且 i*j 还没有达到 150。但是根本没有输出。马上,代码进入无穷大
    • @user1825355:您看到的是堆栈中的值被覆盖的结果,而它不应该被覆盖(例如:p[150] = 1)。事实是 p[150] 正在访问您的数组之外的东西,这是未定义的行为。一切都有可能发生!由于我的回答中的第 2 点,您看不到任何输出。 stdout 被缓冲。换句话说,在写入换行符 (\n) 或刷新流(手动或进程终止时)之前,内容不会真正写入流。您也可以在每个printf 之后fflush(stdout),或使用setvbuf 禁用缓冲。
    • @jweyrich 感谢您的回复。我尚未了解 C 中的 I/O。我很欣赏您指出的“未定义行为”。一切都有可能发生。'
    【解决方案2】:

    i*j &lt;= 150 不正确,应该是i*j &lt; 150,因为p 数组有从0149 的元素。程序因此陷入无限循环。

    编辑:此答案的其余部分不正确,因此我已将其删除。

    【讨论】:

    • ij j
    • Because j = 1, every number will be marked as having a divisor. - 实际上,他的i 是从2 开始的,所以p[i*j] 只标记偶数。
    • 没关系。由于p[i*j] = 1j = 1,每个数字都将标记为p[i*1] = 1 => p[i] = 1。所以筛子不起作用。 j 必须从 2 开始
    • @QuasarDonkey 抱歉,您的逻辑有误。由于i 从 2 开始,在第一个循环中,2*j 将导致 [2,4,6,8,...]。第二个循环将导致 [3,6,9,12,...],第三个在 [4,8,12,16,...]。结论,这不会标记[2,3,5,7,11,13,...],毕竟这是正确的。
    • @jweyrich 是的,我现在明白了。当我将printf 拉出循环时,它巧妙地改变了逻辑。 我的 版本需要ij = 2。我的错:(我不能删除我的答案,直到它未被接受。
    【解决方案3】:

    作为学习练习,尝试添加一些 printf 来了解您的程序的功能。

    还请记住,正如 jweyrich 所说,没有 \n 的 printf 在(可能)程序退出之前不会输出任何内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-16
      相关资源
      最近更新 更多