C言語の配列とポインタについて

このQ&Aのポイント
  • C言語の配列とポインタについてわからないことがあります。
  • 配列とポインタの関係について疑問があります。
  • ポインタ変数と配列の要素の関係について説明してください。
回答を見る
  • ベストアンサー

C言語の配列とポインタについて

C言語の配列とポインタについてわからないことがあります。 以下のソース例は、10個の値の平均値を求めるプログラムです。 コメントを挟んだ部分が疑問点です。 【ソース例】 #include <stdio.h> int getaverage(int *data); int main(void) { int average,array[10] = {15,78,98,15,98,85,17,35,42,15}; average = getaverage(array); printf("%d\n",average); return 0; } int getaverage(int *data) { int i,average = 0; for (i = 0;i < 10;i++) { average += data[i]; /*ポインタ変数なのに? */ } return average / 10; } 【実行例】 49 このdata[i]はポインタ変数であり、 配列arrayの i 番目の要素であるarray[i]の"アドレス" が代入されているはずだと思うのですが、 なぜ通常の整数変数であるaverageと数値計算が出来、正しい結果が出たのでしょうか? あたかもdata[i]には、 array[i]の"アドレス"ではなく、 array[i]の"メモリの中身"が代入されているようです。 どういうことでしょうか? 回答よろしくお願いします。

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

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8466/19280)
回答No.1

C言語では data[0] と *data は同じ意味です。同様に data[1] *(data + 1) data[3] *(data + 3) data[i] *(data + i) も、すべて「同じ意味」です。 なので average += *(data + i); は average += data[i]; と書く事が出来ます。

noiman_tensai
質問者

お礼

なるほど、 たとえ変数dataにはアドレスが代入されていたとしても、 data[0] と書くだけで "array[0]内の数値" として扱えるんですね。 ありがとうございます!

