Top授業関係プログラミング言語2 → 関数の自作の基礎
[前のページ] [目次] [次のページ]


8. 関数の自作の基礎


8.1 関数の自作方法

C言語の関数は自作することができます。

たとえば、以下のような例を考えます。 この例では、sample01という関数を作成しています。

#include<stdio.h>

int sample01(int max){
    int i;
    int tmp=0;

    for(i=1;i<=max;i++){
        tmp=tmp+i;
    }
    return tmp;
}

main(){
    int value;
    int scan_value;

    scanf("%d",&scan_value);
    value=sample01(scan_value);
    printf("%d",value);
}

関数は、

から成り立ちますので、関数を自作するときも、上記の要素を備えている必要があります。

大体の構造は、以下のようになります。

戻り値の型を指定 関数名(引数と引数の型を指定){

    文

    return 戻り値を指定;
}

上記のsapmle01は、

ということになります。


8.2 関数の戻り値

関数の戻り値の型としては、普通の変数として宣言する型以外に、void を指定することができます。これは、『戻り値が無いこと』ことを宣言することになります。

return 命令があると、戻り値を戻し、関数の処理は終了します。 関数の戻り値が void の場合は、単に return と書けばよいです。 return を書かなかった場合は、末尾まで実行した後、戻り値として何も戻さずに、関数が終了します。

main も関数です。main 関数にも、戻り値を指定することができます。 型を指定しなかった場合は、main は整数値を返す関数と解釈されます。


8.3 関数の引数

関数の引数には、

の2通りがあります。ここでは、その内容と違いについて説明します。


8.3.1 値渡し

関数の引数として、値を渡す方法です。

関数に渡されるのは、あくまでも『値のみ』です。 変数が渡されるわけではありません。 関数内部では、渡された値を、自前の変数に代入し、処理を行います。

以下に例を示します。

#include<stdio.h>

int sample01(int tmp){
    tmp=tmp+2;
    return tmp;
}

main(){
    int scan_value;
    int value;
    
    scanf("%d",&scan_value);
    value=sample01(scan_value);
    printf("%d\n",scan_value);
    printf("%d\n",value);
}

関数 main が実行されると、まず、標準入力から整数値を読み込みます。 そのご、sample01 という関数を呼びます。 その際に、scan_value の値を引数として渡しています。

関数sample01 は、渡された値を、tmp という変数に代入します。 そして、tmp に 2 を加え、tmp に代入し、その結果を戻り値として返しています。

main関数は、戻り値を value に代入します。 その後、scan_value と value の値を標準出力に出力します。 この時出力される値は、それぞれ、最初に標準入力から読み込んだ値と、それに2を加えた値になります。

先のプログラムに書き加えて、関数main の中の変数 scan_value のアドレス と、関数sample01の中の tmp のアドレスを表示するようにすると、異なるアドレス(つまり、異なる変数)が使われているのがわかります。

#include<stdio.h>

int sample01(int tmp){
    printf("The addres of tmp is %u\n",&tmp);
    tmp=tmp+2;
    return tmp;
}

main(){
    int scan_value;
    int value;
    
    printf("The addres of scan_value is %u\n",&scan_value);
    scanf("%d",&scan_value);
    value=sample01(scan_value);
    printf("%d\n",scan_value);
    printf("%d\n",value);
}

8.3.2 アドレス渡し

関数の引数として、(変数の)アドレスを渡す方法です。

関数に渡されるのは、『変数のアドレス』です。 関数内部では、自分で使用する変数のアドレスを、引数として渡されたアドレスに設定します。 つまり、関数内部と外部で名前は異なる変数かもしれませんが、保存する場所は一緒になります。

以下に例を示します。

#include<stdio.h>

int sample01(int *tmp){
    *tmp=*tmp+2;
    return *tmp;
}

main(){
    int scan_value;
    int value;
    
    scanf("%d",&scan_value);
    value=sample01(&scan_value);
    printf("%d\n",scan_value);
    printf("%d\n",value);
}

値渡しのときと異なり、sample01の引数が、整数型へのポインタとなっています。

関数 main が実行されると、まず、標準入力から整数値を読み込みます。 そのご、sample01 という関数を呼びます。 その際に、scan_value のアドレスを引数として渡しています。

関数sample01 は、渡されたアドレスを、tmp に代入します。tmp はアドレスですので、*tmp とすると、保存されている値にアクセスすることができます。 そして、*tmp に 1 を加え、*tmp に代入し、その結果を戻り値として返しています。 この際、*tmp が保存されているアドレスと、関数 main 中の変数 scan_value のアドレスは一緒であることに注意しましょう。

main関数は、戻り値を value に代入します。 その後、scan_value と value の値を標準出力に出力します。 この時出力される値は、両方とも最初に読み込んだ値に2を足したものになります。

先のプログラムに書き加えて、関数main の中の変数 scan_value のアドレス と、関数sample01の中の tmp のアドレスを表示するようにすると、同じアドレスを使用していることがわかります。

#include<stdio.h>

int sample01(int *tmp){
    printf("The address of tmp is %u\n", tmp);
    *tmp=*tmp+2;
    return *tmp;
}

main(){
    int scan_value;
    int value;
    
    printf("The address of scan_value is %u\n", &scan_value);
    scanf("%d",&scan_value);
    value=sample01(&scan_value);
    printf("%d\n",scan_value);
    printf("%d\n",value);
}

8.4 スコープ

以下の例を考えます。

#include<stdio.h>

int scan_value;

int sample01(int max){
    int i;
    int value=0;

    for(i=1;i<=max;i++){
        value=value+i;
    }
    return value;
}

main(){
    int value;

    scanf("%d",&scan_value);
    value=sample01(scan_value);
    printf("%d",value);
}

多くの整数型の変数が宣言されているように見えますが、

と、それぞれ宣言文が書かれている場所が異なります。かつ、value に至っては、関数main 中と関数 sample01 の中で、それぞれ宣言されています。

変数は宣言される場所によって、その変数が使える場所が異なって来ます。とりあえず、上記のように宣言した場合は、

と考えておけばよいでしょう(そうでないように宣言することもできますが、この授業では扱いません)。

つまり、

ということになります。

#include<stdio.h>

int scan_value;   // 関数 main 中でも、関数 sample01中でも参照できる。

int sample01(int max){
    int i;   // 関数 sample01中でのみ参照できる。
    int value=0;   // 関数 sample01中でのみ参照できる。

    for(i=1;i<=max;i++){
        value=value+i;
    }
    return value;
}

main(){
    int value;    // 関数 main 中でのみ参照できる。

    scanf("%d",&scan_value);
    value=sample01(scan_value);
    printf("%d",value);
}

以上のことより、関数 sample01 中で宣言された変数 value と、関数 main 中で宣言された変数 value は、別の変数であることがわかります。

同じ場所で、2つの同じ名前の変数が参照できるような状態にすることはできません。 たとえば、上の例で、関数の外側で value という変数を新たに宣言するようなことはできません(関数の外側で宣言した value と関数mainの中で宣言した value がかち合うからです)。


目次に戻る
授業関係のページに戻る