• ベストアンサー

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

こんにちは.私は,大学でアプリケーションソフトをつくる作業を研究の一環としてやっています.C言語でコードを書いているのですが,計算処理の高速化を 実現したいと切に願っております. 例えば,以下のように2つの関数main とTest,があるとします. そのとき,Testは計算結果を返さないとします. #define MAX 100 void Test(i,j data); int main(void) { double data[MAX][3] for (i = 0; i <= MAX; i++ ){ for (j = 0; j <= MAX; j++){ // Test(i,j data); } } return 0; } この場合,毎回Test関数を呼ぶたびにdata配列を指すポインタを 渡し,さらにTest()関数内に定義されているローカル変数用のメモリ領域も 確保されます. ということは,処理を高速化するためには なるべくTest関数内の変数を できるだけへらせばいいのでしょうか? みなさんがプログラムを組むときに留意されているテクニックを 教えて頂きたいです. できればVC++ver6.0でのデバックツールをどのように つかってバグフィクスしておられるのかうかがいたいです. 以上、よろしく御願い致します.

noname#700
noname#700

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

  • ベストアンサー
  • terra5
  • ベストアンサー率34% (574/1662)
回答No.5

>この適材適所ともいうべき能力を身につけるには, >やはり「経験」でしょうか? アルゴリズム的なところは、計算量の問題ですから、 きちんと理詰めでいけば計算できるとは思いますし、 知識でもカバーできるとは思いますが。 何度もやっていれば、いちいち調べないでも すぐに頭に浮かぶのが経験ですしょうか。 >大きいサイズの場合,グローバル変数として確保した方がよい >ときいたことがあるのですが,これもなんともいえませんか? 言えないと思います。 おそらくスタック上に取られるauto変数だと、スタックサイズの制限により、 あまりに大きなエリアは取れれない可能性はありますが。 その場合でも、メモリをグローバルにするか、malloc()を使うか、また、場合によっては共有メモリを使うかとか、 場合によると思います。 もっとも、高速化より目的にあった・・の意味合いが強いとは思います。 >実際,関数を呼ぶときには,その呼ばれた関数内の変数も呼ばれる, >すなわち,スタックの繰り返しですよね? >ということは,あまり大きいサイズをつまないようにした方が >いいと知識がない私は考えてしまうのですが… 初期化が必要がない変数なら,まとめて取れますから、 速度的には数は影響しないでしょう。 また、popも関数の戻りにスタックポインタを復元すれば いいだけですから、通常は一命令でしょう。 たとえば、 f() { int a,b,c,d,e; ... } g() { int a; ... } では、手間は同一です。 って、実際はコンパイラ、CPUによるんでしょうが。 関数呼び出しの場合だと,手間がかかるのは 呼び出す前のレジスタの保存の方でしょう。 これはある程度,コンパイラの生成するコードと、 それを実行するCPUのアセンブラレベルの知識か、 それを調べることが必要でしょう。 ですが、やはりあまりすすめられないですね。 通常、それ以前の一般的な部分,アルゴリズムでの 高速化に及ばないですし。 処理の高速化は通常はアルゴリズムの改良です。 もし、処理にAPIやシステムコールが使われるなら, 重いAPIは極力使わないとかの工夫も含みます。 ところで、ダイアログの応答5秒とありますが、 本当に時間がかかる処理なら通常はマルチプロセスやマルチスレッドにすると思いますが。 ところで、配列をポインタにすることで高速化するという 話が出てますが, その程度のことは割と以前からコンパイラの最適化ではやっていると聞いてます。 最適化のレベルにもよると思いますが、Cコンパイラの最適化としてはかなり初歩的な部分でしょう。

noname#700
質問者

お礼

