ベイジアン研究所

技術(人工知能、数学等)と心理の話をしています。

【C言語入門】関数編2

1. 値を返さない関数
関数とは処理を一纏めにしたものである。値を返却する事で元の処理に役立つが、値を返却しない関数も書く事ができる。例えば次のように表示のみを行う関数である。

void aisatsu(int n)
{
    while (n-->0)
        printf("Hello World!");
}

先頭のvoidが、返却値がないことを表している。

2. 仮引数を受け取らない関数
例えば、次のようなプログラムを書く事ができる。

int sum(void)
{
    int i = 1
    for (i=1; i<=100; i++) {
        i = i+1
    }
    return i;
}

int main(void)
{
    int n = sum()
    print("%d", n);

    return 0;
}

main関数のnはsum関数で計算された値で常に初期化される。ちなみに、main関数のint main(void)のvoidは、main関数が仮引数を受け取らないことを示している。

3. 関数での配列の受け渡し方法
配列を関数で受け取る場合は、次のように書く。

int max(int v[ ], int n)
{
    int max = v[0];
    for (i=0; i<=n; i++){
        if (v[i]>max) {
            max = v[i];
        }
    }
    
    return max;
}

配列の仮引数を配列名と空の括弧からなる文字とする。その後ろに配列の数を引数として配置する。ここで受け取った配列は関数内で変更すると、元の配列も変更される。(ポインタを渡しているので。ここでは気にしなくて良い。)

配列を関数に渡す時は、次のように書く。

int main(void)
{
    int mat[5] = {1, 2, 3, 4, 5};
    mat_e = max(mat, 5);
    print("%d",  mat_e);

    return 0; 
}

次のような「型修飾子」と言うものをつける事ができる。

void max(const int v[ ], int n)

この時、受け取る配列の要素の値を変更しないことを宣言する。

4. 有効範囲と記憶期間
関数の内側か、外側かで、変数の有効な範囲が変化する。この変数が通用する範囲のことを「有効範囲」と言う。

関数のようなブロック(複合文)の中での宣言はそのブロックの中でしか通用しない。このような有効範囲のことを「ブロック有効範囲」と言う。逆に、関数の外で宣言された変数は、宣言した場所からそのソースプログラムの最後まで通用する。このような有効範囲のことをファイル有効範囲という。

ブロック有効範囲とファイル有効範囲には図に示すようないくつかの性質がある。 f:id:camelsan:20200929201802p:plain

また、宣言された変数は、その名前を書き終えた直後から有効である。例えば図のようなものが考えられる。 f:id:camelsan:20200929202205p:plain

「記憶域期間」とは、変数が生存できる期間のことである。自動記憶期間と静的記憶期間と言うものがある。

  • 自動記憶期間
    生存できるのはブロックの中のみ。関数の中で記憶域クラス指定子を付けずに定義された変数。初期化子が与えられなければ、その初期値は不定値。

  • 静的記憶域期間
    main関数を実行する前に変数が生成され、生存期間はプログラムの終了時まで。関数の中でstaticをつけて宣言された変数や、関数の外で宣言、定義された変数。初期化子が与えられなければ、自動的に0で初期化される。

5. ヘッダとインクルード
ここで、main関数の前にくっついている、

#include <stdio.h>

と言う部分に関して説明する。これは、printfやscanfなどの関数が使えるようにするための宣言で、「ヘッダをインクルードする」などと言う。 f:id:camelsan:20200929203818p:plain