• ベストアンサー

マージソートのプログラム

↓が自分の作ったマージソートのプログラムなのですが、コンパイルするとエラーが起きてしまいます。 mergesort()にポインタを引数として渡してる、引数の数が足りない、ということが書いてありますが…。 ちゃんとint型を渡してるし、引数の数も合ってるように思います。 どこがおかしいのでしょう? #include<stdio.h> #include<stdlib.h> #include<time.h> #define Max 255 int A[Max]; main(){ int n,k; n=inputdata(); int w=1; mergesort(w,n); printdata(n); return(0); } inputdata(){ //配列に乱数を要素として入れていく int n,i; printf("n= "); scanf("%d",&n); //使用者にいくつの要素を入れるか指定してもらう srand(time(NULL)); for(i=1; i<=n; i++){ A[i]=1+rand()%30; } printf("A[%d]={%d,",n,A[1]); for(i=2;i<n;i++) printf("%d,",A[i]); printf("%d}\n",A[n]); return(n); } void mergesort(int p, int r){ int q; if(p<r){ q=(p+r)/2; mergesort(p,q); mergesort(q+1,r); merge(p,q,r); } } void merge(int p, int q, int r){ int i,j,k,B[Max]; i=p; j=q+1; for(k=p;k<=r;k++){ if((j>r) || ((i<=q)&&(A[i]<=A[j]))){ B[k]=A[i]; i++; }else{ B[k]=A[j]; j++; } } for(k=p; k<=r; k++) A[k]=B[k]; } printdata(int n){ int i; printf("A[%d]={%d,",n,A[1]); for(i=2; i<n; i++) printf("%d,",A[i]); printf("%d}\n",A[n]); } ・エラーメッセージ merge1.c: In function ‘main’: merge1.c:12: warning: passing argument 1 of ‘mergesort’ makes pointer from integer without a cast merge1.c:12: error: too few arguments to function ‘mergesort’ merge1.c: At top level: merge1.c:31: error: conflicting types for ‘mergesort’ /usr/include/stdlib.h:294: error: previous declaration of ‘mergesort’ was here merge1.c:41: warning: conflicting types for ‘merge’ merge1.c:37: warning: previous implicit declaration of ‘merge’ was here

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8514/19356)
回答No.2

