我在 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 回圈之前進行一些 -任何- 列印會對回圈中完全不相關的已識別素數的列印產生影響?
uj5u.com熱心網友回復:
程式中的 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(從零開始計數)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/451787.html
