【C言語】ポインタ渡しで配列中の最大値を発見するプログラム

このQ&Aのポイント
  • C言語で配列中の最大値を発見するプログラムをポインタ渡しで実装する方法について質問です。
  • findMax関数で渡されているparyは、aryの先頭アドレスを指すポインタ変数です。
  • findMax関数内では、pary[]を引数として受け取って、配列の最大値を見つける処理を行っています。具体的には、maxにpary[0]の値を代入し、forループ内で配列を走査し、現在の要素がmaxより大きければmaxを更新します。
回答を見る
  • ベストアンサー

【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); }

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

  • ベストアンサー
回答No.2

C言語の配列の面白い性質を一つだけ。 char a[10]などあったとき、 a[1]と*(a + 1) は同じで、 *(a + 1)と*(1 + a)は同じで、 *(1 + a)と1[a]は同じです。 int findMax(int *pary,int size)でaryの先頭アドレスがparyに入っているので、 当然、*paryでary[0]の値を得られるのはわかりますよね。 *pary は *(pary + 0)と同じですから、pary[0]と同じです。 ちなみに、pary + 1の指すアドレスはparyの型によって変わります。 paryはint型変数へのポインターなので、実際のアドレスは(void*)(pary) + 1 * sizeof(int)になっています。 printf("%p\n", pary + 1)して確認してみてください。 > ポインタ変数をpary[0],pary[1],pary[2]と使った場合, > 元の配列ary[0],ary[1],ary[2]全く同じ意味になるのでしょうか? どちらも配列の同じ要素を参照しています。 なんか回し者みたいでアレですが、ポインターを理解することなくしてC言語は理解できませんから、一度「秘伝C言語問答 ポインタ編」などを読んで網羅的に理解してみてはいかがでしょうか。

taka1985a
質問者

お礼

回答ありがとうございます。 詳しく説明してくださったのでベストアンサーにさせていただきます。 >*(1 + a)と1[a]は同じです。 こちらの文の意図がわかりませんでした。 1は数字なので,変数のように扱うことはできないのでは? よくわからないことを言っていたらすいません。 オススメ本までありがとうございます。 Cの勉強はまだ一冊目の基本書をやっている所ですので, それが終わったら挑戦してみようと思います。

その他の回答 (1)

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

関数における仮引数の宣言は特殊で, 「配列」と宣言したとしても勝手に「ポインタ」と解釈されます. つまり int findMax(int *, int); という宣言と int findMax(int [], int); という宣言とは全く同じものを意味します. 同様に, 関数定義を int findMax(int pary[],int size) ではじめても int findMax(int *pary,int size) ではじめても違いはありません. 一方, 配列名を式の中で使うと (例外的な場所を除いて) 「先頭要素へのポインタ」に自動的に変換されます.

taka1985a
質問者

お礼

回答ありがとうございます。 まだわからない箇所があります,教えて頂ければ嬉しいです。 int findMax(int *pary,int size) でparyにaryの先頭アドレスを代入し, その後 max = pary[0];を実行していますが,そこがよくわかりません。 ポインタ変数をpary[0],pary[1],pary[2]と使った場合, 元の配列ary[0],ary[1],ary[2]全く同じ意味になるのでしょうか? ポインタの示す先の値を代入する場合は, max = *pary[1]のようにするのではないのでしょうか?(コンパイルは通りませんでした。)

