数はファイル内のどの関数からでも参照できるので便利ではありますが 変数の衝突が起こったり ファイル内のどこで値が書き換えられたかわかりづらくなったりなどの欠点があります 複数の関数で変数を共有する時は出来るだけ引数を使うようにし グローバル変数は プログラムの全体の状態を表すものなど最低限のものに留

Similar documents
プログラミング実習I

memo

分割コンパイル (2018 年度 ) 担当 : 笹倉 佐藤 分割コンパイルとは 一つのプログラムのソースを複数のソースファイルに分けてコンパイルすること ある程度大きなプログラムの場合ソースファイルをいくつかに分割して開発するのが普通 1

Microsoft Word - Training10_プリプロセッサ.docx

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

Microsoft PowerPoint - 計算機言語 第7回.ppt

(1) プログラムの開始場所はいつでも main( ) メソッドから始まる 順番に実行され add( a,b) が実行される これは メソッドを呼び出す ともいう (2)add( ) メソッドに実行が移る この際 add( ) メソッド呼び出し時の a と b の値がそれぞれ add( ) メソッド

Microsoft Word - no11.docx

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

Microsoft Word - VBA基礎(6).docx

書式に示すように表示したい文字列をダブルクォーテーション (") の間に書けば良い ダブルクォーテーションで囲まれた文字列は 文字列リテラル と呼ばれる プログラム中では以下のように用いる プログラム例 1 printf(" 情報処理基礎 "); printf("c 言語の練習 "); printf

PowerPoint Presentation

講習No.12

プログラミング及び演習 第1回 講義概容・実行制御

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

Microsoft PowerPoint ppt

PowerPoint プレゼンテーション

#include<math.h> 数学関係の関数群で sin() cos() tan() などの三角関数や累乗の pow() 平方根を求める sqrt() 対数 log() などがあります #include<string.h> 文字列を扱う関数群 コイツもまた後日に 4. 自作関数 実は 関数は自分

Fortran 勉強会 第 5 回 辻野智紀

プログラミング入門1

Microsoft PowerPoint - 12.ppt [互換モード]

PowerPoint プレゼンテーション

概要 プログラミング論 変数のスコープ, 記憶クラス. メモリ動的確保. 変数のスコープ 重要. おそらく簡単. 記憶クラス 自動変数 (auto) と静的変数 (static). スコープほどではないが重要.

Microsoft PowerPoint - å®�æ−•è©¦é¨fi3ㆮ対ç�Œ.pptx

02: 変数と標準入出力

関数の中で宣言された変数の有効範囲はその関数の中だけです さっきの rectangle _s で宣言されている変数 s は他の関数では使用できません ( 別の関数で同じ名前の変数を宣言することはできますが 全く別の変数として扱われます このように ある関数の中で宣言されている変数のことをその関数の

memo

Microsoft PowerPoint - 09.pptx

Microsoft PowerPoint - CproNt02.ppt [互換モード]

演算増幅器

ブート領域、フラッシュ領域の分割方法 RL78ファミリ用Cコンパイラ CC-RL

Microsoft Word - CygwinでPython.docx

<4D F736F F D2091E63589F182628CBE8CEA8D758DC08E9197BF2E646F6378>

ガイダンス

Microsoft PowerPoint - prog04.ppt

Microsoft PowerPoint - 13.ppt [互換モード]

Microsoft PowerPoint - prog07.ppt

Microsoft PowerPoint Java基本技術PrintOut.ppt [互換モード]

演算増幅器

Microsoft PowerPoint - prog03.ppt

プログラミング基礎

C言語講座

Microsoft PowerPoint - prog08.ppt

PowerPoint プレゼンテーション

関数 C 言語は関数の言語 関数とは 関数の定義 : f(x) = x * x ; 使うときは : y = f(x) 戻り値 引数

02: 変数と標準入出力

C#の基本

3-4 switch 文 switch 文は 単一の式の値によって実行する内容を決める ( 変える ) 時に用いる 例えば if 文を使って次のようなプログラムを作ったとする /* 3 で割った余りを求める */ #include <stdio.h> main() { int a, b; } pri

た場合クラスを用いて 以下のように書くことが出来る ( 教科書 p.270) プログラム例 2( ソースファイル名 :Chap08/AccountTester.java) // 銀行口座クラスとそれをテストするクラス第 1 版 // 銀行口座クラス class Account String name

講習No.1

Microsoft Word - C言語研修 C++編 3.doc

memo

Undestand の解析 Understand の C 言語で抽出できない依存関係について サンプルコードを用いて説明します 確認バージョン Understand 3.0 (Build 640) Understand 3.1 (Build 700) Understand 4.0 (Build 78

Microsoft Word - no202.docx

Microsoft Word - no02.doc

Microsoft PowerPoint - 12.ppt [互換モード]

プログラミング入門1

Si 知識情報処理

memo

Microsoft PowerPoint pptx

プレポスト【問題】

プログラミングI第10回

slide5.pptx

Microsoft PowerPoint - 10.ppt [互換モード]

プログラミング演習3 - Cプログラミング -

また 初期化について 以下のサンプルコードのように指定すれば 定義時に値を代入できます * オマケ配列は同名で複数個の箱を用意出来ます 同名ではありますが それぞれは別々の個体であるわけです また この複数個の変数は メモリ上に連続で確保されます 2. 文字と文字列 C 言語では文字と文字列は異なる

PowerPoint Presentation

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

アクション講座 第1回目

実行形式の作成と構成管理 2012 年 7 月 8 日 海谷治彦 1

Microsoft PowerPoint - 第5章補足-DB2組み込みSQL.ppt

PowerPoint プレゼンテーション

CプログラミングI

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

プログラミング演習3 - Cプログラミング -

Microsoft PowerPoint - handout07.ppt [互換モード]

Microsoft PowerPoint - chap10_OOP.ppt

Microsoft PowerPoint - 11.pptx

Microsoft PowerPoint - guidance.ppt

情報処理 Ⅱ 2007 年 11 月 26 日 ( 月 )

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

3.Cygwin で日本語を使いたい Cygwin で以下のコマンドを実行すると それ以降 メッセージが日本語になります export LANG=ja_JP.UTF-8 これは 文字コードを日本語の UTF-8 に設定することを意味しています UTF-8 は Cygwin で標準の文字コードで, 多

Microsoft PowerPoint - kougi2.ppt

Microsoft Word - no13.docx

C C UNIX C ( ) 4 1 HTML 1

1. 関数 scanf() 関数 printf() は変数の値を画面に表示しますが それに対し関数 scanf() はキーボードで入力した値を変数に代入します この関数を活用することで対話式 ( ユーザーの操作に応じて処理を行う ) プログラムを作ることができるようになります 整数の和

Microsoft PowerPoint - Borland C++ Compilerの使用方法(v1.1).ppt [互換モード]

C 言語固有の命令で全部で32 個 の関数C 言語第 1 回 C 言語って?( シラバス 1 2 回目 ) 関数型言語 コンピュータに実行してもらう命令はすべて関数の中に記述されている 関数がプロ グラム

WinAPIOverride32 入門

マクロの実行許可設定をする方法 Excel2010 で 2010 でマクロを有効にする方法について説明します 参考 URL:

PowerPoint プレゼンテーション

SuperH RISC engineファミリ用 C/C++コンパイラパッケージ V.7~V.9 ご使用上のお願い

cp-7. 配列

プログラミング基礎I(再)

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

デバッグの工夫

スライド 1

JavaプログラミングⅠ

Microsoft PowerPoint - prog06.ppt

基礎プログラミング2015

Transcription:

第 10 章分割コンパイル 1 ソースを分割する今まで出てきたソースは全て一つのソースファイルにソースを記述してきました しかし ソースが長くなっていくと全てを一つのファイルに書くと読みづらくなります そこで ソースを複数のファイルに分割してコンパイルを行う分割コンパイルをします 今章は章名にもなっている 分割コンパイルの方法についてやります 分割コンパイルする時は大抵 関連性のある機能ごとにファイルにまとめます そうすることによって ソースが長くなった時に複数のファイルに分け 更に機能ごとにまとまるので修正する時など読みやすくなります 良く使う処理を別のファイルにしていろんなプログラムで使いまわすということも考えられます また 変更を加えたファイルだけコンパイルすることが出来るので コンパイルの時間を減らすことが出来ます 更に 現在プログラムが作られる時は大抵複数人で行います そういう時ももちろん分割コンパイルします 分割コンパイルは次のセクションで述べる変数のスコープ ( 有効範囲 ) をしっかり把握していれば難しいものではありません 2 変数のスコープ変数はどこで宣言するかによってどこで使えてどこで使えないかが決まります 例えば今まで関数内で宣言した変数は関数内でしか使えませんでした これに対し 関数の外で宣言するとそのファイル内全体で使用することができます 関数内でしか使えないような変数をローカル変数 ファイル内全体で使用することが出来る変数をグローバル変数と呼びます 変数のスコープ int a; int b; void func(void){ int c; 上のようなソースだった場合 a は main 関数でも func 関数でも使うことが出来ます それに対し b は main 関数のみ c は func 関数のみで使うことが出来ます グローバル変 1

数はファイル内のどの関数からでも参照できるので便利ではありますが 変数の衝突が起こったり ファイル内のどこで値が書き換えられたかわかりづらくなったりなどの欠点があります 複数の関数で変数を共有する時は出来るだけ引数を使うようにし グローバル変数は プログラムの全体の状態を表すものなど最低限のものに留めておきましょう ( 最初はよく使うことになるでしょうが ) 先ほどグローバル変数の説明にファイル内全体で使えると書きました 今章ではソースの分割を行いますが 複数のファイルで変数を共有する時も出てきます その場合はどうするかというと その変数を共有したいファイル内で extern 宣言と呼ばれる宣言をします 複数のファイルで変数を共有する ファイル 1 int a; void func1(void){ ファイル 2 void func2(void){ ファイル 3 extern int a; void func3(void){ main 関数内や func1 関数内では当然変数 a は使うことが出来ます func2 では宣言がされていないので a は使うことは出来ません func3 ではファイル 3 内で extern 宣言をしているのでファイル 3 内では普通にグローバル変数として用いることが出来ます int a; と書くと a という変数のためにメモリ領域を取るなどが行われます extern int a; と書くと他のファイルにある a という変数をこのファイル内で用いるということを宣言しています 関数のプロトタイプ宣言も本来は頭に extern をつけるのを省略しているだけで 意味合いは同じです 2

3 Makefile それでは 具体的に分割コンパイルをする方法を見てみましょう 分割コンパイルを行うには Make と呼ばれる作業が必要です Make を行うには何通りか方法があります まずは 全てを手作業で行う方法です これについては後ほど触れます 他に Makefile と呼ばれるものを使う方法があります Visual C++ などの統合環境を用いると勝手に作ってくれるのですが まずは自分で書いてみましょう それでは例を示します Makefile を使った分割コンパイルの方法 ( プログラム 10.1-1) ファイル名 :main.c void func(void); func(); return(0); ファイル名 :func.c void func(void){ printf(" 関数が呼び出されました "); まずはコンパイルするソースを作ります 今までと違って今回はファイル名を指定していますが 別の名前でもかまいません ( その場合は次に示す Makefile の所でファイル名を用いますので各自ファイル名を置き換えてください ) main 関数内で func 関数を呼び出すので関数のプロトタイプ宣言を行います これはファイルを分割してもしなくても同じことです また それぞれのファイルで stdio.h をインクルードしています ヘッダーファイルをインクルードする時はそれぞれのファイル内で使う関数を使うのに必要なヘッダーファイルをそれぞれインクルードします ( この例だと main 関数では必要ないですが ) 分割したファイルのどこかでインクルードしたら別のファイルでも使えるということは無いので注意してください それでは次に Makefile の作り方を示します ファイル名は makefile にしておいて下さい 3

Makefile を使った分割コンパイルの方法 ( プログラム 10.1-2) # makefile for main # target : main.exe all : main.exe main.exe: main.obj func.obj bcc32 -emain.exe main.obj func.obj main.obj: main.c bcc32 -c main.c func.obj: func.c bcc32 -c func.c # から始まる行はコメント文を表します target は CPad に実行ファイルがどれかを知らせるための文で Make には関係ありません all はシンボリックターゲットと言って その後ろにあるファイル名が最終的に作られるファイルです 二つ以上の実行ファイルを作る時はその数だけ実行ファイル名を書きます その下からは実際に Make する時のファイルの依存関係と Make するためのコマンドです 依存関係は必ず行頭から書き コマンドは行頭に必ずタブ文字を入れてから書きます スペースを入れても動きません ところで.obj という拡張子があります これはオブジェクトファイルと言うものです 今まで特に触れませんでしたが C のソースを実行形式にする場合二つの手順が踏まれています コンパイラがソースをコンパイルした物がオブジェクトファイルです ソース内で使われているライブラリ関数を使用するのに必要なものと先ほどのオブジェクトファイルをつなげて実行形式にするのがリンクと言う作業です これが今までコンパイルと呼んでいた作業です main.exe: main.obj func.obj は main.exe が main.obj と func.obj から出来ているというファイル同士の依存関係を示します bcc32 -emain.exe main.obj func.obj はコマンドです 今まで CPad を使っていて意識していませんでしたが 本来 bcc はコマンドラインで使うコンパイラです このコマンドは実際に Make する時のコマンドと同じです -emain.exe はコンパイルする時のオプションで main.exe という名前の実行ファイルを生成するという意味になります この時 -e と main.exe の間にスペースを入れると動作しません 残りの二つは引数で main.obj と func.obj を用いると言うことを意味します 残りの文も基本的には同じ意味です -c は C のソースからオブジェクトファイルを生成するためのオプションです ちなみに この Makefile は BCC を用いた場合の物で他のコンパイラを使うと少し書き方が変わります 4

先ほど Make は全て手作業で行えるといいましたが Makefile に書いたコマンドを実際にコマンドラインで実行すると Make することが出来ます 今回の場合は bcc32 -c main.c と bcc32 -c func.c を実行した後に bcc32 -emain.exe main.obj func.obj を実行すると Makefile を用いた時と同じ実行ファイルが出来ます 4 自作ヘッダーファイルヘッダーファイルは自分で作ることが出来ます ヘッダーファイルは関数や変数の宣言のみが記載されたもので ファイルの分割を行う際に用います 先ほどの例だと main.c の void func(void); の宣言は普通ヘッダーファイルに書きます それではヘッダーファイルを用いた場合の分割例と Makefile の書き方を示します Makefile を使った分割コンパイルの方法 2( プログラム 10.2-1) ファイル名 :main.c #include func.h func(); return(0); ファイル名 :func.c void func(void){ printf(" 関数が呼び出されました "); ファイル名 :func.h void func(void); 先ほどの例と違う点は main.c で読み込むヘッダーファイルが増えている点と 関数の宣言がヘッダーファイルに移っただけです ヘッダーファイルをダブルクォーテーションで囲んでいますがこれは自作ヘッダーファイルをインクルードする時は普通ダブルクォーテーションで囲みます これは コンパイラが<>で囲んだ場合は標準ライブラリから探し で囲んだ場合は同じフォルダないから探すといった動作をするからです また 見てすぐに自作なのか標準ライブラリにあるのかわかりやすくする意味もあります ヘッダーファイルはこのように関数の宣言をそのまま書いたものです しかし 普通は関数の宣言が 2 重にならないようにプリプロセッサを用いて条件コンパイルさせます 5

多重インクルードを防ぐヘッダーの書き方 ( プログラム 10.2-2) ファイル名 :func.h #ifndef _func #define _func void func(void); #endif //_func 一見意味のないように見えるかもしれませんが こうする事によって同じヘッダーファイルを分割コンパイルする複数のファイル内で宣言されても関数の宣言が 2 重になりません stdio.h 等最初から用意されているヘッダーを見てみれば似たような記述があるはずです 条件コンパイルを忘れているかもしれませんので軽く復習すると意味は 1 行目が _func がマクロ定義されていなければコンパイルすると言う意味で 2 行目は普通のマクロの定義です 最後の行は条件分岐の最後につけるものでした これで このヘッダーファイルが呼び出されたのが 2 回目であれば既に _func がマクロ定義されていてインクルードされません ところで #endif の後ろにコメントがありますが マクロは大抵入れ子になってもインデントしないので どれと対応するのかがわからなくなるためこのように書くことがあります このような短いヘッダーファイルならあまり意味はありませんが 長くなった時には必須とも言えます それでは次に Makefile の書き方を見てみましょう Makefile を使った分割コンパイルの方法 ( プログラム 10.2-3) # makefile for main # target : main.exe all : main.exe main.exe: main.obj func.obj bcc32 -emain.exe main.obj func.obj main.obj: main.c func.h bcc32 -c main.c func.obj: func.c bcc32 -c func.c 先ほどと違うのは main.obj のファイルの依存関係に func.h が追加されているだけです これは書かなくても動きますが 普通はファイルの依存関係を示すために書きます 6

5 統合開発環境分割コンパイルを行う際に Makefile を自動的に作ってくれるソフトがあります 統合環境には有名なもので VisualC++ があります 他にも今まで使ってきたコンパイラを使う BCC Developer があります 別途使い方を示しますので今回のサンプルプログラムをコンパイルして使い方を確かめてください 6 10 章のまとめ大きなプログラムを組む時に分割コンパイルは必須になります 今のうちにある程度なれていた方がいいかもしれません また 変数のスコープの考え方は大変大事な物なので忘れないようにして下さい 確認問題 分割コンパイルを用いたプログラムを作りなさい (Makefile 統合環境両方でやる事 ) 余談とおまけ分割コンパイルとヘッダーファイルを使うと 実際のソースを隠す事が出来ます 実際標準ライブラリ関数はオブジェクトファイルの状態で提供されています その時に関数の仕様を表すのがヘッダーファイルです ヘッダーファイルはソースを読む時の手がかりにもなるのでそういう事を意識して書くようにしましょう また分割コンパイルがなくても出来ますが 関数ラッパという手法があります これは 既にある標準ライブラリ関数に引数を渡す前に自分で処理を挟む事が出来ます 標準ライブラリ関数は渡す引数によっては問題を起こす時もあるので引数のチェックをするべきですが それを関数として作ってライブラリにしておくと 再利用する事が出来て便利です 関数ラッパの詳しい事については自分で調べて見てください 7