terra5 様,度重なるアドバイスありがとうございます. >その場合でも、メモリをグローバルにするか、malloc()を使うか、また、場合に >よっては共有メモリを使うかとか、 >場合によると思います。 >もっとも、高速化より目的にあった・・の意味合いが強いとは思います。 上記の意味は,リスト構造のような可変のデータをとりあつかうときは, malloc()を使うといったところでしょうか? しかし,「目的」に応じて,メモリーをグローバルにとる,または, 共有メモリにするといったアプローチは,私にとってちょっと 難しいところです.一例を指し示して頂けると分かりやすいのですが… >通常、それ以前の一般的な部分,アルゴリズムでの >高速化に及ばないですし。 >処理の高速化は通常はアルゴリズムの改良です。 アルゴリズムの改良ですか…うーーん,がんばって改良してみます. といっても,ここの関数の処理ルーチンについて再検討から始めたいと思います. >ところで、配列をポインタにすることで高速化するという >話が出てますが, >その程度のことは割と以前からコンパイラの最適化では >やっていると聞いてます。 >最適化のレベルにもよると思いますが、 >Cコンパイラの最適化としてはかなり初歩 >的な部分でしょう。 このようなコンパイラに関する知識も乏しいので,勉強ですね. terra5様はじめ,さまざまな方から意見を賜り,息詰まっていたキモチに モチベーションが戻りました.ここで改めてお礼を述べたいと思います. 有り難う御座いました.なにかまた不明瞭な点があったらこの掲示板を 利用させて頂くのでそのときは,どうか宜しく御願い致します. では.

その他の回答 (4)

  • 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] が同じデータを示すということから類推して下さい。 **************************************************************** わかりました.ポインタ重要なのでこの際きちんとまなび直します. 御手数をお掛けしますが,御叱咤でもかまいません,アドバイスを よろしく御願い致します.

  • papataku
  • ベストアンサー率18% (11/58)
回答No.3

高速化するには、まず今やりたい処理を再検討することです。 現在:データ個数分ループ->関数で1データ処理 ここで問題なのは、1データ処理単位ずつで関数呼び出しが存在することです。関数呼び出しのオーバーヘッドがありますので、高速化のためには、「複数データ高速一括処理」ルーチンの作成の必要があります(引数は、配列のポインタ?)。さらにデータを配列から持ってくる場合にabc[i]のような引っぱり方をすると遅くなる(iからデータ列の存在するアドレス計算を内部的にやっている為)ので最初からポインタ計算型でコーディングするといいでしょう(ranxさんの(2)のようなかんじ)。 <さらに> 本当に限りなく高速化したいのなら、VCでアセンブラ表示に変更してC->アセンブラ(マシン語)へどう落ちるかのチェックが必要です。CPUのマニュアルには、そのマシン語がどのくらいの時間で実行されるか記述してあるので、これから逆算できます。

noname#700
質問者

補足

papataku 様,お返事ありがとうございます. >関数呼び出しのオーバーヘッドがありますので、 >高速化のためには、「複数データ高速一括処理」ルーチンの作成の必要があります 関数呼び出しのオーバーヘッドとは具体的には,PC内部でどのようなことが 起きるのでしょうか? 上記のように,i,jのfor文内があればTest()関数は,メモリ上では,pushするpopを繰り返すことで 呼ばれ,処理の遅延を招くのでしょうか?? また,「複数データ高速一括処理」というのをもう少し具体的に例を挙げて御教示して頂けませんでしょうか? >(引数は、配列のポインタ?)。 はい,そうです. 2次元配列 data[MAX][3] の先頭アドレスを指すポインタをTest関数に渡しています. >さらにデータを配列から持ってくる場合にabc[i]のような引っぱり方をすると遅くなる(iからデータ列の存在するアドレス計算を内部的>にやっている為)ので最初からポインタ計算型でコーディングするといいでしょう(ranxさんの(2)のようなかんじ)。 うーーん,ここがちょっと私の技量では,分からなくて頭をひねってしまうところなのです. もう少し勉強してみます. >本当に限りなく高速化したいのなら、VCでアセンブラ表示に変更して C->アセンブラ(マシン語)へどう落ちるかのチェックが必要です. papatakuさんがおっしゃるアセンブリ表示とは, VCでデバックツールをメニューから選択すると表示される16進数表示のメモリダンプですか? >CPUのマニュアルには、そのマシン語がどのくらいの時間で実行されるか記述してあるので、これから逆算できます。 できれば逆算の仕方がのっているURLを教えて頂きたいのですが… 長々と,書いてすみません.また,こんなタコ(タコよりひどいかも…)に 適切なしかも丁寧な解説ありがとうございます. まだわからない消化しきれていない箇所が多々ありますので どうか宜しく御願い致します.

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.2

