お断わり(2014/01/09)
5.節の内容は5階計算機室の環境にそぐわないところがあります。
授業内で環境に合わせた操作を示します。
(ここに書いてある内容通りにしても操作ができるとは限りません)
ここまで、emacs( gedit?)などのテキストエディタを使ってC言語でプログラム記述→gccでコンパイル→gccでリンク→実行、という作業をしてきました。
(単純なプログラムの場合は「コンパイル→リンク」を1度に済ませてましたね。)
この方式では、コンパイルエラーや実行時エラーがでると、テキストエディタに戻って自分でエラー部分を特定せねばなりません。
プログラムが短いうちはこれでもいいのですが、長くなってくると非効率です。
そこで、本講義では統合開発環境 eclipse (エクリプス)を導入します。
これは、エディタ・コンパイラ・デバッガの機能をすべて一つのアプリケーション上で利用できるソフトウェアです。
(Microsoft Windowsでプログラミングしたことのある人なら、VisualStudioのfreeなLinux版と思っておけばまあOKです)
eclipse はもともと java言語でのプログラミング支援を想定して開発が開始されましたが、その使い勝手のよさとプラグイン形式の拡張性の良さゆえに、次々と他の言語へと拡張されました。
そのうちの一つが C/C++ 言語への対応を謳う C Development Tooling (CDT) です。
つまり、皆さんは eclipse + CDT という形での利用となります。
(この授業ではJavaなど他言語におけるeclipse利用法の説明はしません)
なお、eclipse は open software のご多分に漏れず現在も継続にバージョンアップが重ねられていますが、工学システム学類では ver.3.7.2 (Indigo) を使います。
(eclipseの利用概念はどのversionでも大して変わらないし‥)
(と言いつつ新しいversionには色々良い機能が増えてたりします)
(いろいろ使い勝手が変わって説明する方は大変ですが)
Eclipseを使っても、プログラム編集→コンパイル→コンパイル時のエラーデバッグ→リンク→実行時デバッグ→完成という工程自体が変化するわけではありません。
統合開発環境での説明にあたって、まずは作業課程を区分けしてそれぞれに名前をつけておきます。
05.01.01. 2種類のパースペクティブと2種類の実行ファイル
Eclipseの作業画面には、たくさんの小ウィンドウが存在します。
この小ウィンドウ群を、ある作業目的をもってレイアウトしたものを、eclipseではパースペクティブといいます。
プログラムの作成は、C/C++ パースペクティブで行います。
C/C++ パースペクティブ中のエディタウィンドウ上で、C言語のソースを記述していきます。
分割ソースファイルの利用も当然可能です。
プログラム編集中、少しでも変更がある度に文法チェックが自動的に行われ、エラーが見つかればその時点でソースファイルの編集画面上にエラーと思われる箇所を表示してくれます。
(この機能は、一旦もう動いていたプログラムを改造しているときに、とりわけ役に立ちます)
さらに、コンパイルをすると、コンパイル時エラーを指摘してくれます。可能であればソースファイルの編集画面上にエラーと思われる箇所を表示してくれます。
プログラム編集でプログラムが一応完成し、かつコンパイルエラーがなくなると、(実行時デバッグ用の実行ファイルを生成するという)C/C++ パースペクティブの役割が一段落します。
ここで得られる実行ファイルをデバッグ用実行ファイルと呼びます。
続いて必要になるのが、プログラムを実際に実行させてその機能を確認する実行時デバックです。
この作業のために、デバッグ パースペクティブを使います。
デバッグ パースペクティブでは、実行ファイルをデバッガ(gdb)の監視のもとで実行させ、ソースファイルと対応させての実行の追跡や停止、変数の監視などが全てGUIで可能です。
実行時デバックも問題ないことが確認できれば、開発の最終段階に入ります。
C/C++ パースペクティブに戻って、今度は性能重視のコンパイルオプションをつけて再コンパイルを実施し、さっきまでとは別の、性能重視の実行ファイルを生成します。
この性能重視の実行ファイルのことを、リリース用実行ファイルと呼びます。
このリリース用実行ファイルを得ることで、全ての開発は終了します。
出来上がったリリース用実行ファイルは、eclipse抜きでも(コマンドラインから普通に)実行可能です。
(デバッグ用実行ファイルでもコマンドラインから普通に実行は可能なので、性能を追求する必要がない場合は、この最終段階は行う必要はありません)
演習
05-01-01-ex1: デバッグ用実行ファイルとリリース用実行ファイルは、実行して同じ結果を得るという目的では(ごく一部の例外を除いて)同じ結果を出してくれます。ではどうしてもう一度わざわざリリース用実行ファイルを作ろうとするのでしょうか?
05-01-01-ex2: eclipse抜きでコマンドラインでデバッガを動かす方法について調査してみなさい。
05.01.02. プロジェクト
上記のプログラム作成開始からリリース用実行ファイルの生成までを行うひとまとまりの作業(1つの実行ファイルを得るための作業)を総称して、eclipseではプロジェクトと呼びます。
(本授業ではC言語でのプログラム開発に特化してeclipseの説明をしています。一般的なプロジェクトの定義には言及しません)
違う実行ファイルを作成したい場合は、別のプロジェクトを用意することになります。
本授業では、概ね1つの節で1つの実行ファイルを作るようにしているので、節ごとに新しいプロジェクトを用意することになります。
その意味で、本授業全体では、数十のプロジェクトを扱うことになります。
eclipseは同時に複数のプロジェクトを扱うことができるので心配はありません。
演習
05-01-02-ex1: ファイル分割によるプログラミングでは、1つのプロジェクト内に複数のCプログラムソースファイルが存在することになります。その全てのソースファイルを通して、main()関数の記述は何回現れるでしょうか?その理由は?
05-01-02-ex2: 「C言語でのプログラム開発」の指定はeclipseを使っているとき、どこで行っているでしょうか?
(この章の後のほうで出てきます)
05-01-02-ex3: 「C言語でのプログラム開発」以外に用意されているC言語環境でのプロジェクトにはどのようなものがありますか?調べてそれぞれ説明を試みなさい。
(習ってない範囲の知識がいるので通常の履修者には難問です)
05.01.03. ワークスペース
ワークスペースは、複数のプロジェクトをまとめるための単位です。
(これは同時に、複数のプロジェクトをまとめておいて置くためのフォルダの名前でもあります)
通常は、お互いに関連するプロジェクト群をまとめて1つのワークスペースで扱います。
本授業では、プロジェクト間でのソースの共有などを行わないので、1プロジェクト毎に別のワークスペースにしても問題ありませんが、「授業でひとまとめ」という意味で、学期を通して1つのワークスペースを使います。
なお、eclipseでは起動中は同時には1つのワークスペースしか扱えないので注意が必要です。
(例えばプログラミング序論3以外でもeclipseでプログラムを書くような授業があれば、そちらには別のワークスペースを用意して、それぞれの授業開始時に切り替えて使えば問題ありません)
演習
05-01-03-ex1: 各自の「ホーム」ディレクトリ下にワークスペースがすでに存在しているかどうか確認しなさい。存在する場合、それぞれのワークスペースの利用目的を示しなさい。
eclipse上で記述しているプログラムが、他のファイルと連携して動くような場合は、eclipseがソースファイルや実行ファイルをどこに配置しているのかの知識が必要です。
05.02.01. ワークスペース
あるワークスペースで作業をしている間、eclipse上で扱う全てのファイル群は、ワークスペースフォルダの下に配置されます。
(もちろん何にでも例外はあるので、ワークスペースフォルダ以外の場所にあるファイル群でeclipseを動かすこともできます。)
(ただ、本授業ではその例は扱いません。気になる人は2011年度の授業の「外部収容」を参照してみてください)
ワークスペース名(ワークスペースフォルダ)は、デフォルトではホーム直下の workspace という何のひねりもないフォルダです。
本授業では workspace-ic2 というワークスペース名を使うことにしましょう。
(アカウントがs209912345だとしたら /home/s209912345/workspace-ic2 という形ですね)
ワークスペース名とワークスペースフォルダ名は常に一致します。
演習
05-02-01-ex1: 各自の「ホーム」ディレクトリを絶対パスで示してください。
05-02-02-ex2: 各自の「ホーム」ディレクトリの使用量を調べてください。各自で実際に調べる方法を示し、その結果で答えること。
(ログイン時にメッセージとして表示されますが、それだけでは解答とは認めません。)
05.02.02. プロジェクト
プロジェクトを開始しようと思った時点でまずすべきことは、プロジェクト名の指定です。
プロジェクト名はそのまま「プロジェクトフォルダ名」になり、「実行ファイル名」にもなるので、プロジェクト名は、ファイル名やフォルダ名として使える英数文字だけで指定しておくほうが無難です。
(日本語ファイル名やパス名の対応はずいぶん進みましたが、私は未だにあまり信用していません‥)
(プロジェクト名に日本語とか半角スペースとかを織り交ぜるといろいろ難易度が上がるというのが私の経験則なので。特に開発時はその傾向が顕著です。)
プロジェクト名が決まると、eclipseはワークスペースフォルダ直下に、プロジェクト名でフォルダを用意します。以後、このフォルダのことをプロジェクトフォルダと呼びます。
なお、ワークスペースフォルダの下にすでに存在しているフォルダ名を新しいプロジェクト名にすると、そのフォルダ内のファイル一式がプロジェクト内に登録されるので注意してください。
(この辺り、昔とeclipseの挙動が異なります。eclipseの開発者さん達にもいろいろあったのでしょう‥‥)
05.02.03. ソースファイル
本授業では、ある1つのソースファイルは必ずどれか特定のプロジェクトにのみ帰属するようにしています。
本授業では、プロジェクト内では、ソースファイルはプロジェクトフォルダの直下に置くようにしてください。
(プロジェクトフォルダの下にソースフォルダを用意して、その下にソースファイルを置くスタイルもあるのですが、この辺りは好み=文化の差です。)
(どうせ分割コンパイルでも、本授業ではファイルの数はせいぜい10程度ですから、プロジェクトフォルダ直下に全部置いたほうが見やすいと思います)
なお、プロジェクト開始後、外からソースファイルを持ち込むことは可能です。
持ち込みたいソースファイルをプロジェクトフォルダ直下に置いて、「プロジェクト」の上で右クリック→「更新」でプロジェクトツリーに反映されます。
こうして「更新」すると、プロジェクトフォルダ直下に置いたファイルはソースでなくてもすべてプロジェクトに取り込まれるので注意してください。
(プロジェクトツリーに含めたくないようなファイルをプロジェクトフォルダに置くのはeclipseの流儀に反します)
(この「更新」の性質を上手に使うと、本授業のあとのほうで少し楽ができます)
演習
05-02-03-ex1: eclipse(の開発者)側に立って考えると、「更新」は各ファイルの何に基づいてトリガをかけるべきでしょう。
(実はこのことが5階計算機システムでのeclipseの振舞の微妙なところが発生する原因だろう、と私は踏んでます‥)
05.02.04. 実行ファイルと実行時カレントディレクトリ
デバッグ用実行ファイルは、"プロジェクトフォルダ/Debug/プロジェクト名"として生成されます。
(今ここでは「プロジェクトフォルダ」を「プロジェクト名」と同じにしていることに注意)
リリース用実行ファイルは、"プロジェクトフォルダ/Release/プロジェクト名"として生成されます。
デバッグ用実行ファイル、リリース用実行ファイルがeclipseから実行されるとき、プロジェクトフォルダをカレントフォルダとして実行されます。
eclipse上でデバッグや実行をするとき、プログラム内部からファイル等を参照する場合はこのことに注意してください。
手動で実行する場合も、はじめのうちはプロジェクトフォルダに移動してから実行するほうが無難でしょう。
演習
05-02-04-ex1: なぜeclipseは実行ファイルがあるディレクトリをカレントディレクトリにして実行しようとしないのでしょう?これには尤もな理由があります。その理由を述べなさい。
(ヒントは、eclipseは開発者が DEBUG と RELEASE の2段階のプロセスを踏むだろうと想定していることです)
05.02.05. その他
ワークスペースフォルダ直下に何らかのファイルを置いてもeclipseは関知しません。
プロジェクトフォルダの兄弟に別のフォルダを作ってもeclipseは関知しません。ただし、そのフォルダ名は以後このワークスペース内ではプロジェクト名として利用できなくなります。
(このことを上手に使うと、eclipseに見えない形で「倉庫」ディレクトリを用意しておけたりします)
05.03.01. eclipseの起動とワークスペースの設定
Ubuntu Desktopのメニューから eclipse を探して(アプリケーション→プログラミング)起動しましょう。
もちろんコマンドラインから eclipse とタイプして起動しても構いません。
ワークスペースをどうするか尋ねられるはずなので、workspace-ip3としてください。
(もし尋ねられなかったら、起動後、メニュー:ファイル→ワークスペースの切り替え、で切り替えてください)
通常は「ようこそ」タブが表示されるので、そのタブを消すか、そのウィンドウ右端の辺りにある「ワークベンチ」アイコンをクリックしてください。
すると、eclipseの基本である(私たちには用のない)java パースペクティブになります。
05.03.02. eclipseの初期設定
パースペクティブは自由にレイアウトを変えられますが、もし元のデフォルト配置に戻したいときは、メニュー:ウィンドウ→パースペクティブのリセット を実行します。
(パースペクティブのリセットは小ウィンドウ群の配置を直すだけなので、内容的には一切変化はおきません。)
ここではCプログラミングに纏わる全体的な設定を2つしておきましょう。
エディタに関して、行番号表示します。
(これはテキストエディタに一般的に見られる機能ですね。)
また、Cプログラミング時に、関数折りたたみ機能を利用可能にします。
(こちらは「C言語記述=Cプログラム編集」時にのみ利用できる機能ですね。)
05-03-02-A | 行番号の表示 |
1 | メニュー:ウィンドウ→設定 |
2 | <設定>
(以後<◎△◇>とあるときは、◎△◇というWindowがポップアップしている状態を指すものとします。) (左):一般[展開]→エディター[展開]→テキストエディターを選択 (右):テキストエディター→行番号の表示→チェック→OK |
05-03-02-B | 関数の折りたたみ機能 |
1 | メニュー:ウィンドウ→設定 |
2 | <設定>
(左):C/C++[展開]→エディター[展開]→折りたたみ (右):折りたたみ→新規エディターを開くときに折りたたみを使用可能にする→OK |
eclipseの終了は特に気を遣う必然性はありませんが、作業内容の記録等に時間がかかることがあるので注意してください。
作法的には「メニュー:ファイル→終了」が一番上品です。
05.04.01. プロジェクト概要の決定
まずは直接プログラムを書いてみる形式でプロジェクトを立ててみましょう。
プロジェクト名をまず考えます。
本授業では、「2桁の章番号-2桁の節番号-名称」というルールにしておきます。
(ようやく節見出しが 5.4. ではなく 05.04. になっている理由がここで明らかに‥)
(こういうルールのことを、ネーミングスキーマと言います。)
(ネーミングスキーマは大規模なプログラミングをしていく上で将来『自分が』するであろう間違いやトラブルを回避するための技術です)
(従う必要はありません。が、従っておいたほうが後で生き延びる確率があがるのではないかと)
プロジェクト名:05-04-HelloEclipse
ソースファイル名:05-04-HelloEclipse-Main.c
05.04.02. 新規プロジェクトの登録
05-04-02-A | 新規プロジェクトの登録 |
1 | a. メニュー:ファイル→新規→プロジェクト、<新規プロジェクト>C/C++のツリーを展開して C プロジェクト→「次へ」
b. プロジェクトビューの何もないところで右クリック→新規→C プロジェクト→「次へ」 |
2 | <C プロジェクト>
プロジェクト名:05-04-HelloEclipse (「デフォルト・ロケーションの使用」にチェックが入っていることを確認してください) (グレイアウトされているロケーションが .../workspace-ip3/05-04-HelloEclipse になっていくはずです) プロジェクト・タイプ:実行可能[展開]→空のプロジェクト (★要確認) ツールチェーン:Linux GCC →上記が済めば「完了」 (関連つけられたパースペクティブを開きますか?と聞かれたらそのまま「はい」) |
作業が済むと、左側のプロジェクトビューに「05-04-HelloEclipse」というプロジェクトが増えてるはずです。
これによって、二つの設定(DebugとRelease)を伴うプロジェクトが用意されました。
先頭の三角アイコンをクリックしてプロジェクトツリーを展開表示しておきましょう。
05.04.03. 新規ソースファイルの作成
05-04-03-A | ソースファイルの登録 |
1 | a. プロジェクトビューで05-04-HelloEclipseを選択後、メニュー:ファイル→新規→ソース・ファイル
b. プロジェクトビューで05-04-HelloEclipseを右クリック→新規→ソース・ファイル |
2 | <新規ソース・ファイル>
ソース・ファイル: 05-04-HelloEclipse.c →完了 |
プロジェクトツリーに05-04-HelloEclipse.cが登録されると共に、中央のエディタで05-04-HelloEclipse.cがオープンします。
(Eclipseがすでに先頭にコメントを書いて用意していると思います)
(こういうのも、ある意味、文化の一部ですね)
あとは、中央のエディタでC言語プログラムソースを記述していくだけです。
Ctrl-Sで時々ソースを保存するようにしましょう。
では、さっそく下のプログラムを入力してみましょう。
Eclipseではとても大事なキーボードショートカットがあります。
Ctrl+z : 直前の動作を取り消す。(Undo)
Ctrl+y : 直前の動作をもう一度行う。(Redo)
Alt+/ : 今の時点で「正しい」入力候補を提示する。(Content Assist)
Ctrl+s : ファイルの保存
特に3番目は、Eclipse利用の3大メリットの1つです。とりあえず途中でバンバンAlt+/してみてください。
(例えば、"#inc"ぐらい入力してAlt+/すると‥)
(例えば、続いて、stdio.hと入力しようとして"std"ぐらいでAlt+/すると‥)
入力中から、構文上不具合が見つかると、ソースの左側にアイコンで間違っていそうなところを指摘してくれます。
これがEclipse利用の3大メリットの2つめ、静的な構文チェックです。
(あと1つは、オンラインデバッグでのトラッカですかねぇ。)
(ちなみにこの「3大機能」は私が勝手に呼んでるだけなのでGoogle先生に聞いたりしないように。)
下のサンプルプログラムは「コピー&ペースト」しないでキーボードで打ち込むこと。
(コピー&ペーストではeclipseの様々なアシスト機能のありがたさがわからないでしょうから。)
Eclipseでは整形も司ってくれますので、改行する度にインデンテーションが自動的に行われます。
(ある領域をまとめて「インデンテーションし直してもらう」ということも実は可能ですが。)
(インデンテーションのスタイルを変更することもほんとは可能です。)
(インデンテーションのスタイルにすら流派があります。文化ですねぇ。華道や茶道と同じ世界ですよ。)
打ち込み時にはAlt+/を多用してみること。
05-04-HelloEclipse.c |
#include <stdio.h> int main(int argc, char **argv){ int i = 2; int j = 4; printf("Hello, Eclipse.\n"); i = i * i; printf("Second variable = %d\n", j); printf("First variable = %d\n", i); return 0; } |
(eclipseのcompletionではmain関数の第2引数は *argv[] ではなく **argv とされます。どちらもC言語の文法としては全く正しいので、どちらで書くかは信仰の問題です。私は *argv[] 派ですが、ここだけは eclipse の completion 機能に敬意を表して **argv にしておきました。)
入力中、まめに Ctrl+s で保存する習慣を身につけましょう。
(保存を頻繁に行うことでトラブルから生き延びれる可能性が上がります)
演習
05-04-03-ex1: "char **argv" と記述した場合のargv変数の型を説明しなさい。
05-04-03-ex2: "char *argv[]" と記述した場合のargv変数の型を説明しなさい。
05-04-03-ex3: "char **argv" と "char *argv[]" は等価とみなせます。なぜそうなるのか丁寧に説明しなさい。
05.04.04. デバッグ用実行ファイルの作成
構文エラーはもうなくなりましたか?
以下に、プログラミングに便利なeclipseの機能を紹介しておきます。
アウトライン
右側のアウトラインビューに並んでいる構成要素をクリックすると、エディタ内で該当部分の先頭に飛びます。
関数折りたたみ表示
関数の最初の行に小さく「-」の表示が出ています。
これをクリックすると、関数ボディ部が全部折り畳まれて表示されるようになります。
ソースが長くなってきたときに、この機能は威力を発揮します。
リファクタリング
単純に言えば、変数名(関数名でも可能)の一括変換です。
例えば、上記のソースで、エディタ内で変数 i を右クリックして リファクタリング→名前変更 とし、ポップアップしてくる小さいウィンドウで val1 と入力すると、ソース中の変数 i に該当する部分が全て置換されます。
同じ要領で、変数 j を変数 val2 に変更してください。
適切な変数名、関数名をつけることはプログラミングをしていく上で重要な作法なので、この機能も重宝することでしょう。
静的に見つけられる文法誤りはもうなくなったことでしょうか。
エラーがなくなれば、いよいよデバッグ用実行ファイルの作成に臨みます。
本来であれば、デバッグ用実行ファイルの作成にあたっては、コンパイラとリンカにこちらの希望を色々伝えるべきです。
しかし、ここで利用しているeclipseでは、一般的な(初歩的な)希望はすでに記入済なので、単にコンパイル・実行するだけで済みます。
(そのため、逆に中で何が行われるかわかりにくくなってブラックボックス化が進むわけですね。)
(だからこそ授業では前の04.章があったわけで。)
eclipseでは、ソースファイル群から一つの目的を実行することを「ビルド」するといいます。ここでは、Cソースファイル群から1つの実行ファイルをコンパイル・リンクで作ることが相当します。
ソースファイル群はプロジェクト単位で保管されているので、結局「あるプロジェクトをビルド」することになります。
ビルドの仕方にはデバッグ用の他、あとではリリース用というのが出てきます。
その意味で、これから行う作業は、より細かく説明するなら「あるプロジェクトをデバッグ用にビルド」して実行ファイルを得る、ということになります。
なお、デバッグ用実行ファイルの作成の前に、すべてのファイルを保存しておくように。
05-04-04-A | 「デバッグ用実行ファイルの作成」 |
1 | a.メニュー:プロジェクト→すべてビルド
b.メニュー:プロジェクト→プロジェクトのビルド c.メニュー:ハンマー型のアイコン(=プロジェクトのビルド) |
実行すると、エラーがあればソースにあちこち表示がされ、同時に下側の「問題」ペインに理由が列記されます。
「コンソール」ペインのほうを確認してみましょう。
こちらにeclipseが内部で実際には何をしたかが出力されています。
演習
05-04-04-ex1: コンソールペインの内容を1行ずつ説明しなさい。
(makeコマンドの行は飛ばして構いません。)
05-04-04-ex2: 作成された実行ファイルの場所がどこか、パスとファイル名で示しなさい。
05-04-04-ex3: コマンドラインでその実行ファイルを実際に実行してみなさい。
05.04.05. 実行時デバッグの設定
本節では実行時デバッグの方法について学習します。
(このような短いプログラムではあまり実行時デバッグの値打ちがないですが‥)
eclipseのあるプロジェクト(より正確にはある実行ファイル)について、新しいデバッグ実行を開始するときは、初回のみ「デバッグの構成」(Debug Configurations)を行う必要があります。
(同じ設定でまたデバッグ実行を行う2回目以降では、「デバッグの構成」を改めて行う必要はありません)
05-04-05-A | 「デバッグの構成」 |
1 | プロジェクトビューで実行時デバッグをしようと思っているプロジェクトが選択されていることを確認
(今はプロジェクトが1つしかないので外しようがないですが、だんだんプロジェクトが増えてくると意外にこれを忘れたりします‥経験談) |
2 | a. メニュー:実行→デバッグの構成
b. 上段のアイコンのうち虫の形をしたアイコン(デバッグアイコン)の右横の小さい黒逆三角形をクリック→デバッグの構成をクリック |
3 | <デバッグ構成>
(左):C/C++ Applicationをダブルクリック (eclipseに、今ここで新しくデバッグが構成可能できそうなプロジェクトを探させます) (左):C/C++ Applicationの1階層下に現在のプロジェクト名と同じ名前の構成要素(デバッグ構成)が新しく現れるのでそれをクリック(ここでは05-04-HelloEclipse Debugですね) (右):名前:これはこのデバッグ構成につける名前です。暫定的に"プロジェクト名 Debug"というのが入っていますが、できれば自分なりの名前にしておきましょう。ここでは 05-04-HelloEclipse Debug Go としておきます。 (C/C++ アプリケーション:の欄が空白であれば、まだデバッグ用実行ファイルが用意できていません。(左)で該当デバッグ構成を右クリック→削除して前節からやり直し。) |
4 | <デバッグ構成>
(右):全ての設定が終わったら、「適用」をクリックして設定を保存します。 |
5 | <デバッグ構成>
(右):全ての設定が終わったので、右下の「デバッグ」をクリックして実行時デバッグを開始します。 (eclipseでは複数のデバッグを同時に走らせることができますが、最初のうちは混乱のもとなのでそうしないようにしておきましょう) (「デバッグ」をクリックすると、このデバッグ構成に基づく1つのデバッグ実行インスタンスが開始されます) |
いよいよデバッグに移行するので、eclipseもデバッグパースペクティブに移行です。
デバッグパースペクティブに移行する段になると、「パースペクティブ切り替えの確認」ウィンドウが現れるかもしれません。
毎回「はい」を押してもらってもよいですが、面倒ならここで「常にこの設定を使用する」のチェックをオンにしてしまってもよいでしょう。
ビューやエディタなどのペイン群のレイアウトが変わって、ウィンドウのタイトルに「デバッグ」が入ったり、右上のパースペクティブアイコンの右の表示が「デバッグ」になっていることで、デバッグパースペクティブに切り替わったことが確認できます。
05.04.06. 実行時デバッグ
実行時デバッグを開始してみると、eclipseでは常にmain()関数の1行目で一時停止した状態になります。
(エディタの該当行に小さい矢印が表示されてその行に色がついているはず)
(細かいですが、矢印の行はまだ実行してない状態です)
また、デバッグペインでは「05-04-HelloEclipse Debug Go」(05.04.05.節でつけたデバッグ構成の名前)で始まるデバッグツリーが表示されているはずです。
(eclipseでは複数のデバッグを同時に走らせることができますが、最初のうちは混乱のもとなので、デバッグペインに複数のデバッグ(ツリー)が並ばないようにしておきましょう)
実行時デバッグの方法は大きく分けて2通りあります。
(1) ステップ実行:
ソースプログラムを1行ずつ実行させて行きます。何が起きているのか正確に知ることができますが、プログラムが長くなってくると実行にとても時間がかかります。
(2) 通し実行:
コマンドラインでの実行と同じように、プログラム実行をさせます。ただし、ユーザが指定した場所や条件に合致したときは、そこで一時停止させます。ある程度プログラムの動作が見えているときに便利な方法です。
ステップ実行と通し実行は随時切り替えられます。例えば、ある行にブレークポイント(一時停止指定)を設定してそこまでは通し実行させ、一時停止した後はステップ実行する、ということが可能です。
演習
05-04-06-ex1: デバッグが複数実行できるというeclipseの仕様が便利と思える状況を考えて説明してみなさい。
(ほとんどの履修生はこのありがたみを実感することなく卒業してしまうでしょうけどね)
05.04.07. ステップ実行(ステップイン、ステップオーバー)
まずはステップ実行をしてみましょう。
ステップ実行は進め方によってさらに2種類に分かれます。
ステップイン :
プログラムを1行進めます。その1行がユーザ定義関数呼び出しであれば、その関数の中に移ります。
ステップオーバー :
プログラムを1行進めます。その1行がユーザ定義関数呼び出しであれば、その関数関数呼び出しを通し実行して、そのユーザ定義関数呼び出しが終えて次の行(の実行前)の状態になります。
要するに、関数の中身まで確認する気があればステップイン、その関数の動作にはもう興味がなく、内部動作をいまさら確認する気がないのであればステップオーバー、ということです。
はじめのうちは全てステップインでいいでしょう。
05-04-07-A | ステップインのさせ方 |
1 | a. メニュー:実行→ステップイン
b. F5 c. 上段2段目のアイコン並びのうち、黒い点2つの間に矢印が割って入っている(ステップイン)アイコンをクリック (eclipseではアイコンの上にマウスカーソルをそっと置いておくと、1秒ぐらいのフーバーでそのアイコンの説明を表示してくれます) |
05-04-07-B | ステップオーバーのさせ方 |
1 | a. メニュー:実行→ステップオーバー
b. F6 c. 上段2段目のアイコン並びのうち、黒い点1つの右に矢印が降りてきている(ステップオーバー)アイコンをクリック |
ステップインであれステップオーバーであれ、進めていくと、エディタウィンドウの矢印が進んでいき、変数に変更があったときには変数ペインの該当変数がハイライトされてそのことを知らせてくれます。
(2014/1/22現在の5階計算機システムのeclipseでは、ステップ実行時に時々標準出力がタイムリーに表示されないことがあるようです。原因の予想はついているのですが、対処が難しそうなので、printf()の連発によるdebugは避けるか、あとの05.08.節のアドバイスに従って下さい)
(おそらくシステム間の時計が微妙に不整合していることが原因ではないかと予想していますが、調査依頼中です)
05.04.08. デバッグの再実行
ステップインやステップオーバーで最後まで進むと、デバッグビューのデバッグツリーの最上位階層に「<終了しました>」と表示されます。
そうなったら、今回のデバッグ実行は終了です。
直前に行っていたデバッグをもう一度実行するのは簡単です。
以下のいずれかで、前回と同じ構成のデバッグを開始することができます。
Eclipseに本当に慣れるまでは再実行前に先ほど終了したデバッグ実行を削除しておきましょう。
05-04-08-A | デバッグの再実行(前回のデバッグ構成と同じデバッグ実行)(その前に削除) |
1 | 前回の「デバッグ実行」の削除
(デバッグペインの中が空になるように掃除します) a. (メニュー:実行→終了を念のため確認→)メニュー:編集→削除 b. (デバッグペインのタイトルバーの停止アイコンをクリックして終了を確認→)二重×アイコンをクリック (停止状態にしないと削除ができません) (成功すればデバッグペインの中が空白になります) |
2 | デバッグ再実行
a. メニュー:実行→デバッグ b. F11 c. 虫の形をしたデバッグアイコンをクリック d. 虫の形をしたデバッグアイコンの右横の黒逆三角形をクリック→05-04-HelloEclipse Debug Goをクリック |
これによってまた05.04.06.節の状態になります。
【注意】前のデバッグ実行が終了・削除してない状態で上記の操作を行うと、前のデバッグ実行を一時停止したままの状態で、別の(2つめの)デバッグ実行を開始することになってしまいますので、注意してください。
(デバッグペインでデバッグ構成が2つになるので気がつくと思います。)
(慣れてくるとこれはこれで使い途があるのですが、今はややこしいので、05.04.10.節も参照して望まないほうのデバッグは終了して削除しておきましょう)
05.04.09. 通し実行(Run, Break point)
今度は通し実行をやってみましょう。
まずは、何も考えないで通し実行を行います。
(でもその前に、デバッグ構成がまだ残ってるのなら停止して削除しておきましょう)
通し実行(eclipseでは「再開」とも言います)(下記のどれでも同じことです)
a. メニュー:実行→実行
b. 虫の形をしたデバッグアイコンの隣にある再生ボタンをクリック
目にも止まらない速さで実行され、コンソールペインに標準出力が表示されます。
(何度もやってみたければ、削除→F11→F8→削除→F11→F8→削除→F11→F8→削除‥)
次はブレークポイントを設置してみましょう。
1つ目のprintf()の実行直前で止まってもらうことを考えます。
ブレークポイントの設置(下記のどれでも同じです)
a. エディタペインの該当行をクリックしてから、メニュー:実行→ブレークポイントの切り替え
b. エディタペインの該当行の左端をダブルクリック
成功すればエディタの行の左に小さい丸が表示されます。
また、ブレークポイントペインにも表示されます。
デバッグ開始状態(main()関数先頭行での一時停止状態)で、通し実行(F8)を始めてみましょう。
すると、今度はその行で一時停止します。
ここでさらに再開(F8)すると、今度は最後まで実行が進んで終了します。
(何度もやってみたければ、削除→F11→F8→削除→F11→F8→削除→F11→F8→削除‥)
一時停止した状態で、ステップインやステップオーバーしても構いませんし、ステップ実行したあと再開しても構いません。
なお、ブレークポイントの外し方には2通りあります。
ブレークポイントの恒久解除:ブレークポイントの設置と同じことをもう一度すればOKです。
ブレークポイントの一時解除:ブレークポイントペインで、該当するブレークポイントのチェックボックスのチェックを外します。
05.04.10. C/C++パースペクティブに戻る前に - デバッグ実行の終了 -
デバッグ実行による動作確認が済んだら、今作業しているデバッグ構成を終了して削除しておきましょう。
(立つ鳥後を濁さず。整理整頓。いずれも将来の自分を苦しめないためです)
05-04-10-A | デバッグの終了 |
1 | 終わらせようと思うデバッグ構成を選択
(デバッグペインでまだ「<終了しました>」が表示されてないでしょうね) |
2 | a. メニュー:実行→終了
b. デバッグペインのタイトルバー右側の赤い四角ボタン(終了アイコン)をクリック |
3 | 選んだデバッグ構成が「<終了しました>」になっているのを確認 |
4 | a. 当該デバッグ構成をクリックした後、上段2段目左端の×が二重のアイコン(「終了したすべての起動を除去」アイコン)をクリック
b. 当該デバッグ構成をクリックした後、メニュー:編集→削除 |
5 | デバッグペインから当該デバッグ構成が削除されたことを確認 |
eclipseでは、デバッグを終わらせないままでデバッグパースペクティブからC/C++パースペクティブに切り替えたりそこから戻ってきたりできますが、この授業では、「デバッグパースペクティブからC/C++パースペクティブに戻るときは必ず全部のデバッグ実行を終了・削除する」ことを習慣付けておいてください。
(そうしないと、次にC/C++パースペクティブからデバッグパースペクティブに戻ってきたときに、前回立ち去った時の状況をあなた自身の頭の中で再構成する必要が出てきます。Eclipse+CDT側にとっては簡単なことでも、慣れてない皆さんの頭のほうがついていかないでしょう‥)
05.04.11. パースペクティブの切り替え
デバッグパースペクティブからC/C++パースペクティブに戻りましょう。
05-04-11-A | パースペクティブの切り替え |
1 | a. メニュー:ウィンドウ→パースペクティブを開く→C/C++
b. eclipseのツールバー右側の田んぼみたいなアイコン(パースペクティブ切り替えアイコン)をクリック→C/C++をクリック |
デバッグパースペクティブにも同じ要領で戻ってこられます。
戻るときには「デバッグ」を選ぶことになります。
05.04.12. デバッグ用実行ファイルの動作確認
実行時デバッグも済んだ今の時点で、(デバッグ用)実行ファイルを使うことが出来ます。
(デバッグ実行ではなく、単に実行する、という意味ですね)
作成したデバッグ用実行ファイルを実行するには2通りの方法があります。
1つめの方法は eclipse上での実行です。
05-04-12-A | 実行ファイルの実行 |
1 | C/C++パースペクティブにいることを確認 |
2 | a. メニュー→実行→実行 (Ctrl+F11)
b. ツールバーのアイコンのうち再生ボタンみたいなのの右隣の黒逆三角形をクリック→05-04-HelloEclipse Debug Goをクリック c. ツールバーのアイコンのうち再生ボタンみたいなのをクリック(虫アイコンの右のアイコン) |
この場合、パースペクティブの切り替えは起こらず、中央下のコンソールペインにプログラムからの標準出力結果が表示されるだけです。
すぐに再度実行したい場合は、05-04-12-AのStep2でa.ないしc.を実行してください。
(再生ボタンアイコンは、直近に行った「実行(デバッグではない)」を再度行うアイコンです。)
2つめの方法はコマンドラインでの実行です。
以下はeclipseから離れて、ターミナルでの作業となります。
$ cd $ cd workspace-ip3/05-04-HelloEclipse $ ls $ ls Debug $ ./Debug/05-04-HelloEclipse
演習
05-04-12-ex1: 端末ウィンドウ内のbashで「cd」するとどこに移動するのでしょうか。
05.04.13. リリース用実行ファイルの生成
ここからは、リリース用実行ファイルの生成を目指します。
(デバッグ用実行ファイルにはいろいろな仕掛けがしてあるので、最大速度がとても出しにくい構造になっています。)
(陸上競技で例えて言うなら、デバッグは競技者に心拍計測装置とか発汗計測装置をつけながら走ってもらっているようなものです。もちろん走れますが、全力で走ってもらうためにはすべての装置を外してあげるべきでしょう。)
(ちなみにgccのデバッグモードのパフォーマンス低下は実は大したことありませんが、VisualStudioのデバッグモードはひどい状態です。gccの計測装置が腕時計型ぐらいだとしたら、Visual Studioの計測装置は鉛バッテリ入りの計測装置をてんこ盛りしてリュックで背負わせているような状態?まあその分、解析は微に入り細に渡ってできるわけですが‥)
(どちらのスタイルが良いと思うかは、結局のところデバッグに何を期待するかで決まります。)
リリース用実行ファイルを作るためには、実行ファイル作成の方針を、従来のデバッグ向けからパフォーマンス重視に切り替えなくてはいけません。
違う種類の実行ファイルの作成を目標に掲げるので、これまでとは異なる「ビルド」をすることになります。
05.04.05.節でデバッグ用ビルド設定をしていたのですが、そのときにセットでリリース用ビルド設定も行われています。
(eclipseを構築している人達は賢いので、皆さんがスピードアップを望むときに、だいたい何をしたらいいか皆さんに聞くまでもなかろうと‥)
今度は、そのリリース用ビルド設定を使うことになります。
05-04-13-A | 「アクティブビルドの変更」 |
1 | a. プロジェクトビューで該当するプロジェクトツリーの最上位ノード(ここでは05-04-HelloEclipse)を選択、メニュー:プロジェクト→構成のビルド→アクティブにする→Release
b. プロジェクトビューで該当するプロジェクトツリーの最上位ノード(ここでは05-04-HelloEclipse)を右クリック→構成のビルド→アクティブにする→Release c. メニュー:ハンマー型のアイコンの右の小さいボタン→Rlease |
切り替えが済んだら、この新しい(リリース用)設定のもとで、「デバッグ用ビルド」で行っていたことと同じ作業をしていきます。
(現在の5階計算機室のEclipseではアクティブビルドを変更したら即時でビルドするようですがまあ一応。)
まずは、リリース用実行ファイルを作ります(ビルドします)。
(05.04.04節と同じ手順で。ただし今は、ビルド用設定が「デバッグ用」ではなく「リリース用」というところが異っています。)
(ビルドが済むと、コンソール中で作業の様子が表示され、同時に、プロジェクトビューの2階層目に、Debugと並んでReleaseというノードが増えているはずです。)
続いて、「(リリース)実行構成」をします。
(05.04.05節とほぼ同じ手順で。ただし、05-04-05-A:Step2-bでは対象となるアイコンは「虫の形アイコン」ではなくその隣の「再生アイコン」になります。または、「デバッグ構成」とあったところは適宜「実行構成」に読み替えます)
(実は、リリース実行をeclipse上で行わない予定でターミナル上でのみの実行を考えているのなら、「(リリース)実行構成を飛ばしても構いません)
以上のようにして準備が整ったら、やっと実行できます。
(05.04.12節と同じ手順で。)
リリース用実行ファイルは、実行時デバッグができないこと、実行ファイルが格納されているディレクトリがデバッグ用とは異なることを除けば、使い方は同じです。
(05.04.06-11のようなデバッグは当然出来ませんけどね)
デバッグ用実行ファイル同様、リリース用実行ファイルも、eclipseからの実行、コマンドラインからの実行、どちらも可能です。
コマンドライン実行の場合、05.04.12.節に示したシェルコマンド中の「Debug」を「Release」に読み替えてください。
$ cd $ cd workspace-ip3/05-04-HelloEclipse $ ls $ ./Release/05-04-HelloEclipse
残念ながらこのような短いプログラムでは速度差を体感することはできませんが、身軽になっていることはファイルサイズから想像できそうです。
$ ./Debug/05-04-HelloEclipse $ ./Release/05-04-HelloEclipse $ ls -l ./Debug/05-04-HelloEclipse ./Release/05-04-HelloEclipse
演習
05-04-13-ex1: デバッグ用実行ファイルとリリース用実行ファイルでは、動的ライブラリに差があるでしょうか?本節で作成した実行ファイルを対象に確認しなさい。
05-04-13-ex2: リリース用実行ファイル作成のためのコンパイルオプションは、デバッグのためのオプションを外すだけではないことが普通です。
履修者が現在用いているeclipse環境において、デバッグ用、リリース用でそれぞれどのようなオプションが使われているかを調べ、その意味を1つずつ解説しなさい。(不明なものは不明なままでよいが、その場合は調べ方を明記すること。)
05-04-13-ex3: デバッグ用実行ファイルとリリース用実行ファイルのファイルサイズを調べなさい。ファイルの大きさに差がある理由について、どちらがなぜ大きいか説明を試みなさい。
05.05.01. プロジェクトの概要
01.02.節のプログラムを、eclipseの新しいプロジェクトとして取り込む方法についてここで説明します。
プロジェクト名:01-02-HelloESYS-Better
ソースファイル:01-02-HelloESYS-Better.c
05.05.02. 新規プロジェクトの登録
このワークスペース(workspace-ip3)ではこれが2つめののプロジェクトになることでしょう。
05-04-02-Aの要領で作成してください。
作業が済むと、プロジェクトビューに「01-02-HelloESYS-Better」「05-04-HelloEclipse」と2つプロジェクトが並ぶはずです。
01-02-HelloESYS-Betterを選択し、先頭の三角アイコンをクリックしてプロジェクトツリーを展開表示しておきましょう。
05.05.03. 外からのソースファイルの取り込みとデバッグ・実行
プロジェクトフォルダ(~/workspace-ip3/01-02-HelloESYS)に、取り込みたいソースファイルをコピーします。
ここでは、01-02-HelloESYS-Better.cをこのファイル名のまま保存してください。
用意できましたか?では、eclipseの「リフレッシュ」を使ってソースファイルをプロジェクトに登録します。
05-05-03-A | プロジェクトフォルダ内に新しく用意したファイルの登録 |
1 | a. メニュー:ファイル→リフレッシュ
b. F5 c. プロジェクトビューの01-02-HelloESYS-Betterを右クリック→リフレッシュ |
成功すると、01-02-HelloESYS-Betterのプロジェクトツリーに01-02-HelloESYS-Better.cが追加されます。
05.04.04.節の要領でデバッグ用実行ファイルを作成してみましょう。
実行時デバッグをする場合は05.04.05.節の要領で実行時デバッグを構成し、デバッグパースペクティブに移って実行時デバッグを開始します。
リリース用実行ファイルを作成する場合は05.04.12.節の要領でビルド方法を変更してビルドしてください。
<-- ex1:2014, ex2:2014 -->
演習
05-05-03-ex1: 本節のプログラムソースのprintf()ごとにfflush()を追記して、コンソールでprintf()の出力が毎回確実に出るように改変しなさい。
05-05-03-ex2: 上記ex1のfflush()の追記の時、printf()の右に追記するのと、printf()の下に追記した場合のstep in実行時の振舞の挙動の差について説明しなさい。
05.06.01. プロジェクトの概要
04.02.節の分割ソースファイル(複数)によって記述したプログラムを、eclipseの新しいプロジェクトとして取り込む方法についてここで説明します。
プロジェクト名:04-02-SC
ソースファイル:
04-02-SC.h,
04-02-SC-BasicFunctions.c,
04-02-SC-ExtraFunctions.c,
04-02-SC-Main.c
05.06.02. 新規プロジェクトの登録
このワークスペース(workspace-ip3)では3つめののプロジェクトになります。
前節で決めたプロジェクト名で新しいプロジェクトを、05-04-02-Aの要領で作成してください。
作業が済むと、プロジェクトビューに「01-02-HelloESYS-Better」「04-02-SC」「05-04-HelloEclipse」と3つプロジェクトが並ぶはずです。
04-02-SCを選択し、先頭のアイコンをクリックしてプロジェクトツリーを展開表示しておきましょう。
05.06.03. 外からの分割ソースファイル群の取り込みとデバッグ・実行
プロジェクトフォルダ(~/workspace-ip3/04-02-SC)に、取り込みたいソースファイル群をコピーします。
ここでは、
04-02-SC.h,
04-02-SC-BasicFunctions.c,
04-02-SC-ExtraFunctions.c,
04-02-SC-Main.c
を用意します。
05.05.03.節の作業を思い出して、コピーしたファイル群をプロジェクトツリーに一括登録してしまいましょう。
成功すると、04-02-SCのプロジェクトツリーに上記4ファイルが追加されます。
そのまますぐに、デバッグ用実行ファイルもビルドしましょう。
(eclipseは分割ソースファイルの中を調べて、どこにmain()関数があるかを把握してコンパイル・リンクまで自動で行ってくれます)
(コンソールペインに、たくさん表示されますね。各ソースのコンパイルと、最後のリンク作業までがそれぞれ記述されています。)
実行時デバッグをする場合は05.04.05.節の要領で実行時デバッグを構成し、デバッグパースペクティブに移って実行時デバッグを開始します。
実行時デバッグの間、複数のソースファイルに跨って実行が続きますが、表示するソースファイルの切り替えは全てeclipseが自動でしてくれるのでユーザが気にする必要はありません。
ユーザ定義ライブラリ関数の呼び出しがこのプログラムの中にはあるので、ステップインとステップオーバーの違いを確認してください。
なお、実行時デバッグ中、fgets()関数のところでプログラムは(当然ですが)一時停止になって、標準入力からのデータを待ちます。
コンソールペインで1行分の式を入力してください。(そのあとまた指定した形でデバッグ実行が続行されます。)
リリース用実行ファイルを作成する場合は05.04.12.節の要領でビルド方法を変更してビルドしてください。
05.07.01. プロジェクトの概要
02.02.節の「ファイルを開くプログラム」を、eclipseの新しいプロジェクトとして取り込んで実行する方法についてここで説明します。
プロジェクト名:02-02-OpenFile-Full
ソースファイル:02-02-OpenFile-Full.c
05.07.02. 新規プロジェクトの登録
要領は05.05.02.節の05-05-02-Aとほぼ同じです。
プロジェクト名だけはこちらでは 02-02-OpenFile-Full としてください。
05.07.03. 外からのソースファイルの取り込み
要領は05.05.03.節と同じです。
(プロジェクトフォルダ名やファイル名は本節の内容に合わせて読み替えること!)
05.07.04. 起動時引数(オプション)を伴う実行時デバッグの構成
実行時デバッグをする場合は05.04.05.節の要領で実行時デバッグを構成し、デバッグパースペクティブに移って実行時デバッグを開始します。
デバッグ構成の名前は02-02-OpenFile-Full Debugとしておきます。
実際にこれをやってみると、(これまた当然ですが)ファイル指定が起動時に引数(オプション)として渡されてないので、実行はユーザプログラム中で用意していたトラップに引っかかって終了してしまいます。
そこで、起動時引数がついた別のデバッグ構成を作ってみましょう。
05-07-04-A | 引数を伴う「構成およびデバッグ」 |
1 | プロジェクトビューで実行時デバッグをしようと思っているプロジェクト(02-02-OpenFile-Full)が選択されていることを確認 |
2 | a. メニュー:実行→デバッグの構成
b. 上段のアイコンのうち虫の形をしたアイコン(デバッグアイコン)の右横の小さい黒逆三角形をクリック→デバッグの構成をクリック |
3 | <デバッグ構成>
(左):C/C++ Applicationをダブルクリック (eclipseに、今ここで新しくデバッグが構成可能できそうなプロジェクトを探させます) |
4 | <デバッグ構成>
(左):C/C++ Applicationの1階層下に現在のプロジェクトに対応するデバッグ構成が「新しく」現れるのでそれをクリック(ここでは02-02-OpenFile-Full Debug (1)ですね)。 |
5 | <デバッグ構成>
(右):名前:これはこのデバッグ構成につける名前です。ここでは 02-02-OpenFile-Full Debug Arg としておきます。 ("(1)"を削除して代わりに "Arg"とします) |
6 | <デバッグ構成>
(右):(x)=引数:プログラムの引数の欄に、コマンドライン引数を与えます。 ここでは hello.txt としておきましょう。 (ちなみにその下に 作業ディレクトリー の表示があって、eclipseがどのフォルダで実行を行うかが示されています) |
7 | 構成およびデバッグ(右):全ての設定が終わったら、「適用」をクリックして設定を保存します。 |
8 | 構成およびデバッグ(右):全ての設定が終わったので、右下の「デバッグ」をクリックして実行時デバッグを開始します。 |
これで実行すれば大丈夫‥
ということはなく、自分の書いた別のトラップに引っかかってしまいます。
これは、当然ですが、hello.txtというファイルが存在してないからです。
一旦C/C++パースペクティブに戻って、hello.txtを作成しましょう。
hello.txtは単なるテキストファイルという想定です。
せっかくなので、hello.txtもプロジェクトに登録してeclipseのエディタで編集できるようにしてしまいましょう。
05-07-04-B | テキストファイルのプロジェクトへの追加 |
1 | プロジェクトビューで実行時デバッグをしようと思っているプロジェクト(02-02-OpenFile-Full)の最上位ノードが選択されていることを確認 |
2 | a. メニュー:ファイル→新規→ファイル
b. プロジェクトビューの02-02-OpenFile-Fullを→クリック→新規→ファイル |
3 | 新規ファイル:ファイル名に hello.txt と入力→終了
(親フォルダーが02-02-OpenFile-Fullになっていることを確認しておいてください) |
これによって、~/workspace-ip3/02-02-OpenFile-Full/hello.txt というファイルが生成され、eclipseで編集できるようになりました。
(02-02-OpenFile-Full.cでは実際にはファイルの中身を参照しないので、ファイルの中身は空でも何か書いてあっても関係ありませんね)
再度デバッグパースペクティブに移動して、実行時デバッグしてみましょう。
02-02-OpenFile-Fullプロジェクトには今や2種類の実行時デバッグ環境があります(02-02-OpenFile-Full Debug と 02-02-OpenFile-Full Debug Arg)。
今は、後者の 02-02-OpenFile-Full Debug Arg を以下の作業で選択することにします。
デバッグアイコン右の黒逆三角形をクリック→02-02-OpenFile-Full Debug Arg を選択することで、デバッグパースペクティブでの実行時デバッグが開始します。
今度は正常にプログラムが進行します。
コンソールの最後に "All set. Bye!"まで表示されれば、想定通りに動いたという証ですね。
<-- ex1:, ex2:, ex3:2014 -->
演習
05-07-04-ex1: 本節のプログラムソースのprintf()ごとにfflush()を追記して、コンソールでprintf()の出力が毎回確実に出るように改変しなさい。
05-07-04-ex2: 上記ex1のfflush()の追記の時、printf()の右に追記するのと、printf()の下に追記した場合のstep in実行時の振舞の挙動の差について説明しなさい。
05-07-04-ex3: 本節のプログラムソースにおいてprintf()とfflush()をまとめて行う関数を自分で定義し、それを呼ぶことでprintf()を置き換えなさい。そのとき、読んだ側のプログラムソースの行番号を出力できるようにしなさい。
printf()の使い方の違いに合わせて、ユーザ定義関数は3種類用意したほうがよいでしょう。
少し考えれば、ユーザ定義関数は2種類に減らせます。
05-07-04-ex4: C言語の関数の定義では、本来、引数の個数は固定ですが、printf()関数のように明らかに引数の個数を呼び出し時に変えていいものがあります。これと同じことをユーザ定義関数で実現したい場合、どのように記述すればいいか、例を示しながら説明しなさい。
05-07-04-ex5: 上記ex4の知識を用いて、ex3のプログラム作成時に用意するユーザ定義関数を1つだけにしてみなさい。(相当に面倒なプログラムになります)
05.07.05. eclipse:デバッグパースペクティブでの配列変数の読み方と、文字列の配列というargvの構造
02-02-OpenFile-Full-Debug-Arg のデバッグ構成で実行時デバッグを開始したとき、(右上の)変数ペインには、argc, argv, filetoopenの3変数が並んでいることでしょう。
argcの値が2になっていることはいいですね。
(実行時引数に hello.txt を与えたので)
わかりにくいのはargvで、これはまずはポインタの配列で、要素数は2(要素数はargcの値で知ります)です。
(ポインタではあるので、値としてはアドレスが入っています。0xで始まっているので、16進数表記ですね)
ところが、argvだけみても配列が何個分くるのかはわかりません。
しょうがないので、ポインタ配列が来ても、eclipseは最初、ポインタ配列の先頭のアドレスだけ値に表示して終わってます。
このように、配列のつもりでポインタ変数を使っているとき、eclipseでは配列の形で表示してくれません。
(C言語の仕様上、要素数が1以上いくつあるかわからない状態でむやみに参照すると、即バッファオーバーランが待ってます‥)
ところで、実行時のこの瞬間、我々はargvが要素数2のポインタ配列であることを知っています。
そこで、eclipseにその情報を与えて、表示方法を変更してもらいます。
05-07-05-A | 配列に対応しているポインタ変数の配列表示 |
1 | 変数ペインでargvを右クリック→配列として表示 |
2 | 配列として表示:開始インデックスに0を、長さに2を指定→OK |
これによって、argvツリーは、第2階層に2ノード表示されます。
argv[0], argv[1]をクリックすると、変数ビューの最下行にそれぞれの先頭アドレスと、そこから始まる文字列が表示されます。
暇な人は、argv[0]に入っている文字列の文字数を数えてみましょう。
argv[0]のアドレス+argv[0]の文字数+1('\0'ですね)が、argv[1]のアドレスになっていることがわかると思います。
0x7fffffffe3cd "hello.txt"
(原稿を書いている私の環境での例は、0x7fffffffe377 + 85 + 1 = 0x7fffffffe3cd でした)
(ちなみに第0引数は"/home/kameda.yoshinari.ft/workspace-ip3/02-02-OpenFile-Full/Debug/02-02-OpenFile-Full"でしたよ
(16進数だけどがんばって!)
(この辺のメモリ空間のレイアウトはコンパイラが違うと若干違うので、皆さんの環境でこの通りになってなくてもまあ気にする必要はありません)
(でも大抵は文字列配列は詰めて並べてることが多いのでたぶんこの計算は成立することでしょう‥)
なお、filetoopen構造体変数については触れません。
filetoopenツリーを展開してみれば分かりますが、皆さんには隠しているもののファイルとのデータのやりとりは実はすごく面倒くさい問題を含んでいるというのが想像がつくことでしょう‥
その面倒くささを、FILE構造体というのを使って上手に隠しているのですね。
(これもまた典型的な「情報隠蔽」の一例です)
演習
05-07-05-ex1: 05.07.04節のプログラムをベースに、2つのファイルを(読出用に)開くプログラムを作成しなさい。
・指定されたファイルが2つとも開けなかったり正しいファイル名でなかった場合は、どのファイルが開けなかったか理由と共に表示すること。
・プログラム終了時には2つのファイルとも閉じること。
工学システム棟5階計算機室のLinux環境では、eclipse利用時に、たまに所定の動作を行わないときがあります。
コンパイル時や、デバッグ実行のうちの通し実行でたまに見られるようです。
その場合は、その作業を再度最初から実行してください。
(おそらく皆さんのホームがnfsマウントされていることに伴う症状だと踏んでますが確認は取れていません)
printf()でデバッグするのが好きな学生は、学類のeclipse対策として、各行ごとに fflush(NULL); を追記しましょう。
(ターゲットバイナリからの出力がキャッシュされてしまって、何もしないとプログラム終了時までconsoleに表示されません‥通常環境ではこんなことは起きないのですが。fflush()に特段の害はないので、そのまま他の環境にもっていっても問題はないですし。)
・ eclipse (original) : 開発本家サイト。
・ wikipedia での eclipse の説明 : 技術的な内容は載っていません。
・ 生産性向上への道 Eclipseで行うC/C++開発(2)「CDT」で効率的なC/C++開発を実現する : CDTのいろいろな機能が説明されてます。参考にしてください。
(ここに限らず、WWWでの資料では微妙にメニューの位置や挙動が違ったりしますが、その辺は適宜各自修正して読みましょう)
・ 生産性向上への道 Eclipseで行うC/C++開発(1)組み込み開発におけるEclipseの有効性 : 関係ない話も混じってますが、出だしのeclipseの概念説明はわかりやすいでしょう。
(今回、講義資料を用意していて思ったけど、google先生に尋ねても、大学などでeclipse教えてそうな例にほとんど出くわさないのはどうして?)
(eclipseがまともに動くようになってから、5年ぐらいは経ってると思うんですけど‥)
(大学では受けが悪い? 今後もemacs/e-lisp + gcc でガンバローってこと?理由がわかりません。)
(統合開発環境は全部Visual Studioに流れていくとか。ええー。)
演習
05-08-ex1: fflush()関数の機能を調べて説明しなさい。引用元も明記すること。また、fflush()をprintf()直後につけた場合とつけない場合でどのように差が出るかを述べ、それが実際の実行上でなぜ君たちが実感できないかを説明しなさい。