C語言「尋找100000以內的所有素數?」為什麼這麼寫?

不知道為什麼必須要添加第17行的代碼,否則就會段錯誤。


在32位系統下,int型變數的上限是2147483647。sqrt(2147483647)約等於46340。當i&>46340時,j=i*i;溢出,溢出後j可能為負數或特別大的數。

然後循環開始,我們給mark[j]賦值,而j是負數或者超過mark數組大小的數。這是未定義操作,便發生了錯誤。

題主可以在18行後將j列印出來,會加深印象。


你在代碼用了bool, 不加stdbool.h 頭文件, gcc是編譯不過的。

這個是我在 求十億內所有質數的和,怎麼做最快? - 鄧攀的回答 的回答隨便改的。

之所以用 bool *state = (bool *)malloc(sizeof(bool) * (MAX+1)); 開數組,是你把

#define MAX 1000000000 也可以的。

開超大數組建議用malloc 在堆上算, 不然你隨時注意棧內存溢出。linux 棧內存是8M, 開int數組大概可以開200w,  堆就限制很少了。

#include &
#include &
#include &
#include &

#include & #define MAX 100000

int main()
{
bool *state = (bool *)malloc(sizeof(bool) * (MAX+1));
//bool state[MAX];
int64_t sq = sqrt(MAX);

for(int64_t i = 2; i&<= sq; ++ i) { if(!state[i]) { for(int64_t j = i*i; j &<= MAX; j += i) { state[j] = true; } } } int64_t num = 0; for(int64_t i = 2; i &<= MAX; ++ i) { if(!state[i]) { num ++; } } free(state);//如果是 bool state[MAX]; 就不要這句 printf("the total num : %lld ", num); for(int64_t i = 2; i &<= MAX; ++ i) { if(!state[i]) { printf("%lld ", i) } } return 0; }


第一個for循環和賦值是廢話,全局變數默認以0初始化,你再用false / 0賦值一遍沒有意義

j = i*i有可能會溢出為負值,取負值的下標多半是錯的

還有你沒有include &就能使用bool類型,說明你是用的c++編譯器編譯的這段代碼!!

不要用cpp後綴來保存C代碼!!!!!!

不要把C,C++混為一談!!!!!!

C和C++是兩種不同的語言!!!!!!


很多回答指出了代碼中的問題,但其實這個寫法本身就很垃圾(那3個外部變數),根本不值得改。


吐槽一下,第17行的這個

if (i&>=1000) continue;

因為 lceil sqrt{100000} 
ceil=317,所以應該改成

if (i&>=317) continue;

否則 j 會超出 mark[] 的取值範圍,造成泄漏。


強制停止,否則會溢出報錯


這是哪個ide,看起來很舒服啊。


1.出錯時因為溢出

2.添加17行正確是因為1000=sqrt(100000)


正確的寫法是把i的循環上界改成i*i&<=100000


推薦閱讀:

Dijkstra演算法能否用於有環圖?
如何判斷一個 16 位乃至更高位的整數是否為一個素數?
如何求有向圖的鄰接矩陣的冪斂指數和周期?
如果兩台阿法狗對弈上億次並不斷修正演算法,會不會創造出來絕世的棋局?
為什麼說 MD5 是不可逆的?

TAG:演算法 | 編程 | C編程語言 | OnlineJudge |