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

削减

我在 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 anything\n");它似乎没有做任何与功能相关的事情。但是,如果我删除此行或将其注释掉,我将不会得到任何输出。似乎printf("%i\n", k);第三个 for 循环内的行取决于之前发生的其他一些打印。

这里发生了什么?为什么在 for 循环之前进行一些 -任何- 打印会对循环中完全不相关的已识别素数的打印产生影响?

来自莫斯科的弗拉德

程序中的 for 循环中的此类表达式,如下所示

*(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] 指定第 E2 个元素E1(从零开始计数)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Getf行为与循环中的printf

为什么在使用getchar()的while循环中移动printf()会产生不同的结果?

为什么printf在运行循环中无法打印出NSObject?

在for循环中使用printf()函数

在while循环中反转printf函数的输出

没有初始打印语句,循环中的Printf无法工作

Printf被for循环阻止

使用printf然后在循环中使用scanf

在C中-for循环中的scanf()导致printf()运行多次

Ncurses 在 while 循环中使用 printf 时显示垃圾

为什么不执行这个 printf 语句

为什么printf语句无限执行?

这个小的printf循环似乎发出了一个额外的字节,为什么呢?

C、为什么printf一定要放在循环里面,而不是外面?

在 NASM 中使用 printf 循环

循环使用printf和fgets

来自数组的简单Printf循环

每当在fork()之前调用printf()时,每次调用fork()时,printf()的循环输出都会输出到stdout。为什么'\ n'可以解决这个问题?

为什么printf比echo好?

为什么插入printf语句会使我的函数正常工作?

为什么我的 printf() 语句运行两次?

echo和printf不会在bash中打印循环中分配的变量

Bash 文件描述符并在 while 循环中将 printf 写入文件

如何在for循环中仅打印带有echo或printf的一种情况

你如何像 printf 在 while 循环中打印字符一样打印字符?

循环重复 printf 但不重复 scanf

字符串 printf 的 Ocaml 循环

为什么bash的printf比/ usr / bin / printf快?

为什么在for循环中包含for循环