<STEP1>

配列をアドレスで渡す場合の事例を1つ取り挙げます。

 

#include <stdio.h>

void sum(int*, int);

int main(){

int list[] = {2,44,3,6,76,43,13,83,22};

sum(list, sizeof list / sizeof list[0]);

return 0;

}

void sum(int *lp, int n){

int total=0;

int i;

for(i=0; i<n; ++i){

total += *(lp+i);

}

printf("%d", total);

}

 

 

**********説明***********

 

・sizeof list / sizeof list[0]

sizeof list で配列全体のバイト数を求め、 sizeof list[0]で、配列の要素1つ分のバイト数を求めるため、

全体のバイト数÷1つ分のバイト数で「配列の要素数」を求めます。

 

・sum関数の1つ目の引数は、 list ですが、listは配列名ですので、配列の先頭のアドレスを送っています。

 

・total += *(lp+i);

iが0のときは、「*lp」です。アドレスに*が付いていますので、アドレスの先にある値を取りに行っています。

iが1のときは、「*(lp + 1)」です。次のアドレスに格納されている値を取りに行きます。

nこ分の値を取りに行って、sumに足していっているので、配列に入っている値の総合計値を求めています。

 

 

 

<STEP2>

配列の感覚を思い出してください。

list         と  &list[0]

list + 1   と  &list[1]

list + 2   と  &list[2]

list + 3   と  &list[3]

list + 4   と  &list[4]

は同じアドレスを表していることを確認しましたね。

 

 

アドレスではなく、値をみにいくには、

*(list)         と  list[0]

*(list + 1)   と  list[1]

*(list + 2)   と  list[2]

*(list + 3)   と  list[3]

*(list + 4)   と  list[4]

が、同値表現になります。

 

【演習1】

<STEP1>のsum関数を、別の書き方で表現して下さい。

 

 

 

<STEP3>

<STEP1>で、sum関数は、

void sum(int *lp, int n){

}

のように記述されていました。

ここで、配列のポインタを受け取る際は、

int *lp

ではなく、

int lp[]

として、受け取ってもいいという特例があります。(Cの文法とは逸脱している特例処置です)

 

【演習2】

上の引数の設定方法で、<STEP1>を表現してください。

 

 

このように、配列のポインタを渡す際は、仮引数の宣言をする際、

int *lp ⇔ int lp[]

のように、ポインタとして受け取る方法と、配列の特例措置の書き方の2通り

 

配列から値を取り出す際は、

*(lp + i) ⇔ int lp[i]

のように、ポインタとしてアクセスする方法と、配列のようにアクセスする方法の2通り

 

つまり、2×2=4通りの書き方ができることを確認してください。

また、4通りの書き方について、いつでも書き直せるようにしておきましょう。

 

 

 

【演習2】

それでは、<STEP1>のようにメイン関数を記述し、sum関数ではなく、配列の平均を求めるave関数を記述してください。