n個の素数を求めるプログラムについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
素人

n個の素数を求めるプログラムについて

#1

投稿記事 by 素人 » 12年前

nまでの素数の個数を求めるプログラムを作りました。
これを利用してINT_MAXとUINT_MAXを求めたいのですが実行出来ません。
なぜ実行できないのでしょうか
また、どうすればうまく実行させれますか?
よろしくお願いします。

コード:

#include <stdio.h>
#include<math.h>
#include<time.h>
#include<limits.h>

void main(int argc, char *argv[])
{
	unsigned int i, j, n, sqrtn;	//nまでの素数を求める
	unsigned int sqrtn;		//√nまでの素数をふるいにかける
	char *flags;			//フラグを格納する配列
	int np = 0;				//素数の個数
	time_t t1, t2, t3;		//タイマー
	
	flags=(char *)malloc(n = atoi(argv[1]) + 1000);
	
	t1 = clock();
	
	flags[0] = flags[1] =1;
	flags[2] = 0;
	flags[3] = 0;
	for(i=4; i<=n; i+=2){
		flags[i]     = 1;
		flags[i+1] = 0;
	}
		sqrtn = (int)sqrt((double)n);
	for(i=3; i<= sqrtn; i+=2){
		if(flags[i] == 0){
			for(j=i*i; j<=n; j+=2*i){
				flags[j] = 1;
			}
		}
	}
	t2 = clock();
	
	for(i=0; i<=n; i++)
		if(flags[i] == 0){
			np++;
			printf(" %d", i);
		}
		printf("\n%uまでに%d個の素数が見つかりました\n", n, np);
		t3 = clock();
		printf("計算時間: %10.3fsec\n",	(t2-t1)/1000.0);
		printf("出力時間: %10.3fsec\n",	(t3-t2)/1000.0);
		printf("合計時間: %10.3fsec\n",	(t3-t1)/1000.0);
		
		return ;
}

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: n個の素数を求めるプログラムについて

#2

投稿記事 by h2so5 » 12年前

素人 さんが書きました:これを利用してINT_MAXとUINT_MAXを求めたいのですが実行出来ません。
求めるも何も、INT_MAXとUINT_MAXは定数ですよ?

素人

Re: n個の素数を求めるプログラムについて

#3

投稿記事 by 素人 » 12年前

h2so5 さんが書きました:
素人 さんが書きました:これを利用してINT_MAXとUINT_MAXを求めたいのですが実行出来ません。
求めるも何も、INT_MAXとUINT_MAXは定数ですよ?
すみません、抜けてました。
INT_MAXとUINT_MAXまでの素数の数を求めたいのです。

アバター
spaaaark・∀・
記事: 66
登録日時: 12年前
住所: 埼玉
連絡を取る:

Re: n個の素数を求めるプログラムについて

#4

投稿記事 by spaaaark・∀・ » 12年前

ソースを実行してみましたが、いくつかのコンパイルエラーを吐きました。
コンパイルエラーの際はエラーログを付属していただき、その旨を伝えていただけるとうれしいです。

さて、このプログラムにはいくつか問題点があります。

1.malloc関数等を使用しているのに、stdlib.hをincludeしていない。
malloc関数は標準ライブラリのstdlib.hに定義されています。これを読み込まないとこれらの関数は使用することができません。

2.sqrtn変数を多重に宣言している。
同じ型ではありますが、宣言でsqrtn変数が2回宣言されていました。
もしこの2つの使用用途が異なるなら、1つを別の変数名(もちろん他とかぶらない名前)に、
そうでなければ片側の宣言は消してしまいましょう。

3.malloc変数の引数指定
malloc関数の引数には、確保するサイズの大きさを指定します。今回、あなたはatoi関数を使用していましたが、それではまずいことになります。
また、今回私はBorland C++のコンパイラを使用しましたが、*argv[]の中身は不定(未初期化)で、このままではこの関数は0を返してしまいます。
また、そこで同時にnを定義しようとして失敗してしまっています。
この問題を解決するためには、前もって求めたい最大の数字(nの数字)を指定して、malloc関数の引数に、sizeof演算子を使うとうまくいくと思います。
sizeof演算子の使い方については、ここではあえて説明しません。自分で使ってみて、使用方法を覚えてみてください。
また、sizeの大きさを求めるためには足し算ではなく掛け算のほうがいいと思われます。

4.free関数で確保したメモリを開放していない。
これは直接プログラムエラーとはかかわりがないですが、非常に重要なことです。
malloc関数で確保したメモリは、必ずfree関数で解放するよう必要のあることが、どこの参考書、webサイトにも載っていると思われます。
これを行わないと、メモリリークというバグが生じてしまい、最悪の場合アプリケーションだけでなく、OSまでも落ちてしまいかねない致命的なバグになります。
プログラムの最後にこのfree関数を使用するようにしてください。

ここまで問題点の指摘をしましたが、素数を求めるアルゴリズムは間違っていないと思われます。
恐らく、これらの問題点を解決すれば、あなたの求めている目標に到達できると思います。
少しバグ修正が大変だと思われますが、頑張ってみてください。
最後に編集したユーザー spaaaark・∀・ on 2013年7月30日(火) 21:36 [ 編集 1 回目 ]
クリエイティブな生活で刺激的な毎日を!

box
記事: 2002
登録日時: 14年前

Re: n個の素数を求めるプログラムについて

#5

投稿記事 by box » 12年前

3~nとなっている箇所をINT_MAX~UINT_MAXとなるようにすれば
いいのではないでしょうか。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: n個の素数を求めるプログラムについて

#6

投稿記事 by みけCAT » 12年前

int型が4バイトの環境では、INT_MAX≒20億、UINT_MAX≒40億です。
40億要素のchar型の配列を確保しようとすると、char型が1バイトの環境では約4GBになります。
素人さんのパソコンに何GBのメモリ(RAM)が積まれているかわかりませんが、
自分のパソコンでは全部で3GBほどしかRAMが使えないので、配列が確保できないか動作がおかしくなる可能性があります。
アルゴリズムはエラトステネスのふるいのようですので、1バイトごとではなく1ビットごとでフラグを管理するべきだと思います。
(これならメモリ使用率が512MBになって現実的です)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: n個の素数を求めるプログラムについて

#7

投稿記事 by かずま » 12年前

次のプログラムを実行してみてください。どうなりますか?

コード:

#include <stdio.h>
#include <limits.h>

int main(void)
{
    unsigned int u;
    for (u = UINT_MAX - 10; u <= UINT_MAX; u++)
        printf("%u\n", u);
    return 0;
}

閉鎖

“C言語何でも質問掲示板” へ戻る