関連するQ&A

  • ポインタについて

    ポインタについてですが、下記のプログラムで、 data = array;  で、array[0] のアドレスを代入してますよね? for文で、all+= data[i];では、 どんな計算がおこなわれていますか? dataにarray[0]のアドレスが代入されているので、アドレスの足し算が行われているんですか?(よく解らないのですが。) 教えてください。 #include <stdio.h> int main(void) { int *data; int i, all = 0, array[10] =15,78,98,15,98,85,17,35,42,15; data = array; for (i = 0;i < 10;i++) { all+= data[i]; } printf("%d\n",all/ 10); return 0; }

  • C言語、配列とポインタとアスタリスクの関係

    ちょっと行き詰まっています。 苦しんで覚えるCで勉強しているのですが、まさに苦しんでいます。 http://9cguide.appspot.com/19-01.html #include <stdio.h> #include <stdlib.h> int main() { int i; int *heap; heap = (int *)malloc(sizeof(int) * 10); if (heap == NULL) exit(0); for (i = 0;i < 10;i++) { heap[i] = i; } printf("%d\n",heap[5]); free(heap); return 0; } int *heap; ここで int ポインタを宣言しています。 heap = (int *)malloc(sizeof(int) * 10); ここでヒープを確保しています。(int *) のキャストも sizeof(int) も理解できました。 for (i = 0;i < 10;i++) { heap[i] = i; } まず1点目の疑問はここです。 変数 heap は「ポインタ変数」です。それでいて配列です。 ポインタ変数は、プログラムの文中で通常の変数として使うときには「*heap」のように先頭にアスタリスクを付けなければならかなったと記憶しています。 アスタリスクなしの「heap」はアドレス格納用の変数ではないでしょうか。 printf("%d\n",heap[5]); そして、その疑問をよそに、この命令が成り立っているようです。 画面上に出される結果は「5」であり、変数「heap」がただの配列として機能しているように見えます。 この printf 次のように書き換えると、エラーが出てコンパイルできませんでした。 書き換え実験1 printf("%p\n",*heap[5]); アスタリスクを付けて、通常の変数として扱い、受ける方も「%d」から「%p」に書き換えてアドレスを表示してみようと思ったのですが、 「「pointer」を付け忘れています。」というエラーが表示されました。 書き換え実験2 printf("%p\n",heap[5]); 受ける方を「%d」からポインタを受ける「%p」にしましたが、変数の方はアスタリスクなしです。 すると、結果はアドレス「00000005」が返ってきました。 (変数にアスタがないのになぜ?) 書き換え実験3 printf("%d\n",*heap[5]); これはもうめちゃくちゃですが、一応やってみました。コンパイルエラーで、 「「pointer」を付け忘れています。」というエラーが表示されました。 つまり、こういうことです。 0:printf("%d\n",heap[5]); //5 1:printf("%p\n",*heap[5]); //エラー 2:printf("%p\n",heap[5]); //00000005 3:printf("%d\n",*heap[5]);//エラー この結果から推測するに、アスタリスクはそもそも付けるとエラーになり、アドレスを表すか、そのアドレスに格納された値を表すかを切り替えるには、単にその変数を受ける「%d」や「%p」を変えるだけ、ということになるのだと思います。 mallocで返ってくるのは、ポインタ変数(の配列)だと思うので、変数のモードを切り替えるためにアスタリスクが必要なのだと思っていましたが、どこかで重大な勘違いをしているようです。 この件について、どなたか教えていただけないでしょうか。

  • // c のポインタと配列について質問です。

    // c のポインタと配列について質問です。 //次のようなプログラムがあります。 /* main.c */ #include <stdio.h> int main(void) { int array[5] = { 0, 1, 2, 3, 4 }; int i; int* p = &array[0]; for( i = 0; i < 5; ++i ){ printf( "%d ", p[i] ); } puts(""); return 0; } /* これをデバッグすると、定義されていないアドレスの配列 p[i] のため、エラーになるような気がしますが、実際には 1 2 3 4 5 と出力されます。 ここで質問ですが、 p[i] とは何を指しているのですか? できればc初心者の中学生でも分かるように教えてください。 p.s. 余計な御世話かもしれませんが、これをこのままコピペすれば、デバッグできます。 */

  • C言語のポインタについて教えてください。

    C言語のポインタについて教えてください。 ・pointer1.c  int main(){   int a;   int *p;   p = &a;     a = 123;   printf("%d", *p);   return 0;  } ・pointer2.c   int main(){ int a[100]; int *p; p = &a[0]; int i; for(i = 0; i < 100; i++) a[i] = i; for(i = 0; i < 100; i++) printf("%d", *p++); return 0; } と二つのソースコードがあるとき、pointer2.cの「p = &a[0]」をpointer1.cのように「p = &a」と書けないのはなぜですか?  また、「&a」は動かすことのできなく、「aを指し示す*p」は動かすことができる変数のようなもの、という認識に誤りはないでしょうか?  宜しくお願いします。

  • C言語 初期化について

    はじめまして。 C言語を学習しております。 【初期化】の意味について混乱しております。 今まで、【初期化】とは下記のような繰り返しのある文に初期値(数え始めの値、下記の例では1)を代入することだと思っていました。 for (i = 1;i <= 10;i++) { printf("メッセージ\n"); } しかし、勉強が進むにつれ、下記のように様々な場面で【初期化】という言葉が出てきたことで、【初期化】の意味がわからなくなりました。 ●【文字変数の配列の初期化】の例 char str[6] = {'M','A','R','I','O'}; ●文字列リテラルを用いた【文字列の初期化】の例。 #include <stdio.h> int main(void) { char str[] = "MARIO"; printf("%s\n",str); return 0; } ●【配列の初期化】の説明 型名 配列名[要素数]={0番の数値,1番の数値,2番の数値,・・・}; ●【配列を初期化】して表示する例 #include <stdio.h> #include <stdio.h> int main(void) { int array[10] = {42,79,13}; printf("array[0] = %d\n",array[0]); printf("array[1] = %d\n",array[1]); printf("array[2] = %d\n",array[2]); printf("array[3] = %d\n",array[3]); printf("array[4] = %d\n",array[4]); return 0; } ●for文の説明 for (初期化;条件式;更新) { 繰り返す文; } 初期化とは、カウント変数の初期化を行うための文です。 ここに書かれた式は、最初に1回だけ実行されます。 【初期化】とは、場面場面で意味が変わるのでしょうか。 どの場面に通じる【初期化】の本来の意味を教えてください。 よろしくお願い致します。

  • C言語の配列について

    配列を20 定義し値を入力して合計値を出したいのですがどうすればよいのでしょうか 下のソースでエラーはおこりませんでした 何がちがうのでしょうか #include <stdio.h> int main() { int a[20]={}; int i, sum; printf("整数を入力してください:"); scanf("%d",&a); printf("\n"); for (i = 0; i < 10; i++) { sum += a[i]; } printf("sum= %d\n", sum); return 0; }

  • ポインタ配列

    配列をポインタでとって、配列要素を足していこうと思ったのですが、 #include <stdio.h> int main (void) { int p[11]={11,23,43,66,54,67,51,88,22,43,-1}; int *e=p; int x=0; int i=0; while( *e!=-1 ) { x + = ( * (e+i) ); i++; } printf("%d\n",x); return 0; } x = ( * ( e+i ) ); ↑この部分がなぜだめなのか理解できません どなたか教えてくださるとありがたいです

  • 変数の使い方

    お聞きしたいのですが、下記の main関数、getaverage関数の両方で 変数averageを宣言してますが、 名前は同じだが、まったく別変数と考えて良いのですか? 教えてください。 #include <stdio.h> int getaverage(int data[10]); int main(void) { int average,array[10] = {15,78,98,15,98,85,17,35,42,15}; average = getaverage(array); printf("%d\n",average); return 0; } int getaverage(int data[10]) { int i,average = 0; for (i = 0;i < 10;i++) { average += data[i]; } return average / 10; }

  • C言語 ポインタ変数について

    ポインタ変数の値とアドレスの表示の仕方がよくわからないため、教えていただけますでしょうか。 --------------------------------------------------------------------- #include <stdio.h> int main() {    char* animal[] = {"dog", "cat", "hamster", "mouse"};    int i;    for(i=0; i<4; i++) {      printf("%p animal[%d] : %s, アドレス : %p\n",      animal+i, i, animal[i], *(animal+i));    }    return 0; } --------------------------------------------------------------------- このプログラムを実行すると 0022FF40 animal[0] : dog, アドレス : 00403000 0022FF44 animal[1] : cat, アドレス : 00403004 0022FF48 animal[2] : hamster, アドレス : 00403008 0022FF4C animal[3] : mouse, アドレス : 00403010 となるのですが、なぜanimal[i]のところに配列の要素(dog, cat,・・・)が表示されるのかがわかりません。 char* animal[] = {"dog", "cat", "hamster", "mouse"};の行では、 animal[0] = "dog" なら animal[0]には"dog"の先頭アドレス(00403000)が代入されているのではないのでしょうか。

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

専門家に質問してみよう