C言語において、引数(ひきすう)とは、関数呼出し時にその関数に渡す値と、呼び出された関数側で渡された値に名前をつけ関数内で使用できるようにしたもの、の2つのことです。前者が実引数、後者が仮引数と呼ばれます。
C言語の引数の大きな特徴として、すべての引数が値で受渡しされる、という点があります(値渡し、call by valueと呼ばれます)。これは、呼ばれた関数側で呼び元の関数の変数を変更することはできないということを意味しています。
C言語の引数について、実引数と仮引数、C言語の引数の大きな特徴である値渡し、main関数の引数について説明しています。
C言語において、引数(ひきすう)とは、関数呼出し時にその関数に渡す値と、呼び出された関数側で渡された値に名前をつけ関数内で使用できるようにしたもの、の2つのことです。前者が実引数、後者が仮引数と呼ばれます。
C言語の引数の大きな特徴として、すべての引数が値で受渡しされる、という点があります(値渡し、call by valueと呼ばれます)。これは、呼ばれた関数側で呼び元の関数の変数を変更することはできないということを意味しています。
実引数(じつひきすう、argument, actual argument)とは、関数の呼出しの際に実際に関数に渡す値(式)のことです。呼出し関数の括弧で括られた中にカンマで区切られて書かれます。また、関数マクロの呼出しにおいて渡される値も実引数と呼ばれます。
仮引数(かりひきすう、かびきすう、parameter, formal parameter)とは、関数定義の際に、その関数に渡されてくる実引数に名前を付け、関数内で使用できるようにしたもののことです。関数名直後の括弧内にカンマで区切られて書かれます。関数宣言の括弧内に記述された識別子も仮引数と呼ばれます。また、関数マクロ定義のマクロ名直後にある括弧で括られた中に書かれる識別子も仮引数です。仮引数はパラメータとも呼ばれます。
例を見てみましょう。以下の例では、n1, n2が実引数、a, bが仮引数となります。
int main(int argc, char *argv[])
{
/* 省略 */
m = max(n1, n2);
/* 省略 */
}
int max(int a, int b)
{
int value;
if (a >= b) {
value = a;
} else {
value = b;
}
return value;
}
C言語では、すべての引数は値で受渡しされます。引数が値で受渡しされることを、値渡し(あたいわたし、call by value)と呼びます。
実引数として変数や式を渡したとしても、その評価結果の値のみがコピーされて渡されます。そのため、呼び出された関数側で、仮引数(パラメータ・オブジェクト)の内容を変更しても、元の実引数に影響はありません。
では、呼び出し元関数の変数の値を変更したい時にはどうするのでしょうか?
これは、関数を呼び出す際に、変数のアドレスを渡すことにより実現可能です。呼び出された関数では、パラメータがポインタであることを宣言し、ポインタの指すオブジェクトの内容を変更します。
例を見てみましょう。
#include <stdio.h>
#include <stdlib.h>
void max(int a, int b, int *m)
{
if (a >= b) {
*m = a;
} else {
*m = b;
}
}
int main(int argc, char *argv[])
{
int n1, n2, m;
n1 = atoi(argv[1]);
n2 = atoi(argv[2]);
max(n1, n2, &m);
printf("%d¥n", m);
}
main関数でint型の変数mのアドレスをmax関数に渡しています。max関数はint型のポインタとしてそれを受け取り、ポインタの指すオブジェクトを変更します。このようにするとmain関数のローカル変数mの内容をmax関数側で変更することが可能です。
C言語のmain関数に渡されてくる引数は、プログラム実行時にパラメータとして指定されたものです。下記の例ではabcになります。
C:¥c>parrot.exe abc
abc
C:¥c>
main関数の引数は2つあります。
int main(int argc, char *argv[])
1つめの引数はargcは、そのプログラムを呼び出したコマンド行の引数の個数です。argcはargument countの略です。この個数にはプログラムの名称もカウントされてきます。上記例のようにparrot.exe abcと入力されたならばargcは2となります。
2つめの引数argvにはコマンド行の引数が文字列の配列として渡されてきます。argv[0]にはプログラムの名称が、argv[1]には第一引数、argv[2]に第二引数、、、という具合に渡されます。argvはargument vectorの略です。
例として、コマンド行で指定された引数をそのまま出力するparrotプログラムを書いてみます。
/*
parrot.c
プログラムに渡された引数をそのまま出力するプログラム
*/
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
/* 引数の個数分繰り返す */
/* argv[0]はプログラム名なのでiは1から始める */
for (i=1;i<argc;i++) {
/* 引数を出力 */
printf("%s", argv[i]);
/* 最後の引数以外は区切りの半角スペースを出力 */
if (i < argc - 1) {
printf(" ");
}
}
printf("¥n");
}