関連するQ&A

  • 引数が配列のときの関数内でのsizeofについて

    こんにちは. Cを勉強している最中に疑問にあったことを質問させていただきます.以下のプログラムで配列myarrayの中の最大のメンバーを見つけるプログラムです.コメントアウトしてある //int ary_size = sizeof(myarray)/4; をグローバル変数で定義するとうまく最大の数を見つけてくれるのですが, 関数の中で int ary_size = sizeof(ary)/4; と定義するとうまくいきません.そこで,以下の printf("The size of the ary is %d\n",ary_size); という表示を追加したところ,ary_size = 1となっていることが分かりました. なぜそうなるのでしょう?関数の引数はint ary[]の配列なので,sizeof(ary)でaryがメモリ中で占めるバイト数が得られるんじゃないんですかね?ちなみに私の環境ではsizeof(int)は4バイトなので int ary_size = sizeof(ary)/4; と割る4で配列のメンバーの数を求めています. 初心者の質問ですみませんがよろしくお願いします. #include <stdio.h> #include <Windows.h> int myarray[] = {1,2,3,4,5,6,7,2}; int FindMax(int ary[]); //int ary_size = sizeof(myarray)/4; int main() { int max; max = FindMax(myarray); printf("The maximum value is %d\n",max); Sleep(2000); return(0); } int FindMax(int ary[]) { int ary_size = sizeof(ary)/4; int i; int max; max = ary[0]; for(i=1;i<ary_size;i++) { if(ary[i]>max) { max = ary[i]; } } printf("The size of the ary is %d\n",ary_size); return(max); }

  • C言語 ポインタ 関数

    キーボードから文字列”abcdefg”を入力し、main関数で配列aryに格納する。 main関数から配列aryの先頭アドレスを副関数に引き渡す。 副関数で配列aryの最後尾の要素の内容を';'に変更する。 main関数で配列aryの内容を表示する。 この問題が解けません... #include <stdio.h> int main (void) { char ary[]="abcdef"; int *p; int i,x; p=&ary[0]; func(&i); for (x=0;x<=7;x++){ printf("%s",ary[x]); void func (int i) if(i==\0) i=';' else i++ } return 0 } とりあえずこんな感じなんですけど、出来ませんでした...

  • ポインタによる関数への配列渡し

    林晴比古さんの「新C言語入門」でC言語を勉強している初心者です。 現在ポインタの勉強をしています。色々教科書の文例等をポインタで書くとどうなるか試しております。 上書P200練習問題2に「配列の最大値を返す(その際配列の長さを渡す)」プログラムがあり、それをポインタで渡すプログラムに直してみました。 仮引数に「maxdata」を設定し、そのアドレスを関数側に渡し、関数側ではポインタとして受け取る(そうすれば関数側からはreturnで値を返す必要がない)、と考え、下記のように書いてみました。 #include <stdio.h> void max_of_array(int n[], int len, int *ans); int main(void) { int dt[6] = {50,20,80,30,10,40}; int maxdata; max_of_array(dt,6,&maxdata); printf("最大値=%d\n", maxdata); return 0; } void max_of_array(int n[], int len, int *ans) { int i; ans = &n[0]; for (i=1; i<len; i++){ if (*ans < n[i]) *ans = n[i]; } } しかしコンパイルすると、何故か「最大値=1」となってしまいます。(正しくは80です) 他にも色々試してみましたがうまくいかず、かなり考えてみたのですがどうしても分かりません。お分かりの方、どうすれば正しくなるのが教えてください、よろしくお願いします。

  • プログラミング(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言語

    3. 整数配列data の,data[left]からdata[right-1]の最小値がある添字番号を返す関数 int min_ind_ary(const int data[ ], int left, int right) で最小値が複数あるときは,一番小さい添字を返すようにするにはどうしたらよいのかわかりません? 途中経過↓ #include <stdio.h> int min_ind_ary(const int data[10],int left,int right) { int i,min = 0; for( i = 1; i < left; i++){ if(data[min] < data[i]) min = i; } return min; } void print_ary(const int data[10], int size){ int i; for(i = 0; i < 10; i++){ printf("%2d", data[i]); } } void sort_ary (int data[10], int size) { int i; for(i = 0; i < size - 1; i ++ ) { int min, work; min = min_ind_ary(data, i, size); work = data[min]; data[min] = data[i]; data[i] = work; } return; } int main(void) { int data[10] = {1, 6, 4, 8, 2, 3, 5, 9, 7, 4}; print_ary(data, 10); sort_ary(data, 10); print_ary(data, 10); return 0; }

  • C 関数とポインタ

    ポインタと関数がよく分かりません。 (日本語がおかしくてすみません(^_^;)) たとえば↓のようなプログラムで、 #include <stdio.h> void increase(int *i); int main(void) { int x = 3; increase(&x); printf("%d\n", x); return 0; } void increase(int *i) { (*i)++; } 結果は4になりますが、increase(&x)が&xとなっていて、 関数はvoid increase(int *i)でint *iになっているのですが、 これはvoid increase(int *i)はint型の「ポインタ」なので、 increase(&x)も&xと「アドレス」を渡さなければいけないということですか?? そして、void increase(int *i)内では、アドレス&xの指す値をインクリメント、という考えで良いのでしょうか?

  • 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; } }

  • できているとは、思うのですが。ポインタの配列を

    コンパイラではちゃんと動いてます。 1 2 3 0 1 2 3 という具合です。 気になるのは、printarrayの部分が正しいのか、ちょっと悩んでいます 問題としては main関数では0の値を読み込むまで最大99(MAX-1)個の値を配列 xに読み込んでいる。引数のポインタからの値を、値が0になるまで すべて1行に1つづつ画面に出力する関数printarray()を作成し、 プログラムを完成せよ。 引数はアドレスとして受け取る事。(配列としてでなく) フォーマットは、 "%d¥n" とする。(余計な出力はしない事。) (0は出力しない。) main内部を変更してはならない。 以下がソースです。 ご指摘よろしくお願いします。 #include <stdio.h> #define MAX 5 void printarray(int *); int main() { int x[MAX], i; int *p; x[MAX-1] = 0; for (i = 0, p = x; i < MAX-1; ++i, ++p) { scanf("%d", p); if (*p == 0) { break; } } printarray(x); return 0; } void printarray(int *a) { int i,*p; for(i = 0, p = a; i < MAX-1; ++i,++p) { if(*p == 0){ // continue; break; }else{ printf("%d\n", *(a+i)); } } }

  • C言語 関数の問題

    C言語(関数の問題)で読み込んだ4つの整数の最大値を求めプログラムで 整数を2つペア比較し、関数の入れ子を用いて最大値を見つけて、表示する。 というプログラムを作成したいのですが #include<stdio.h> int maxof(int a, int b) { if(a > b) return (a); else return (b); } int max4(int a, int b, int c, int d) { max(max(a, b), max(c, d)); } int main(void) { int num1,num2, num3, num4; ------ 整数の読み込み printf("最大値は%dです。", max4(num1, num2, num3, num4)); return(0); } と記述すると、上手くいったのですが これを max関数だけを用いて作成できますでしょうか? 整数の比較は全てmax関数で行いたいです。

  • ポインタ渡しについて

    関数の引数をint型のポインタで出力し、その関数を呼び出し側で値を取得するにはどうしたらいいのでしょうか? 一応ソースを作成しました(下記参照)が、ほしい値が出てきません。 よろしくお願い致します。 ----------------------------------------------- #include <stdio.h> int check(int *num){ int n=10; num = &n; return 0; } int main() { int m_num; check(&m_num); printf("%d\n",m_num); return 0; } ----------------------------------------- m_numに、10が格納されません。 check()でアドレス渡しをしたのですが・・・。 どうすれば、main関数で、数値を扱うことが出来ますか? よろしくお願い致します。

専門家に質問してみよう