>どこがおかしいのでしょう? 書いている順番がおかしい。 まず、mainが一番上にあり、呼ばれる関数本体が定義される前に呼び出しをしているのが悪い。 この場合、Cコンパイラは「関数が定義されていないので、引数と返り値を勝手に予想」してコンパイルしてしまう。 で、関数の本体が現れた段階で「予想したのと違う」って言って、エラーになったりワーニングになったりする。 それと、運悪く、stdlib.hに「既にmergesortというのが定義されてて、名前が衝突している」ので、mergesortと言う名前の関数は使えない。 もう一つは、mainで main(){ int n,k; n=inputdata(); int w=1; とやってて、実効コードが現れた後で、変数の宣言をしようとしているので、ここでエラーになる。 他にも「intを返す関数に、戻り値の型を書いてない」」とか「引数無しの関数に、引数が無い事を示すvoidと書かれてない」とか、色々問題点が山盛り。 で、それらを全て修正し、ワーニングが出ないようにしたのが、以下のソースコード。 #include<stdio.h> #include<stdlib.h> #include<time.h> #define Max 255 int A[Max]; /*関数は呼ばれる前に実体を定義する事*/ /*inputdataはmainから呼ばれるので、mainより先に関数本体を定義する事*/ /*intを返す関数には、ちゃんと「intを返す」と書く事*/ /*引数が無い場合は引数無しを明示するため、引数に「void」と書く事*/ int inputdata(void){ //配列に乱数を要素として入れていく int n,i; printf("n= "); scanf("%d",&n); //使用者にいくつの要素を入れるか指定してもらう srand(time(NULL)); for(i=1; i<=n; i++){ A[i]=1+rand()%30; } printf("A[%d]={%d,",n,A[1]); for(i=2;i<n;i++) printf("%d,",A[i]); printf("%d}\n",A[n]); return(n); } /*関数は呼ばれる前に実体を定義する事*/ /*mergeはmerge_sortから呼ばれるので、merge_sortより先に関数本体を定義する事*/ void merge(int p, int q, int r){ int i,j,k,B[Max]; i=p; j=q+1; for(k=p;k<=r;k++){ if((j>r) || ((i<=q)&&(A[i]<=A[j]))){ B[k]=A[i]; i++; }else{ B[k]=A[j]; j++; } } for(k=p; k<=r; k++) A[k]=B[k]; } /*関数は呼ばれる前に実体を定義する事*/ /*merge_sortはmainから呼ばれるので、mainより先に関数本体を定義する事*/ /*mergesortと言う関数名は使えないので変更する事*/ void merge_sort(int p, int r){ int q; if(p<r){ q=(p+r)/2; merge_sort(p,q); merge_sort(q+1,r); merge(p,q,r); } } /*関数は呼ばれる前に実体を定義する事*/ /*printdataはmainから呼ばれるので、mainより先に関数本体を定義する事*/ /*返り値が無いのなら、関数の戻り値の型をvoidにする事*/ void printdata(int n){ int i; printf("A[%d]={%d,",n,A[1]); for(i=2; i<n; i++) printf("%d,",A[i]); printf("%d}\n",A[n]); } /*mainを呼ぶ人は居ないので、必然的にmainの実体は一番最後に書く事になる*/ /*intを返す関数には、ちゃんと「intを返す」と書く事*/ /*引数が無い場合は引数無しを明示するため、引数に「void」と書く事*/ int main(void){ int n,k; int w=1; /*変数の宣言は実効コードより前に行う事*/ n=inputdata(); /*これは実効コード。これ以降は変数の宣言は出来ない*/ /*int w=1; 実効コードの後に変数は宣言できない*/ merge_sort(w,n); printdata(n); return(0); } どうだろうか?これでエラーもワーニングも出ない筈。 質問者さんは「どのプログラムを見ても、mainが一番最後にあるな。なんでだろう?」って思った事は無いだろうか? これは「関数を参照(呼び出し)する前に、関数の実体を定義しておく」と言う書き方をしているから。 普通、変数は int i; と定義を済ませた後で i=0; と言うように参照や代入を行う。 関数もこれと同じで int inputdata(void){ 中身 } と定義を済ませた後で int main(void){ (略) n=inputdata(); というように参照(呼び出し)を行う。 Cのお約束の「定義してから使う」って言うのは、関数にも当てはまる話なのだ。 -------------------------------- ここから蛇足。読み飛ばしても可。 もし「mainが最初に無いと、なんか気持ち悪い」と言うなら、実体が定義される前の関数を正しく呼べるように、関数のプロトタイプ宣言を行ってから、実体が後から定義される関数を呼べば良い。 すると、以下のようになる。 #include<stdio.h> #include<stdlib.h> #include<time.h> #define Max 255 int A[Max]; /*使う関数をプロトタイプ宣言する*/ int inputdata(void); void merge_sort(int p, int r); void merge(int p, int q, int r); void printdata(int n); main(){ int n,k; int w=1; /*変数の宣言は実効コードより前に行う事*/ n=inputdata(); /*これは実効コード。これ以降は変数の宣言は出来ない*/ /*int w=1; 実効コードの後に変数は宣言できない*/ merge_sort(w,n); printdata(n); return(0); } int inputdata(void){ //配列に乱数を要素として入れていく int n,i; printf("n= "); scanf("%d",&n); //使用者にいくつの要素を入れるか指定してもらう srand(time(NULL)); for(i=1; i<=n; i++){ A[i]=1+rand()%30; } printf("A[%d]={%d,",n,A[1]); for(i=2;i<n;i++) printf("%d,",A[i]); printf("%d}\n",A[n]); return(n); } void merge_sort(int p, int r){ int q; if(p<r){ q=(p+r)/2; merge_sort(p,q); merge_sort(q+1,r); merge(p,q,r); } } void merge(int p, int q, int r){ int i,j,k,B[Max]; i=p; j=q+1; for(k=p;k<=r;k++){ if((j>r) || ((i<=q)&&(A[i]<=A[j]))){ B[k]=A[i]; i++; }else{ B[k]=A[j]; j++; } } for(k=p; k<=r; k++) A[k]=B[k]; } void printdata(int n){ int i; printf("A[%d]={%d,",n,A[1]); for(i=2; i<n; i++) printf("%d,",A[i]); printf("%d}\n",A[n]); } -------------------------------- ここから蛇足の蛇足。 1番目の修正ソースのように「呼ぶ前に関数本体を定義する」と言う書き方をすると、関数プロトタイプ宣言は不要な筈。 しかし「2つの関数が、お互いを相互に呼び出す」と言う場合、どうしてもどちらか1つの関数は「呼んだ後に関数本体を定義する」と言う事になる。 そういう場合は「関数プロトタイプ宣言」が必須となる。 例: int func2(int a):/*プロトタイプ宣言*/ int func1(int a){ (略) if (a > 1) return func2(a - 1); return 0; } int func2(int a){ (略) if (a > 1) return func1(a - 1); return 0; } 例を見て判る通り、func1とfunc2の関数の場所を逆にしても、やはり「呼んだ後に関数本体を定義する」のが避けられない。 なので、こういう場合には「関数プロトタイプ宣言」が欠かせない。

e085749
質問者

お礼

詳しい解説ありがとうございます。 プロトタイプ宣言でコンパイラにちゃんと教えてあげないと駄目なんですね。

その他の回答 (4)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.5

本質は既に書かれている通り「ISO C にも POSIX にも定義されていない mergesort という関数が stdlib.h で宣言されている」 (とエラーメッセージにもちゃんと書いてある) ことなので, 関数名を変えるか (可能なら) 適切なコンパイラオプションでつぶすかすることになる. 以下余談: ちと調べてみると BSD系では mergesort が定義されている>#4. ついでにいうと今の ISO C をまじめに取り入れているコンパイラなら「実効コードの後に変数は宣言できない」という制限はない>#2. なぜか知らんがいまだに ISO C に対応しようとしない (ということは事実上 C++0x にも準拠しないことになる) MS なコンパイラではそのような制限があるが, どっちかといえばこれは 「MS なコンパイラ」が腐っていると思うべき.

  • chie65535
  • ベストアンサー率43% (8514/19356)
回答No.4

追記。 >それと、運悪く、stdlib.hに「既にmergesortというのが定義されてて >名前が衝突している」ので、mergesortと言う名前の関数は使えない。 他の一般的なC、C++では「mergesortと言う関数は標準関数として定義されていない筈」で、普通は、自前でmergesortと言う関数を作っても何も問題は起きない筈。 質問者さんが使っているコンパイラには、なぜか「mergesortと言う識別子がstdlib.hに定義済み」で、標準から逸脱した変なコンパイラらしいので、使用する場合は注意が必要だと思われます。 出来れば「変なものが定義されてない、もっと標準的なコンパイラ」を使った方が良いでしょう。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

#define Max 255の次の行に、以下の行を追加して下さい。 void mergesort(int p, int r); //これを追加 void merge(int p, int q, int r); //これを追加

  • kot_o
  • ベストアンサー率16% (6/36)
回答No.1

通りすがりです。 >↓が自分の作ったマージソートのプログラムなのですが、 >コンパイルするとエラーが起きてしまいます。 >mergesort()にポインタを引数として渡してる、 >引数の数が足りない、ということが書いてありますが…。 >ちゃんとint型を渡してるし、引数の数も合ってるように思います。 >どこがおかしいのでしょう 正直、引数が違うとかの問題ではないかと思いますが。 .netでコンパイルしてみたので確認してください。 ちなみ、ソースは質問者様の書いたものをそのままコンパイルしました。 #include<stdio.h> が 1行目になります。 ============================================================== mergesort.cpp(8) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません mergesort.cpp(10) : error C3861: 'inputdata': 識別子が見つかりませんでした mergesort.cpp(12) : error C3861: 'mergesort': 識別子が見つかりませんでした mergesort.cpp(13) : error C3861: 'printdata': 識別子が見つかりませんでした mergesort.cpp(17) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません mergesort.cpp(17) : error C2365: 'inputdata' : 再定義; 以前の定義は '以前は不明な識別子' でした。 mergesort.cpp(21) : warning C4244: '引数' : 'time_t' から 'unsigned int' への変換です。データが失われる可能性があります。 mergesort.cpp(31) : error C2365: 'mergesort' : 再定義; 以前の定義は '以前は不明な識別子' でした。 mergesort.cpp(35) : error C3861: 'mergesort': 識別子が見つかりませんでした mergesort.cpp(36) : error C3861: 'mergesort': 識別子が見つかりませんでした mergesort.cpp(37) : error C3861: 'merge': 識別子が見つかりませんでした mergesort.cpp(41) : error C2365: 'merge' : 再定義; 以前の定義は '以前は不明な識別子' でした。 mergesort.cpp(54) : error C4430: 型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません mergesort.cpp(54) : error C2365: 'printdata' : 再定義; 以前の定義は '以前は不明な識別子' でした。 mergesort.cpp(59) : warning C4508: 'printdata' : 関数に戻り値の型が指定されていません。戻り値を void 型と見なします。 mergesort - エラー 13、警告 2 ========== ビルド: 0 正常終了、1 失敗、0 更新、0 スキップ ========== ご自身で確認してみてください。

関連するQ&A

  • マージソート

    マージソートの実行時間を測定するプログラムを書いています。 コンパイルの時にはエラーが出ないのですが、実行するとコマンドプロンプトが強制終了されます。 どこが悪いか、どう直せばいいのか指摘していただけないでしょうか? よろしくお願いします。 ~qtime.c~ //マージソート実行用プログラム //bcc32 mtime.c merge.c m1.c sfmt.c #include <stdio.h> #include <stdlib.h> #include <time.h> #include "sfmt.h" #define MAX 5000 void merge_sort(int a[], int start, int end); main() { int i , x[MAX] , n; time_t start , end ; int sn; printf("適当な数字の入力 : "); scanf("%d", sn); init_gen_rand(sn); for(i=0; i<MAX; i++) x[i]= (gen_rand32()% MAX);; n=MAX; start = clock(); //測定対象プログラム merge_sort(x, 0, n-1); end = clock(); printf("sort\n"); for(i =0 ; i < n ; i++ ) if ( i == i/100*100) printf("%d\n" , x[i]); printf ("実行時間: %f sec\n" , (double)(end-start) /CLOCKS_PER_SEC); return 0; } ~merge.c~ int b[100]; void merge_array(int x[], int start, int end) { int mid, i, j, k; mid = (start + end) /2; i = start; j = mid + 1; for(k = start; k <= end; k++){ if(x[i] > x[j] && j <= end || i > mid){ b[k] = x[j]; j++; } else{ b[k] = x[i]; i++; } } for(k = start; k <= end; k++){ x[k] = b[k]; } } ~m1.c~ void merge_array(int x[], int start, int end); void merge_sort(int a[], int start, int end); void merge_sort(int a[], int start, int end) { int mid; if(start >= end) return; mid = (start + end) / 2; merge_sort(a, start, mid); merge_sort(a, mid + 1, end); merge_array(a, start, end); }

  • マージソートについて。

    マージソートについて勉強しており、プログラムを作ってみたのですが どうしてもcc=~~の箇所の数値がおかしく表示されてしまいます #include<stdio.h> int main(void) { int a[5]={20,40,15,35,50}; int b[3]={55,20,65}; int c[8]; int i,z,k; printf("a="); for(i=0;i<5;i++) { printf("%d ",a[i]); } printf("\nb="); for(z=0;z<3;z++) { printf("%d ",b[z]); } while(i <= 5 && z <= 3){ if(i < z){ a[i]=c[k]; i++; } else if(i > z){ b[z]=c[k]; z++; } } while(i<5 && z<3) { i=k; i++; z=k; z++; } printf("\nc=") ; for(k=0;k<8;k++) { printf("%d ",c[k]); } return 0; } ご教授していただければ幸いです。

  • シェルソートのプログラムが分かりません

    教科書どおり下のようなプログラムを作ったのですが、ちゃんとソートされません。 打ち間違いなどを探しているのですが見つからないんです・・・ それと、プログラム11行目のj=j-hが何のためにあるのか分かりません。もしかしたら幼稚な質問かもしれませんがどうかよろしくお願いします。 #include<stdio.h> void shell(int n,int a[]) { int i,j,x,h; h=n/2; while(h<0) { for(i=h;i<=n;i++) { x=a[i]; for(j=i-h;j>=0;j=j-h) { if(a[j]>x) { a[j]=a[j+h]; a[j+h]=x; } } } h=h/2; } } main() { int a[]={30,20,60,29,10,90}; int n=6; int i; shell(n,a); for(i=0;i<n;i++) { printf("%4d",a[i]); } printf("\n"); }

  • 行列をべき乗させるプログラム

    2行2列を5乗させるプログラムを作って、一応できたつもりだったんですが結果が合いません・・・ 何かヒントでもいいのでわかる方いらっしゃいましたらよろしくお願いします。 <プログラム> #include <stdio.h> #define N 2 int A[N][N]; int A_NEW[N][N]; int A_5[N][N]; /* 行列Aを5乗したもの */ int main() { int i,j,k,l; /* 2行2列の係数行列Aの成分を入力 */ printf("係数行列Aを%d行%d列で入力してください\n", N, N); for( i=0; i<N; i++) { for( j=0; j<N; j++) { printf("A[%d][%d]=", i+1, j+1); scanf("%d", &A[i][j]); } } for(i=0; i<N; i++) /* A_NEW=A*Aの計算 */ { for(j=0; j<N; j++) { for(k=0; k<N; k++) { A_NEW[i][j] += A[i][k] * A[k][j]; } } } for(l=0; l<3; l++) { for(i=0; i<N; i++) /* A_5の計算 */ { for(j=0; j<N; j++) { for(k=0; k<N; k++) { A_5[i][j] += A_NEW[i][k] * A[k][j]; } } } for(i=0; i<N; i++) { for(j=0; j<N; j++) { A_NEW[i][j] = A_5[i][j]; } } } printf("A_5=\n"); /* 出力 */ for( i=0; i<N; i++) { for( j=0; j<N; j++) { printf("%d ", A_5[i][j]); } printf("\n"); } } <入力例> A= 1 3 2 1 <期待する結果> A= 241 303 202 241 <このプログラムの結果> 406 498 332 406

  • CからVB

    以下のプログラムはC言語で作成されています。 これをVBで作成したいです。 教えてください。 #include <stdio.h> #include <stdlib.h> double *alloc(int r,int n,int m); void input(double *p,int r,int n,int m); void sumup(double *p,int r,int n,int m); int main(void){ int r, n, m; double *p; // 行列サイズ入力 printf("input r n m "); scanf("%d %d %d",&r,&n,&m); // 行列領域取得 p = alloc(r,n,m); // 行列要素入力 input(p,r,n,m); // 行列の和 sumup(p,r,n,m); //終了,行列領域解放 free(p); return 0; } double *alloc(int r,int n,int m){ double *p; printf("MATRIX[r=%d][n=%d][m=%d]\n\n",r,n,m); p = (double*)malloc(sizeof(double)*r*n*m); if( p == NULL){ printf("error! malloc failed.\n"); exit(-1); } return p; } void input(double *p,int r, int n,int m) { int i,j,k; for(i = 0; i < r; i++){ for(j = 0;j < n; j++){ for(k = 0; k < m; k++){ printf("input MATRIX[%d][%d][%d]= ",i,j,k); scanf("%lf",&p[i*(n*m)+j*m+k]); } } } printf("\n"); } // 行列の和 void sumup(double *p,int r,int n,int m){ int i, j, k; // 0.0, not 0!!! double sum = 0.0; printf("sum of %d matrices:\n",r); for(j = 0; j< n; j++){ for(k = 0;k < m; k++){ sum=0; for(i = 0;i < r;i++){ sum += p[i*(n*m)+j*m+k]; } printf("\n%2f",sum); } } printf("\n"); }

  • Gaussの消去法のプログラムなんですがこれを利用して、消去法による行

    Gaussの消去法のプログラムなんですがこれを利用して、消去法による行列式の計算プログラムをつくりたいのですが難しくてよくわかりません。。。 教えていただきたいです。 困ってるのでよろしくお願いします。 int gauss(double *x, double *a, double *b, int n) { int i,j,k,m; double tmp,p,sum; for(k=0; k<n-1;k++){ printf("---- Step %d ----\n",k+1); printf("-- before --\n"); for( m = k;m < n;m++){ printf("%lf\n",a[n * m + k]); } printf("-- --\n"); j = pivot(a,n,k); if(j == ERROR) { return ERROR; } else { if(j != k) { for(i=0; i<n; i++){ tmp = a[n*k+i]; a[n*k+i] = a[n*j+i]; a[n*j+i] = tmp; } tmp=b[j]; b[j]=b[k]; b[k]=tmp; } } printf("-- after --\n"); for( m = k;m < n;m++){ printf("%lf \n",a[n * m + k]); } for(i=k+1; i<n; i++){ p=a[n*i+k]/a[n*k+k]; for(j=0; j<n; j++){ a[n*i+j]=a[n*i+j]-p*a[n*k+j]; printf("a[%d %d]=%lf",i,j,a[n*i+j]); } b[i]=b[i]-p*b[k]; printf("b[%d]=%lf\n",i,b[i]); } printf("k=%d\n",k); /*--------------------------------------------------------------------------*/ } /* step 2: 後退代入 */ for(k=n-1; k>=0; k--){ if(fabs(a[n*k+k]) < EPS){ return(ERROR); } sum=0.0; for(j=k+1; j<n; j++){ sum+=a[n*k+j]*x[j]; } x[k]=(b[k] - sum)/a[k*n+k]; } return 0; } int pivot(double *a, int n, int k) { int i,m; double d; /* ピボットの探索 */ m = k; d = fabs(a[k*n+k]); for(i=k+1; i<n; i++){ if(fabs(a[n*i+k]) > d){ m = i; d = fabs(a[n*i+k]); } } if(fabs(d) < EPS) { return ERROR; } else { return m; } }

  • ガウスの消去法のプログラムについて

    ガウスの消去法のプログラムについて #include <stdio.h> #define N 3 void main(void) { static double a[N][N+1]={{3.0, 1.0, 1.0, 8.0}, {6.0, 2.0, 3.0, 4.0}, {9.0, 4.0, 5.0, 12.0}}; double d; int i,j,k; for (k=0;k<N-1;k++){ for (i=k+1;i<N;i++){ d=a[i][k]/a[k][k]; for (j=k+1;j<=N;j++) a[i][j]=a[i][j]-a[k][j]*d; } } for (i=N-1;i>=0;i++){ d=a[i][N]; for (j=i+1;j<N;j++){ d=d-a[i][j]*a[j][N]; a[i][N]=d/a[i][i]; } } for (k=0;k<N;k++){ printf("x%d=%f\n",k+1,a[k][N]); } } というプログラムを実行したら 8-5.c: In function `main': 8-5.c:4: warning: return type of `main' is not `int' と出たのですがどこを直せばよいのでしょうか?><

  • クイックソートのプログラムを実行するとエラーが出る

    プログラミング初心者のものです。 ソースのファイル名はquicksortという名前にして、コンパイル&実行すると、 「Quicksortが原因でQUICKSORT.EXEにエラーが発生しました。Quicksortは終了します。問題が解決しない場合は、コンピュータを再起動してください。」 と、 「Quicksortが原因でKERNEL32.DLLにエラーが発生しました。Quicksortは終了します。問題が解決しない場合は、コンピュータを再起動してください。」 と言うエラーが出てきて最後まで実行されません。 どうしてでしょうか?ちなみにソースは以下のものです。 #include<stdio.h> #define N 10 void quicksort(int a[],int first,int last) { int i,j,p,w,k; k=(first+last)/2; p=a[k]; i=first; j=last; while(i<=j){ while(a[i]<p){ i++; } while(a[j]>p){ j--; } w=a[i]; a[i]=a[j]; a[j]=w; i++; j--; } if(first>j){ quicksort(a,first,j); } if(last>i){ quicksort(a,i,last); } } main() { int a[]={18,97,59,72,5,38,11,43,67,26}; int i; printf("Before:"); for(i=0;i<N;i++){ printf("%4d",a[i]); } printf("\n"); quicksort(a,0,N-1); printf("After:"); for(i=0;i<N;i++){ printf("%4d",a[i]); } printf("\n"); return(0); }

  • ソートプログラム

    ファイルから10個の整数が 29 45 11 2 86 91 33 62 77 59 のように一行に1個の形式で格納されている。このファイルから10個の整数を読み込み、選択法でソートし、この数字を小さい順に表示するプログラムを作成したのですが、ソート部分がうまくできません。どなたかどうすれば改善できるか教えてください。 <プログラム> #include<stdio.h> #include<stdlib.h> #define MAXN 100 int A[MAXN]; main() { _inputdata(); _selectionsort(1,10); _printdata(); } selectionsort(p,q) ___int p, q; { _int i, j, cmin, temp; _for(j = p; j <= q; j++){ __cmin = j; /* A[cmin]が現在の最小値 */ __for(i = j+1; i <= q; i++) ___if(A[cmin] > A[i]) cmin = i; __/* A[j]とA[cmin]との入れ換え操作 */ __swap(j, cmin); _} } swap(int x, int y) { _int temp; _temp = x; _x = y; _y = temp; } inputdata() { _FILE *fp; _if((fp=fopen("integers10.dat", "r"))==NULL) { __printf("ファイルが見つかりません: integers10.dat\n"); __exit(EXIT_FAILURE); _} _printf("データを入力\n"); _while(fscanf(fp, "%s", A)!=EOF) { ____printf("%s\n",A); _} _fclose(fp); } <コンパイル→実行> % gcc -o sort1 sort1.c % ./sort1 データを入力 29 45 11 2 86 91 33 62 77 59 ソート済みデータ 0 0 0 0 0 0 0 0 0 0 %

  • C言語のソートプログラム

    学校でプログラミングの課題が出たので自分のパソコンに Microsoft Visual C++ 2010 Express をインストールして作ってみました。 それが以下のプログラムです。 これは任意の値nを入力してa[n]までの配列をつくり それを降順に並び替えるものです。 #include <stdio.h> #define N 10000 int main(){ int a[N],i,j,max,min,n,temp; n=0; printf("n="); scanf("%d",&n); if(N<n){ return 0; } else if(n<=0){ return 0; } else if(n<=N){ for(i=0;i<n;i++){ printf("a[%d]",i); scanf("%d",&a[i]); } max=min=a[0]; for(i=1;i<n;i++){ if(max<a[i]){ max=a[i]; } else if(min>a[i]){ min=a[i]; } } printf("a[i]のソート結果\n"); for(i=0;i<n;i++);{ for(j=i+1;j<n;j++){ if(a[i]<a[j]){ temp=a[i]; a[i]=a[j]; a[j]=temp; } } } for(i=0;i<n;i++){ printf("a[%2d]=%d\n",i,a[i]); } printf("Max=%d\n",max); printf("Min=%d\n",min); } } これを実行すると 最初に入力した配列の順番のまま表示されてしまいます。 例えば n=4 a[0]7 a[1]4 a[2]6 a[3]1 a[i]のソート結果 a[0]7 a[1]4 a[2]6 a[3]1 のようにです。 しかしプログラミング上では for(i=0;i<n;i++);{ for(j=i+1;j<n;j++){ if(a[i]<a[j]       temp=a[i];       a[i]=a[j];            a[j]=temp;        }        }        } のようにiとjを比較して a[0]がa[1]より大きければa[0]とa[1]を交換する。 あとはa[0]とa[2], a[0]とa[3]...a[3]とa[4]まで for文の続く限り繰り返すように書いたはずです。 まだ勉強し始めた私にはどこが間違っているのか分からないので 分かる方はご指摘をお願いします。

専門家に質問してみよう