Index

HOME > プログラムTOP > C++




C++の基礎知識(6)

【関数篇】

| ●宣言 | ●戻り値 | ●引数 | ●オーバーロード | ●再帰処理 |
( 記述篇, データ型篇, 定数篇, 変数篇, 演算子篇, 制御文篇, ポインタ篇, 構造体篇, クラス篇, 番外篇 )

sasaraan programming

Exposition

●宣言

 関数はデータ型と関数名を指定して宣言します。関数名の後には()、中身のコードは{}で囲むことが必要です。また、関数は、記述した順番にコードが認識されていくので、使用する前に定義されている必要があります。ただし、宣言だけを前もってしておいても(プロトタイプ宣言)同様の効果があります。
// プロトタイプ宣言なしの場合
// 後ろにある関数は前で呼び出せない

void func_A() {
    func_B();  // 呼び出し不可
}

void fonc_B() {
    func_A();  // 呼び出し可
}
// プロトタイプ宣言
void func_A();  // {}の代わりに、
void func_B();  // 末尾に;が必要

void func_A() {
    func_B();  // 呼び出し可
}
void fonc_B() {
    func_A();  // 呼び出し可
} 

●戻り値

 関数は値を返すことができます。値は関数のデータ型と一致させる必要があります。
 値を返す値は、return キーワードを利用して指定します。この時、return で値を返すと同時に関数を抜けることになります。戻り値がない場合でも、return の記述をした場所で関数は終了します。
 また、配列を返す時は、ポインタを利用して先頭要素のアドレスを返します。この時、関数側の返す値は、関数が終わった段階で消えてしまうので、グローバル変数か静的変数(static)でメモリに常駐させておく必要があります。
// returnで値を返す
int get_id() {
    int n = 999;
    return n;   // 戻り値
}
void main() {
    int id = get_id(); // =999
}
// returnで関数は終了
int get_id() {
    int n = 0;
    return n;  // 関数終了
    n = n + 1;    // 実行されない
}
// 配列を返す(文字列)
char *get_abc() {
    static char buf[10] = "ABC";
    return buf;
}
void main() {
    char *abc = get_abc(); // ="ABC"
}
// 戻り値のない関数のreturn
void get_id() {
    int n = 0;
    return;   // 関数終了
    n = n + 1;    // 実行されない
} 

●引数

 関数にはデータを渡すことができます。これを引数(ひきすう)といい、複数の引渡しも可能です。この時、通常、値はコピーされてから渡され(値渡し)、元の値には影響しません。
 ただし、ポインタ(ポインタ渡し)や参照(参照渡し)を使ってアドレスを渡すこともできます。この時は元の値にも影響します。
 また、引数には初期値を設定することができます。この時、プロトタイプ宣言で初期値を記述した場合は、本体部分の初期値の記述は必要ありません。また、初期値を設定した引数の後にも引数があるときは、すべてに初期値を設定しなければなりません。
// 値渡し
int get_id(int id) {
    id = 0;
    return id;
}
// 結果
void main() {
    int a = 9;
    int b = get_id(a); // a=9, b=0
}
// ポインタ(アドレス)渡し
int get_id(int *id) {
    *id = 0;
    return *id;
}
// 結果
void main() {
    int a = 9;
    int b = get_id(&a); // a=0, b=0
}
// 参照渡し
int get_id(int &id) {
    id = 0;
    return id;
}
// 結果
void main() {
    int a = 9;
    int b = get_id(a); // a=0, b=0
}
// 配列を渡す(配列として)
void set_abc(char buf[]) {
    buf = "ABC";
    printf("%s", buf);
}
// 結果
void main() {
    char s[10];
    set_abc(s);  // "ABC"を出力
}
// 配列を渡す(ポインタとして)
void set_abc(char *buf) {
    buf = "ABC";
    printf("%s", buf);
}
// 結果
void main() {
    char s[10];
    set_abc(s)  // "ABC"を出力;
}
// デフォルト引数
void set_id(int id = 0) {
    // 指定がない時は 0が初期値
    printf("%d", id);
}
// 結果
void main() {
    set_id();   // 引数省略時 0を表示
    set_id(9);  // 通常は 9を表示
}

●オーバーロード

 関数は、異なる引数(データ型、順番、個数)であれば、同じ関数名でも複数定義する(= オーバーロード)ことができます。以下の四つの関数は同時に定義することが可能です。

void set_prop(int x);
void set_prop(float y);
void set_prop(int x, float y);
void set_prop(float x, int y);

●再帰処理

 関数は自らを呼び出す(再帰コール)ことができます。ただし、関数内の変数はすべて自動変数であること、さらに引数は値渡しである必要があります。また、無限に呼び出すことのないよう終了条件を設定しなければなりません。
// 階乗の計算
int get_fact(int num) {
    if (num == 1) {
        return 1;
    } else {
        return num * get_fact(num-1);
    }
} 
// 結果
void main() 
{
    int m;
    int n = 10;
    m = get_fact(n);  // 10の階乗
    printf("%d", m);  // =3628800
} 

www.sasaraan.net

(c) morijoh