为什么 for 循环中的 printf 语句似乎依赖于该循环外不相关的先前 printf?
Why does a printf statement in a for loop seem to depend on an unrelated previous printf outside that loop?
我正在用 C 来实现寻找素数的“Eratosthenes 筛法”。我想出了以下代码:
#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");
行。它似乎没有做任何与功能相关的事情。但是,如果我删除此行或将其注释掉,我将不会得到任何输出。似乎第三个 for 循环中的 printf("%i\n", k);
行依赖于之前发生的一些其他打印。
这是怎么回事?为什么做一些 - any - 在 for 循环之前打印会对循环中完全不相关的已识别素数的打印产生影响?
在你的程序中这样的for循环表达式
*(ptr + i * sizeof(int)) = 0;
不正确并导致未定义的行为。
你需要写成
*(ptr + i) = 0;
这个表达式等同于
ptr[i] = 0;
来自 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))). 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).
我正在用 C 来实现寻找素数的“Eratosthenes 筛法”。我想出了以下代码:
#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");
行。它似乎没有做任何与功能相关的事情。但是,如果我删除此行或将其注释掉,我将不会得到任何输出。似乎第三个 for 循环中的 printf("%i\n", k);
行依赖于之前发生的一些其他打印。
这是怎么回事?为什么做一些 - any - 在 for 循环之前打印会对循环中完全不相关的已识别素数的打印产生影响?
在你的程序中这样的for循环表达式
*(ptr + i * sizeof(int)) = 0;
不正确并导致未定义的行为。
你需要写成
*(ptr + i) = 0;
这个表达式等同于
ptr[i] = 0;
来自 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))). 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).