• ベストアンサー

プログラミングテクニックについて(C言語).

ranxの回答

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.4

terra5さんが百点満点の回答をして下さったので、後は蛇足と知りつつ、付け加えさせていただきます。 大学の研究の一環ということですので、長時間かけて解を出すようなプログラムもあるのでしょうね。 例えば60分で答を出すプログラムがあったとします。データをスタックに置くかヒープに置くか、 配列のアドレス計算や関数呼び出しのオーバーヘッドをどうやって減らすか、といったようなことを 一所懸命に考えてプログラムを修正したとします。そうした高速化では、55分くらいで処理が終わる ようにできれば、ある意味で大成功だと思うのです。が、aki2001さんはそれで満足できますか? それよりも、もっと根本的に処理を見直すことです。例えば、ご質問のプログラムではMAX×MAX=10000回 Test関数が呼び出されています。もし、ある条件の時にはTest関数を呼ぶ必要は無いということを見つけ られれば、処理時間はぐっと短縮できる可能性があります。 例えば、jがiより大きい場合だけで良かったんだということになれば、  for(i=0;i<=MAX;i++){   for(j=0;j<=MAX;j++){   if(i<j){   Test(i.j,data);   }   }  } で良いわけです。Test関数の呼び出しは半分近くに減ります。  for(i=0;i<MAX;i++){   for(j=i+1;j<=MAX;j++){   Test(i,j,data)   }  } とすれば、もう少し速くなります。 terra5さんの「適切なアルゴリズム」の一つの例と考えて頂いて良いと思います。 (もちろん、適切かどうかは実際の状況によります。) あと、前の回答で余計なことを書いてしまったかなと反省しているのですが、 double (*pdata)[3]; はdouble三つの要素から成る配列へのポインタです。 あとは int *p; とした場合に *p と p[0] が同じデータを示すということから類推して下さい。 くれぐれも見ずらいコーディングにならないように。

noname#700
質問者

補足

ranx様,ご返事ありがとうございます. >aki2001さんはそれで満足できますか? すみません,やはり処理の高速化にこだわりたいです. 人間はダイアログのOKなどを押して5秒以上たつと おそいと感じるようなのです. 実際自分のアプリはintractiveなスピードではないです(泣). 私の研究は処理の高速化に大きく関わっています. ある人にいわせると「クソプログラム」といわれます. 従って,どうしてもそのスタック、ヒープの効率的な使用法、 または、関数のオーバーヘッド等について御教示して頂きたいのです. もちろん自分でも勉強しますが,ネットサーフィンなどで 情報の取捨選択に時間を費やすよりも できればranx氏が参考にしている適切なURL等を 教えて頂ければと思っているのですが…. 「楽してるんじゃないか!」といわれそうですけれど… **************************************************************** Test関数が呼び出されています。もし、ある条件の時にはTest関数を呼ぶ必要は無いということを見つけ られれば、処理時間はぐっと短縮できる可能性があります。 例えば、jがiより大きい場合だけで良かったんだということになれば、  for(i=0;i<=MAX;i++){   for(j=0;j<=MAX;j++){   if(i<j){   Test(i.j,data);   }   }  } で良いわけです。Test関数の呼び出しは半分近くに減ります。  for(i=0;i<MAX;i++){   for(j=i+1;j<=MAX;j++){   Test(i,j,data)   }  } とすれば、もう少し速くなります。 terra5さんの「適切なアルゴリズム」の一つの例と考えて頂いて良いと思います。 (もちろん、適切かどうかは実際の状況によります。) **************************************************************** たしかに上記考え方は,重要であると思います. アルゴリズムとデータ構造をどのように構築するかとなやんでばかりで ソースコードをかく手がとまってしまう.といった日々が私の場合多いです. また,やっと考えたデータ構造でも処理がおそくふんだりけったりです. **************************************************************** あと、前の回答で余計なことを書いてしまったかなと反省しているのですが、 double (*pdata)[3]; はdouble三つの要素から成る配列へのポインタです。 あとは int *p; とした場合に *p と p[0] が同じデータを示すということから類推して下さい。 **************************************************************** わかりました.ポインタ重要なのでこの際きちんとまなび直します. 御手数をお掛けしますが,御叱咤でもかまいません,アドバイスを よろしく御願い致します.

