简体   繁体   English

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

[英]Why does a printf statement in a for loop seem to depend on an unrelated previous printf outside that loop?

I was playing around in C to implement the "sieve of Eratosthenes" for finding primes.我在 C 中玩耍,以实现“Eratosthenes 筛法”来寻找素数。 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).这编译得很好,确实会给我最多 500 个素数(最后一个是 499)。 But the wird thing about this is the line printf("Print anything\n");但最奇怪的是行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);但是,如果我删除此行或将其注释掉,我将不会收到任何 output。似乎printf("%i\n", k); line inside the third for loop is dependent on some other printing taking place earlier.第三个 for 循环中的行依赖于之前发生的一些其他打印。

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?为什么在 for 循环之前进行一些 -任何- 打印会对循环中已识别素数的完全不相关的打印产生影响?

Such expressions in for loops in your program like this程序中 for 循环中的此类表达式如下所示

*(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)来自 C 标准(6.5.2.1 数组下标)

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))). 2 后缀表达式后跟方括号[]中的表达式是数组object中元素的下标指定。下标运算符[]的定义是E1[E2]等同于(*((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).由于适用于二元 + 运算符的转换规则,如果 E1 是数组 object(等效于指向数组对象的初始元素的指针)并且 E2 是 integer,则 E1[E2] 指定的第 E2 个元素E1(从零开始计数)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM