- - 関数の引数は値渡し
- C/C++言語では,関数の引数は値渡し方式になっている.
- 例えば,int型変数xに10という値が格納されているとき,関数の引数として変数xを指定した場合は,呼び出した関数へは変数xが渡されるのではなく,変数xの値10が渡される.
- よって,指定した変数の内容は,呼び出した関数内で変更することができない
- 他の言語(BASIC言語など)では,関数の引数が参照渡し方式になっているものがある.
- CやC++言語で,引数で渡した変数の内容を,呼び出した関数内で変更したい場合は,引数として,その辺数のアドレス値を渡すようにする.そして,呼び出される関数では,そのアドレス値を,ポインタ変数で受け取るようにする.
-
- プログラム例
void func ( int * p ) ;
{
*p += 10 ;
}
int main ( )
{
int x = 5 ;
func ( &x ) ;
printf ( "x= %d\n ", x );
}
|
- C++言語では,引数を「参照渡し方式」とすることも可能.
- 「参照渡し方式」だと,引数で渡した変数の内容を,呼び出した関数内で変更することが可能となる.
-
- プログラム例
void func ( int & x ) ;
{
x += 10 ;
}
int main ( )
{
int x = 5 ;
func ( x ) ;
printf ( "x= %d\n ", x );
}
|
|
- 関数に配列を渡す場合
- このときの関数のプロトタイプ宣言は
戻り値のデータ型 関数名(データ型 配列名[]); |
- のように記述する.[ ] の中に配列のよう素数を記述する必要はない.
- 関数に配列を渡すときは,
- のように配列名だけを記述する.また,配列を受け取る関数側はのように記述すると,その変数のアドレスを取得することができる.
- のように[]が必要となる.
- また,関数は受け取った配列の要素数を調べることができない.
- したがって,関数内で配列要素を参照する場合,以下のようにする.
-
- プログラム例
#include <stdio.h>
#define NUM 5 /* 要素数 */
/* 関数のプロトタイプ宣言 */
int dispArray(int dat[]);
/* main関数 */
int main(void)
{
int a[NUM]={1,2,3,4,5};
/* 関数呼び出し */
dispArray(a);
return 0;
}
/* dispArray関数 */
int dispArray(int dat[])
{
int i;
for(i=0;i<NUM;i++)
{
printf("dat[%d] %d\n",i,dat[i]);
}
return 0;
}
|
- 関数に渡されているのは,配列の先頭アドレスである.よって,配列aの先頭アドレスが,関数に渡され,関数側で使う配列datの先頭アドレスにしている.なので,配列aと配列datは,メモリ上で同じ領域を参照している.
- 引数の引き渡しには,値渡しと参照渡しがある.C言語では,特別なことをしない限り,変数は値渡し,配列は参照渡しになる
- 値渡し
- 関数に変数を渡したときは,その変数のコピーが渡される.関数が受け取った引数は,メモリ上の別の領域を使う.そのため,引数の値を更新しても,もとも関数には影響しない.
- 参照渡し
- 配列の場合は,先頭アドレスが関数に渡される.呼び出し元と受け取った側とで別の名前を使っていても,メモリ上の同じ領域を参照している.そのため関数で配列の内容を変更すると,呼び出し元の値も更新される.
|
- - 配列を渡す方法
- 関数には配列の先頭アドレスが渡される.受け取った側の関数では,要素数を知ることができない.そのため,要素数を別の変数で渡すなどの工夫が必要となる.
その1:要素数を別に渡す
サンプルコード
int dat[]={60,72,85,93,42,33};
int n;
n=sizeof(dat)/sizeof(int);
ans=average(dat,n);
float average(int dat[],int n)
{
int i;
int total=0;
float ans;
for(i=0;i<n;i++)
{
total=total+dat[i];
}
ans=(float)total/(float)n;
return ans;
} |
その2:ありえない値を配列の終端にする
サンプルコード
int dat[]={60,72,85,93,42,33,-999};
ans=average(dat);
float average(int dat[])
{
int i=0;
int total=0;
float ans;
while(dat[i]!=-999)
{
total=total+dat[i];
i=i+1;
}
ans=(float)total/(float)i;
return ans;
} |
|
- - 二次元配列の受け渡し
- 一次元配列同様,関数には
- という書式で渡す.
このとき関数に渡されるのは,二次元配列の先頭アドレスである.ただし,先頭アドレスを受け取った関数側では,その配列の構造を正しく定義しなければならない.
-
- サンプルコード
#include <stdio.h>
int dispData(int dat[][10]);
int main(void)
{
int a[2][10]={{1,2,3,4,5,6,7,8,9,10},
{11,12,13,14,15,16,17,18,19,20}
};
dispData(a);
return 0;
}
int dispData(int dat[][10])
{
int i;
int j;
for(i=0;i<2;i++)
{
for(j=0;j<10;j++)
{
printf("%2d ",dat[i][j]);
}
printf("\n");
}
return 0;
}
|
このように受け取った関数側で列数を定義する必要がある.
戻り値のデータ型 関数名(データ型 配列名[][列数]);
|
|
|
|
|
|