为什么 for 循环中的 printf 语句似乎依赖于该循环之外的不相关的先前 printf ?

发布于 2025-01-17 13:52:03 字数 1549 浏览 3 评论 0原文

我正在用 C 语言实现“埃拉托斯特尼筛法”来寻找素数。我想出了以下代码:

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

void strike_multiples(int n, int *storage); // Function prototype
int ceiling = 500;  // Maximum integer up to which primes are found

int main(void) {
    int *ptr = malloc(sizeof(int) * ceiling);  // Create buffer in memory
    int no_of_primes_found = 0;
    printf("Print anything\n");
    for (int i = 0; i < ceiling; i++) {  // Initialise all elements in buffer to zero
        *(ptr + i * sizeof(int)) = 0;
    }

    for (int j = 2; j < (ceiling / 2) + 1; j++) {
        if (*(ptr + j * sizeof(int)) == 0) {
            strike_multiples(j, ptr);
        }
    }

    for (int k = 2; k < ceiling; k++) {
        if (*(ptr + sizeof(int) * k) == 0) {
            no_of_primes_found++;
            printf("%i\n", k);
        }
    }

    printf("%i primes found\n", no_of_primes_found);

    free(ptr);
    return 0;
}


void strike_multiples(int n, int *storage) {  // This function strikes all multiples of a given integer within the range
    for (int i = 2; i < (ceiling / n) + 1; i++) {   // (striking means setting the value of the corresponding index in the allocated memory to one)
        *(storage + sizeof(int) * n * i) = 1;
    }
}

这编译得很好,并且确实会给我最大 500 的素数(最后一个是 499)。但最奇怪的地方是 printf("Print everything\n"); 行。它似乎没有做任何与功能相关的事情。但如果我删除这一行或将其注释掉,我就不会得到任何输出。看起来第三个 for 循环内的 printf("%i\n", k); 行依赖于之前发生的其他一些打印。

这是怎么回事?为什么在 for 循环之前执行一些 - any - 打印会对循环中已识别素数的完全不相关的打印产生影响?

I was playing around in C to implement the "sieve of Eratosthenes" for finding primes. I came up with the following code:

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

void strike_multiples(int n, int *storage); // Function prototype
int ceiling = 500;  // Maximum integer up to which primes are found

int main(void) {
    int *ptr = malloc(sizeof(int) * ceiling);  // Create buffer in memory
    int no_of_primes_found = 0;
    printf("Print anything\n");
    for (int i = 0; i < ceiling; i++) {  // Initialise all elements in buffer to zero
        *(ptr + i * sizeof(int)) = 0;
    }

    for (int j = 2; j < (ceiling / 2) + 1; j++) {
        if (*(ptr + j * sizeof(int)) == 0) {
            strike_multiples(j, ptr);
        }
    }

    for (int k = 2; k < ceiling; k++) {
        if (*(ptr + sizeof(int) * k) == 0) {
            no_of_primes_found++;
            printf("%i\n", k);
        }
    }

    printf("%i primes found\n", no_of_primes_found);

    free(ptr);
    return 0;
}


void strike_multiples(int n, int *storage) {  // This function strikes all multiples of a given integer within the range
    for (int i = 2; i < (ceiling / n) + 1; i++) {   // (striking means setting the value of the corresponding index in the allocated memory to one)
        *(storage + sizeof(int) * n * i) = 1;
    }
}

This compiles fine and will, indeed, give me primes up to 500 (the last of which is 499). But the wird thing about this is the line printf("Print anything\n");. It doesn't seem to be doing anything that's relevant for functionality. But if I delete this line, or comment it out, I'm not getting any output. It seems that the printf("%i\n", k); line inside the third for loop is dependent on some other printing taking place earlier.

What is going on here? How come that doing some - any - printing before the for loop makes a difference for the entirely unrelated printing of an identrified prime in the loop?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遇见了你 2025-01-24 13:52:03

这样的程序中的循环中的这种表达式

*(ptr + i * sizeof(int)) = 0;

不正确,并导致不确定的行为。

相反,您需要编写

*(ptr + i) = 0;

此表达式等效

ptr[i] = 0;

于C标准(6.5.2.1阵列订阅)

2一个后缀表达式,然后在方括号中表达式[]
是数组对象元素的订阅名称。
下标运算符的定义是E1 [e2]与
(*((E1)+(e2)))。
,因为适用于
二进制 +运算符,如果E1是一个数组对象(等效地,指针
对于数组对象的初始元素)和E2是整数,
e1 [e2]指定E1的E2元素(从零计数)。

Such expressions in for loops in your program like this

*(ptr + i * sizeof(int)) = 0;

are incorrect and lead to undefined behavior.

Instead you need to write

*(ptr + i) = 0;

This expression is equivalent to

ptr[i] = 0;

From the C Standard (6.5.2.1 Array subscripting)

2 A postfix expression followed by an expression in square brackets []
is a subscripted designation of an element of an array object. The
definition of the subscript operator [] is that E1[E2] is identical to
(*((E1)+(E2))).
Because of the conversion rules that apply to the
binary + operator, if E1 is an array object (equivalently, a pointer
to the initial element of an array object) and E2 is an integer,
E1[E2] designates the E2-th element of E1 (counting from zero).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文