関連するQ&A

  • for 文における処理の改善(C言語プログラム)

    はじめまして。panicdjです。 いまCでプログラムを組んでいます。 環境はVC++ver6.0 Win32 Console Applicationです。 以下のプログラムを見てください。 #define X_MAX 10 #define Y_MAX 20 #define Z_MAX 5 int main(int argc , char ** argv) { int i, j, k; int aa[10][20][5]; for (i = 0; i < X_MAX; i ++) { for (j = 0; j < Y_MAX; j ++) { for (k = 0; k < Z_MAX; k ++) { aa[i][j][k] = 10.0; } } return 0; } 過去のスレッドでポインタ型によるアクセスを すれば、処理が高速になるとかかれていました。 自分は,for文による繰り返す処理ではなく, その「ポインタ型によるアクセス」を実装したいのです。 こんな私にアドバイスお願い致します。

  • C言語の問題について

    下のプログラムにおいて実行結果は 02134 になります。 この02134になる過程は分かるのですが、時間がかかってしまいます。 iListとiGeneをいちいち紙に書き出さなければならないのでしょうか? 法則的なものが存在するとすれば、教えてください。 #include<stdio.h> #define MAX 5 void func(int *iGene); int main(void) { int i; int iGene[MAX]={0,1,0,0,0}; func(iGene); for(i=0;i<MAX;i++) { printf("%d",iGene[i]); } return (0); } void func(int *iGene) { int i,j; int iBuff; int iList[MAX]; for(i=0;i<MAX;i++) { iList[i]=i; } for(i=0;i<MAX;i++) { iBuff=iList[iGene[i]]; for(j=iGene[i]+1;j<MAX-i;j++) { iList[j-1]=iList[j]; } iGene[i]=iBuff; } } よろしくお願いします。

  • C言語 プログラミング 行列演算

    下記のプログラムのおかしい点と解決法を教えてください。 コンパイルは通りますがうまく動きません。。 #include<stdio.h> #define MAX 500 int main(void){ int matrA[MAX][MAX],matrB[MAX][MAX],matrC[MAX][MAX],l,m,n,i,j,k; printf("lとmを入力してください:"); scanf("%d",&l); scanf("%d",&m); printf("行列Aを入力してください"); for(i=0;i<l;i++){ printf(">"); for(j=0;l<m;j++){ scanf("%d",&matrA[i][j]); } printf("\n"); } printf("nを入力してください(m = %d):",m); scanf("%d",&n); printf("行列Bを入力してください"); for(i=0;i<m;i++){ printf(">"); for(j=0;j<n;j++){ scanf("%d",&matrB[i][j]); } printf("\n"); } printf("C=\n"); for(i=0;i<l;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ matrC[i][j]+=matrA[i][k]*matrB[k][j]; } printf("%d",matrC[i][j]); } printf("\n"); } }

  • C言語のプログラムについて。

    C言語のプログラミングについて質問です。 入力されたデータの配列とデータ数を渡すと配列に格納された値を逆順にして、格納し直す関数reverse関数を書き結果を出力せよ、というものなのですが下のように書いたのですが、うまく作動しません。どこがいけないのでしょうか...?教えていただきたいです。 #include <stdio.h> void reverse(int *data[], int n); #define MAX 100 int main() { int data[MAX]; int n, i; scanf("%d", &n); if (n >= MAX) n = MAX; for (i = 0; i < n; i ++){ scanf("%d", &data[i]); } reverse(data, n); for (i = 0; i < n; i ++) { printf("%d\n", data[i]); } return 0; } void reverse(int *data[], int n) { int c, i; for (i = 0; i < n; i ++) { c = *data[i]; *data[i] = *data[n - (i + 1)]; *data[n - (i + 1)] = c; } }

  • プログラミング(C言語)についての質問です

    3つの整数の入力を受け付け、最大と最小を求める関数を作成し得られた結果を表示するプログラミングを作成したつもりなのですが、うまく作動しません。(コンパイルはできますが、結果が無茶苦茶になります。) ご教授宜しくお願いします。 それと、課題文にはポインタを使って最大値と最小値を同時に求めるようにと書いてあったのですが、それもよくわからないです。 今回初めてポインタと配列の受け渡しについて習ったのでよくわかっていない部分も多いと思うのですが、何卒宜しくお願いします。 ちなみに関数の形自体は void minmax(int data[],int *min,int *max){} で決まっています。 #include <stdio.h> void minmax(int data[],int *min,int *max){ int i; *min=*max=data[0]; printf("1st intenger:"); scanf("%d",&data[0]); printf("2st intenger:"); scanf("%d",&data[1]); printf("3st intenger:"); scanf("%d",&data[2]); for(i=1;i<3;i++){ if(*max<data[i]){ *max=data[i]; } if(*min>data[i]){ *min=data[i]; } } } int main(void){ int data[3],min,max; minmax(data,&min,&max); printf("最小値は%dで最大値は%dです",min,max); return 0; }

  • C言語をお願いします

    何が違うのか教えてください。 segmentation faultになります。 よく分からないので、プログラムを作っていただければ、助かります。 問 整数を入力し、降順並び変えてに表示。 ・入力した整数は配列に入れ、その配列を使って並び変える(入力終りの印は 1000 とする)。 ・入力する整数の個数は #define NUM 100 を使いなさい。 ・使うデータは、下記の例のように、キーボードから入力すること。 #include<stdio.h> #define NUM 100 int main(void){ int d[NUM]; int temp; int i,j,n; printf("Input scores.\n"); for(i=0; i<NUM && d[i]!=1000; i++){ scanf("%d",&d[i]); } n = i; for(i = 0; i < n; i++){ for(j = i + 1; j < n;j++){ if(d[j] > d[i]){ temp = d[i]; d[j] = d[i]; d[i] = temp; } } } printf("After sort."); for(i=0; i < n; i++){ printf("%d\n",d[i]); } return 0; } 実行例 Input scores. 60 30 45 90 100 0 1000 After sort. 100 90 60 45 30 0 よろしければ 問2 並び変えをする部分を mysort 関数にしたプログラムを作ってください。 main 関数から mysort 関数には点数の個数と sort 前の配列を渡し、並び変え結果の表示はmain 関数でお願いします。 (問題の意味が分かりません) 関数はさっぱり分かりません。 では、お願い致します。

  • C言語の実行について、

    #include <stdio.h> #define N 2 void main(void) { int i ,j ; for( i=1 ; i <= N ; ++i) { for( j=i ; j < N+2 ; ++j) { printf("j=%d\n",j); } printf("i=%d\n",i); } } を実行すると、 j=1,j=2,j=3,i=1,j=2,j=3,i=2となったんですが、 どういった順序で行われているのでしょうか? よろしくお願いします。

  • シェルソート(Cプログラミング)

    シェル・ソート 基本挿入法により、データを昇順にソートする。 というプログラムを実行したいと思ったのですが、エラーがでてしまいコンパイルできません。 書いたプログラムは以下の通りです。 #include<stdio.h> #include<math.h> #define N 100 int main (void) { int a[N],i,j,t; for (i=0;i<N;i++) a[i]=rand(); for (i=1;i<N;i++){ for (j=j-1;j>=0;j--){ if (a[j]>a[j+1]){ t=a[j]; a[j]=a[j+1]; a[j+1]=t; } else break; } } for (i=0;i<N;i++) printf("%8d",a[i]); } エラーメッセージは以下のようにでました。 警告 W8065 sample.c 10: プロトタイプ宣言のない関数 'rand' の呼び出し(関数 main ) 警告 W8070 sample.c 22: 関数は値を返すべき(関数 main ) どうすれば出来るのでしょうか、お答えよろしくお願いします。

  • Cの素人がやってしまう・・・と言われた使い方

    関数set()を作って、下にコメントアウトされているプログラム と全く同じ動作をするプログラムを完成させよ。 main内部を変更してはならない。 関数set()内では鈎括弧を使用してはならない。 という問題で、終わるときにチェックされたのですが どうもsetでの中身が素人がよくやるやつ、といわれました。 int x[MAX]とやれ?ということなのでしょうか それともやはり&(*(x+i))の部分がおかしいということでしょうか? 確かにアドレスにアドレスを聞いているような理解としか、今は言いようがないのですが そいえば前回&*を使ってる人がいるけど・・・という話を聞きました 何かご指摘あればうれしいです 以下がコードになります。 #include <stdio.h> #define MAX 10 void set(int *x); int main() { int x[MAX]; int j; set(x); printf("KEKKA\n"); for (j = 0; j < MAX; ++j) { printf("%d\n", x[j]); } return 0; } void set(int *x) { int i; for(i = 0; i < MAX; ++i){ scanf("%d",&(*(x+i))); } } /* int main() { int x[MAX]; int j; for (j = 0; j < MAX; ++j) { scanf("%d", &x[j]); } printf("KEKKA\n"); for (j = 0; j < MAX; ++j) { printf("%d\n", x[j]); } return 0; } */

  • プログラミングCの質問です

    現在10×10の市松模様を表示させるというプログラムを作成しています。 #define文、IF文、for文の使用、printfを使って■と□を表示させることが条件です。 間違っているところの指摘をお願いします。 #include <stdio.h> #define N 10 int main(void) { for( i=1 ; i<=N ; ++i ) { for( j=1 ; j<=N ; ++j ) } if( (i+j) % 2 ){ printf("■"); }else printf("□"); } printf("\n"); i++; } return 0; }