[C言語]分割コンパイルを使ってみた[画像付き]

C言語雑記

参考書を読んで分割コンパイルという技術を知ったので、
今回はアウトプットかつ知識の整理ということで、
初めてソースファイルを分けてプログラムを実行する分割コンパイルを行ってみました。

まあ日記のような感じです。



分割コンパイルとは?

今まで僕の記事ではいつも、「全体のコード」として作った関数などをすべて一つのソースファイルの中に書き込んでみました。

今回はいくつかの関数だけ違うファイルにして、
違うファイルからそれを呼び出してプログラムを実現
してみます。
いわゆる分割コンパイルです。


普段僕たちはprintf関数を使っていますがあれは自分で書いたコードでは定義してないですよね?
最初に<stdio.h>というライブラリをインクルードすることで使用が可能になります。

つまり、<stdio.h>というライブラリの中で頑張ってprintf関数を作ってもらって、僕たちはその内容は知らないけどprintf関数は取りあえず使える状態ですって感じです。


分割コンパイルで別のファイルを作って利用するのも同じイメージです。
今回はそんなライブラリみたいなものを作ってみます。



ソースファイルとヘッダファイル

早速新しいファイルを作ろうと思って
Xcodeで新しいプログラムを開いてメニューバーから新しいファイルを追加したのですが、


ん?
追加した新しいファイルが二つある?
なんで?


どうやら分割コンパイルの際の別のファイルには

ヘッダファイル(.hで終わるやつ)
ソースファイル(.cで終わるやつ)

の二つのファイルがあるようです


簡単に解説すると

ヘッダファイルは構造体やマクロの定義、そして関数原型宣言などのみを行うファイルです。

ソースファイルは宣言した関数の中身を記述するファイルです。中身を記述する前に、ヘッダファイルをインクルードします。

僕の頭の中のイメージ図です

この二つを揃えることが必須です。
ヘッダファイルを作っておくことで、このソースファイルではこんな感じのやつを定義するから準備しとけよっ!!って感じですかね。

そしてメインとなるソースファイルで

ヘッダファイルをインクルードすればおkです


ちなみに全体としては

こんな感じ。

つまり実行する方のソースファイル(上ならprogrm.c)と、
分割された関数の中身が記述されているソースファイル(上ならfile.c)
は直接つながってないんですね。これで動くのはなんか不思議。



簡単なコード

ファイル操作関数を分割コンパイルしてみました。

まずヘッダファイル

#ifndef file_h
#define file_h

void SCAN(int N, double x[N], char *name);

void WRITE(int N, double x[N], char *name);

#endif /* file_h */

そしてそのソースファイル

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

void SCAN(int N, double x[N],char *name){ //読み込み用関数
    FILE *fp;
    int i;

        if((fp=fopen(name,"r"))==NULL){
            printf("ファイルを読み込めません\n");
        }else{
            for(i=0; i<N; i++){
                fscanf(fp,"%lf",&x[i]);
            }
        }
    
    fclose(fp);
}

void WRITE(int N, double x[N], char *name){ //書き込み用関数
    FILE *fp;
    int i;
    
    if((fp=fopen(name,"w"))==NULL)
        printf("ファイルに書き込めません\n");
    else{
        for(i=0; i<N; i++){
            fprintf(fp,"%lf\n",x[i]);
            
        }
    }
    fclose(fp);
}

最後に実行するファイル

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

#define NAME 64

int main(int argc, const char * argv[]) {
    char name[NAME];
    int i;
    
    printf(":");
    scanf("%s",name);
    
    int N=3;
    double x[N];
    for(i=0; i<N; i++){
        x[i] = 0;
    }
    
    WRITE(N, x, name);
    
    double y[]={1,1,1};
    
    SCAN(N, y, name);
    
    for(i=0; i<N; i++){
        printf("%f\n",y[i]);
    }
    
    return 0;
}


こんな感じですね。
ヘッダの

#ifndef file_h
#define file_h

#endif /* file_h */


この条件コンパイルの部分はインクルードガードです。
後に紹介しようと思うのでとりあえず今回はおまじない的な感じで。


分割コンパイルは大規模なコードを書くときに必要らしいのでマスターしたいですね。
頑張ろ!!


ではまた〜

コメント

タイトルとURLをコピーしました