[c言語] さっと復習(7) ソースの分割

ソースコードの分割

「プロトタイプ宣言」「メイン」「プロトタイプ宣言に対応する関数」の3つに分割する。

#include <stdio.h>

// プロトタイプ宣言
double avg(double, double);

// main
int main(void) {
    double a, b, ans;

    printf("Return the average of 2 numbers.\n");
    printf("Please input first one: ");
    scanf("%lf", &a);
    printf("lease input second one: ");
    scanf("%lf", &b);

    ans = avg(a, b);
    printf("The average of %f and %f is %f.\n", a, b, ans);
    
    return 0;
}

// プロトタイプ宣言した関数の処理
double avg(double a, double b) {
    double ans;
    ans = (a + b) / 2.0;
    return ans;
}

上を以下のように3つに分割する。

ヘッダファイル

ヘッダファイル: Header file)は、特にC言語C++でのプログラミングで使われるファイルであり、一般にソースコード形式をしていて、コンパイラが別のソースファイルの一部として自動的に展開して使用する。一般にヘッダファイルは、ソースファイルの先頭部分に書かれたディレクティブによってインクルード(その場に内容を展開)される。インクルードファイル: Include file)とも。

出典: フリー百科事典『ウィキペディア(Wikipedia)』

プロトタイプ宣言部分をヘッダファイルとして分離する。

// avg.h
// 多重includeを防ぐ。
#ifndef _AVG_H_
#define _AVG_H_

// プロトタイプ宣言
double avg(double, double);

#endif //_AVG_H_

#ifndef #endif というディレクティブを使うことで、多重定義を防いでいる。

プリプロセッサ

メイン関数

メイン関数部分。

#include < > は、ライブラリ.libとしてコンパイル済みのファイルをincludeするために使う。

#include " " は、ユーザー定義のヘッダファイルをinlcudeするために使う。

// main.c
#include <stdio.h>
// ユーザー定義のヘッダファイルを読み込むときは "" で囲むようにする。
#include "avg.h"

int main(void) {
    double a, b, ans;

    printf("Return the average of 2 numbers.\n");
    printf("Please input first one: ");
    scanf("%lf", &a);
    printf("lease input second one: ");
    scanf("%lf", &b);

    ans = avg(a, b);
    printf("The average of %f and %f is %f.\n", a, b, ans);
    
    return 0;
}

関数定義

メイン関数で使われる各種関数を実際に定義する。

// avg.c
#include "avg.h"

// プロトタイプ宣言した関数の処理
double avg(double a, double b) {
    double ans;
    ans = (a + b) / 2.0;
    return ans;
}

コンパイル

コンパイルは.c ファイルをまとめて記述する。

gcc -Wall -Wconversion -o main main.c avg.c

グローバル変数

グローバル変数はプログラム全体で利用される可能性があるが、プログラムを分割すると他のプログラムから参照できなくなってします。

そこで、extern を変数宣言の前につけることで、外部で定義されたグローバル変数を他ファイルから参照していることを表す。

下記は、上のプログラムの ans をグローバル変数に変えたもの。

#include <stdio.h>

// グローバル変数
double ans;

// プロトタイプ宣言
void avg(double, double);

// main
int main(void) {
    double a, b;

    printf("Return the average of 2 numbers.\n");
    printf("Please input first one: ");
    scanf("%lf", &a);
    printf("lease input second one: ");
    scanf("%lf", &b);

    avg(a, b);
    printf("The average of %f and %f is %f.\n", a, b, ans);
    
    return 0;
}

// プロトタイプ宣言した関数の処理
void avg(double a, double b) {
    ans = (a + b) / 2.0;
}

上を3つに分割する。

ヘッダファイル

ヘッダファイルでは、グローバル変数の宣言のみを行い、グローバル変数の定義は c フィアルで行う。

#ifndef _AVG_H_
#define _AVG_H_

// グローバル変数 
// ヘッダファイルでは extern をつけて宣言のみ行う。
extern double ans;

// プロトタイプ宣言
void avg(double, double);

#endif //_AVG_H_

メイン関数

グローバル変数の定義はここで行っている。

#include <stdio.h>
#include "avg.h"

// グローバル変数の定義。
double ans = 0;

// main
int main(void) {
    double a, b;

    printf("Return the average of 2 numbers.\n");
    printf("Please input first one: ");
    scanf("%lf", &a);
    printf("lease input second one: ");
    scanf("%lf", &b);

    avg(a, b);
    printf("The average of %f and %f is %f.\n", a, b, ans);
    
    return 0;
}

関数定義

// avg.c
#include "avg.h"

extern double ans;

// プロトタイプ宣言した関数の処理
void avg(double a, double b) {
    ans = (a + b) / 2.0;
}