<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関数を記述してください。