ケースによりますが、小手先の高速化は 不要と思います。 最近のコンパイラの最適化はかなり優秀らしいのと、 CPUの速度の速いこともあって、下手な細工は プログラムの可読性の低下を招くだけですし、 最適化のさまたげになるようなコーディングなら、 却って悪化します。 まずVC++6.0を使うような環境なら、そのレベルの 心配はまず不要でしょう。 >ということは,処理を高速化するためには >なるべくTest関数内の変数を >できるだけへらせばいいのでしょうか? 一概には言えません。 例えば、ローカル変数はまとめて確保しますから、 手間としてはよほど大きいサイズをとらないと 変化しません。 逆に、変数が局所的であるほど最適化が有効に 働きますから、変数の使い方によっては かえって高速の場合もあります。 高速化はまず適切なアルゴリズムとデータ構造です。 これが悪いとその程度のことは無意味です。 バグを無くすにはまず読みやすいプログラミングです。

noname#700
質問者

お礼

terra5様,お返事ありがとうございます. >一概には言えません。 >例えば、ローカル変数はまとめて確保しますから、 >手間としてはよほど大きいサイズをとらないと >変化しません。 >逆に、変数が局所的であるほど最適化が有効に >働きますから、変数の使い方によっては >かえって高速の場合もあります。 この適材適所ともいうべき能力を身につけるには, やはり「経験」でしょうか? >高速化はまず適切なアルゴリズムとデータ構造です。 >これが悪いとその程度のことは無意味です。 大きいサイズの場合,グローバル変数として確保した方がよい ときいたことがあるのですが,これもなんともいえませんか? 実際,関数を呼ぶときには,その呼ばれた関数内の変数も呼ばれる, すなわち,スタックの繰り返しですよね? ということは,あまり大きいサイズをつまないようにした方が いいと知識がない私は考えてしまうのですが… >バグを無くすにはまず読みやすいプログラミングです。 うーーん,↑非常に大切ですよね. それと,最低限のコメント文の併記ですよね.ついつい忘れがちです. なにかと丁重なアドバイスを頂きありがとうございました. 今後とも宜しく御願い致します. では.

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

ケースバイケースで何とも言えないと思いますけどね。 (高速化より構造化・プログラム見易さが重要な場合もあるし。) とりあえず、お尋ねのプログラムについて言えば、 (1) Test()をマクロ化する。   関数呼び出しのオーバーヘッドを減らせます。ただし、Test()の内容によっては  できない場合もあるでしょうし、コーディングに気をつけないとバグの元になる  場合もあります。 (2) i,j のいずれかがdata配列の引数として使われるのなら、   double (*pdata)[3], (*plast)[3];   のような変数を作って   for(pdata=data[0],plast=pdata+MAX;pdata<=plast;pdata++){    for (j=0;j<=MAX;j++){    Test(pdata, j);    }   }   のようにする。 いずれにしても、Test()内の処理で時間を食っているなら、そちらの高速化の方が 重要になりますね。

noname#700
質問者

お礼

さっそくのアドバイスありがとうございます. >高速化より構造化・プログラム見易さが重要な場合もあるし そうですね,コーディングが見やすいとの指摘も最もですね. double (*pdata)[3], (*plast)[3]; ところで↑は,double型の配列のポインタ配列ですか!??? 記述して頂いたコードを見る限り私が書いたコードは 2次元を扱っていますが,ranx様の場合,data[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言語】関数へのポインタ渡し

    配列中の最大値を発見するプログラムとして, 下記のようなプロブラムが参考書にのっていましたが,よくわからない箇所があり,質問させてください。 findMaxという関数に渡されているのは,aryの先頭アドレスだと思いますが, findMax関数内では,pary[]を引数としていますが,これはどういう意味なのでしょうか? 実際にどのような処理が行われているのかよくわかりません。 ポインタ変数? でもそのあとにはpary[0],pary[1]として使っているしよくわかりません。 教えていただけると嬉しいです。宜しくお願いいたします。 最近Cを学び始めましたが,ポインタがまだなれません…。 ============================ #include <stdio.h> #define DATA_SIZE (12) int ary[] = {5,7,10,1,25,15,30,10,31,13,22,32}; int findMax(int *, int); int main(void) { int max; int i; max = findMax(ary,DATA_SIZE); printf("Maximum number is %d\n",max); return(0); } int findMax(int pary[],int size){     int max;       int i; max = pary[0]; for(i = 0; i < size; i++){ if(pary[i] > max){ max = pary[i]; } } return(max); }