最近C++言語の入門書を読んでます,星姫でーす.
基礎編が妙に長かったせいで,正直つまらなかったんじゃないかと思います.
(え?!途中から読み流していて,半分も覚えてません?…上等!)
とにかく,いよいよ実践編の第一話が始まります!(ヤッター!)
今回のテーマは最初の最初ということでメイン関数です.
みなさん,基礎編の「009話 開発環境の構築」にて紹介した開発環境の準備をお願いします.
これからプログラムを書いてと言ったら,この赤枠で囲った領域に書くことを意味しています.
プログラミングが初めてという人は,難しいと感じることでしょう.
Visual Studioの使い方から,ここは丁寧に紹介していこうと思います.
まず,下記のプログラムをコピーして書き,「F7」でビルドし,「Ctrl + F5」でデバッグなしで開始してみてください.
私も上記をコピー&ペーストで試してみました.エラーも警告も無くビルドを確認しました.
「Ctrl + F5」キーの結果を以下に示します.
cmd.exeというアプリケーションが起動し,何やら文字が出力されて,最後に「続行するには何かキーを押してください.」となったと思います.
このウィンドウはコンソールウィンドウと呼ばれるもので
プロジェクトを作る際に決めたプロジェクトの種類がWin32 コンソール アプリケーションであることと
アプリケーションの種類がコンソール アプリケーションの場合に表示されるものです.
さて,たかだか5行のプログラムですが,理解するのは簡単ではありません.
さっそく,それぞれの意味,はたらきを見ていきましょう.
◆まずは,#include <iostream> から説明します.
!っ今気付いたのだけど,プログラムのちゃんとした発音を知らないんですよね.
以降から勝手に読みますが気になる方は自分で調べてみてください.
私はこれを「井げたインクルード <アイ・オー・ストリーム>」と読みます.
<>で囲われたヘッダファイルを読み込むための命令として理解しています.
ヘッダファイルを読み込むとは?
まず,キーボードから情報を入力したり,ディスプレイに文字を出力したりすることを考えて下さい.
基礎編の「011話 命令とアーキテクチャ」にて
アーキテクチャの話をしましたが,ハードは動作の仕様が決められた後に作られます.
(…書いてみると当たり前の事でした)
つまり,それぞれの動作はプログラムから実行できるように設計されています.
この実行命令群が<iostream>ヘッダファイルです.
<iostream>ヘッダファイルを読み込んだら,キーボードやディスプレイへの入出力命令群を使用できるようになると
そのようにして納得がいくと,とてもわかりやすいと思います.
最初から何でも出来るように用意しておけば良いと思うかもしれませんが,プログラムは必要以上に大きくしないのが鉄則です.
仕方がないのです,必要になったヘッダファイルだけ,これからはインクルードするようにしましょう.
◆次に2行目の int main(int argc, char *argv[]) について
これがメイン関数と呼ばれるものです.
読み方ですが「イント メイン(イント アーギュメント・カウント カンマ キャラ アスタリスク アーギュメント・ベクトル[])」です.
最初にして最大の難所です.ポインタを理解しないと先に進めないところに来ました.(早!)
とにかく,わらないところを一つずつ潰していきましょう.
基礎編の「012話 MIPSアーキテクチャとは?」にて bit,byte,word について何か書かれていました.
それぞれbitはbinary digit(2進表現の単位)の略, byte は 8bit, word は4byte つまり 32bit を意味しているとの事でした.
int(イント)は整数(integer:インティジャア)の略字です.C++のキーワードの一つ,整数データ型を意味します.
型ってのは大切でして,メモリ上での大きさを表しています.C++での int の大きさは 4byte です.
また,int 型とは基礎編の「013話 2進数と算術演算」にて学んだ符号付き(signed)整数であり
-2147483648〜2147483647の範囲の整数を表します.
int main(){}とすることで,「メイン関数の型は符号付き整数です」と宣言しているのです.
さて,メイン関数の引数(ひきすう)を見てみましょう.
int argc, char *argv[] について int argc は整数型の変数を定義していると理解できます.argc を第1引数(ひきすう)と呼びます.
変数ってのは,書いて字のごとく中身を調べないと何が入っているのかわからない数です.
もっとも,型の宣言はしていますから,一応-2147483648〜2147483647の範囲の整数であることだけはわかります.
定数として扱うこともできますが,代入することでその値を変更することが出来ます.
また,argc でなくても a でも argument_count でも構いません,定義する時に任意で変数名を決めることができます.
◆ポインタについて
第2引数が,それは難しいポインタ絡みの変数なのです.
メモリにはアドレスがあると,基礎編の「012話 MIPSアーキテクチャとは?」にて述べました.
プログラム上では,このメモリ・アドレスをポインタと呼びます.
char(キャラ)は(character:キャラクター)の略字で,C++のキーワードの一つ,文字型と呼ばれる 1byte の大きさの符号付き整数型です.
8bitですから256段階です.それぞれの整数にアルファベットや数字が割り当てられていて,これを利用します.
さて,文章は文字を並べたものです.(これまた書いていて当たり前のことでした)
よって,文章は文字列と言えます.
言いたいことは,複数の文字列を扱う場合,誰もが最初の文字のメモリ・アドレスを利用するだろうということです.
実際のプログラムの設計も,このように作られています.
文字列はメモリ上に存在し,一文字 1byte のメモリを占有しながら文字列の長さ分だけ連続して配置されています.
複数の文字列を扱うには,それぞれの文字列の先頭アドレスを利用します.
この文字列の先頭アドレスのことをポインタと呼んでいるのです!!
連続してメモリを占有しているデータの先頭アドレスのことを,そのデータのポインタと呼んでいるのです!!
この赤い言葉の意味を,これまでの基礎編で学んだコンピュータのメモリと照らし合わせて,イメージできたならば
自分のことをプログラマ初心者と言って良いと思います.
今,ここで理解できなかった人も心配は要りません.
なぜなら有名大学の大学生が3カ月かけて会得する境地だからです.(1日で出来ちゃう人は稀です)
こんなサイトの数十行の文章を数分で読んで,ポインタが理解出来たなら
書店に置いてあるプログラムの入門書など売れる訳がありません.
ということで,みなさんC++言語にしろ触ったことのない言語を学ぶ時は入門書が必要です.
私がこれから参考書として使う「林晴比古 著 明快入門 C++ シニア編」を紹介します.
http://www.sbcr.jp/books/products/detail.asp?sku=4797349542
これから書いていくプログラムで不明な部分が出てきたら,ぜひこの参考書を開いて解決策を探してください.
ポインタを理解した後の話をさせてもらいます.
char *argv[] の char は文字型の定義だとして,*(asterisk)は何を表しているのでしょうか.
このアスタリスクは,文字型のポインタであることを宣言するために書かれています.
char *という表記が,「文字列が占有している領域の先頭メモリ・アドレスの型」を宣言していると考えても良いでしょう.
さて,char * が理解できたとして,さらに argv[] の [] とは何なのでしょうか?
これは,複数の文字列のポインタを argv[0], argv[1], argv[2],...という風に配列として扱うための宣言です.
配列とは,int i[10]; と宣言した場合 i[0],i[1],...i[9] と10個の int型の変数を扱えるようにする便利な表現技法です.
短い文章で宣言でき,[アクセス演算子]を指定するだけで目的の変数にアクセスできます.
この表現技法を「配列表現」と呼びます.
これは,一度使えば覚えられますので,まずは使ってみることをおススメします.
配列の数がわからない時に argv[] と [] の中に何も記入しないという,特殊なルールがあります.
この char *argv[] とは,ポインタと配列の特殊ルールを知っている者にしか理解できない表現だったのです.
良いですかみなさん!この話に辿り着かずにプログラミングに挫折する学生がたくさんいます.
プログラマ初心者すら語れない彼らは,仕事にしろ研究にしろ実装に苦しむことになります.
ここを偶然にも読んだあなたには,彼らを助けてあげられる力があります,どうか助けてあげて下さい!
一人の若者のちょっとした成長が,これからの日本の将来を支えていくのです.
◆長くなりましたが3行目の for(int i=0;i<argc;i++) について説明します.
for (フォー)文と読みます.良くコンピュータは単純な計算の繰り返しに強いと聞きますが,これは本当です.
その繰り返しを命令するのが,この for 文なのです.
for 文のはたらきを理解するのに以下のサイトを紹介します.
「初心者のためのポイント学習C言語」
http://www9.plala.or.jp/sgwr-t/
リンク先で索引を利用し「for」で検索してみて下さい.
「for文」が引っ掛かり,「for文」についての初心者向け説明文に辿り着くと思います.
for文の扱い方を覚えたら戻ってきて下さい.ちなみに私はここを読んで使い方を覚えました.
これから,プログラムで解らないことがあったら,基本「初心者のためのポイント学習C言語」で検索してください.
一瞬で解決しなかった場合に,参考書で詳しく調べると良いでしょう.
ということで,for(int i=0;i<argc;i++) とは変数 argc のカウント数だけ,次に書かれた文を繰り返すものだとわかりました.
◆4行目の std::cout << "argv[" << i << "] = " << argv[i] << std::endl; について
読み方は「スタンダード(std) スコープ(::) シーアウト(cout) << ダブルコーテーション(") argv[" …以下省略… 」です.
さっそくですが,「std::cout」を「初心者のためのポイント学習C言語」で検索してみましょう.
きっと,「お探しのキーワードは見つかりません」となると思います.(「std」でも「cout」でも同じことです.)
理由は,このサイトはC++言語対応では無いからです.あくまでC言語のサイトなのです.
さて,一瞬で解決出来ない時は参考書を読みましょう.「明快入門 C++ シニア編」で「cout」と索引を調べます.
巻末のINDEXにて,「cout 標準ストリーム」と見つかりました.
すごいです! #include <iostream> の説明から入り,ディスプレイへ出力するためのテクニックが全て書かれています.
私は std::cout 関数を扱うのは初めてなのですが,とてもわかりやすい説明です.
簡単に要約すると <<(小なり小なり)が出力演算子で,>>(大なり大なり)が入力演算子だそうです.
std::cout << 変数 << std::endl; でコンソールウィンドウに変数を出力し std::endl (エンドライン)にて改行させる命令とのこと.
つまり,std::cout << "argv[" << i << "] = " << argv[i] << std::endl; とは,変数 i と文字列 argv[i] を出力する命令と理解できます.
◆最後の return 0; について
これは「リターン」と読み,「戻り値」とか「返り値」を意味します.(当たり前すぎる)
int main(){} でメイン関数を符号付き整数型と定義していると言いましたが,実はこのメイン関数の戻り値の型を宣言していたのです.
return文は関数の処理を終了させ,右に書かれている式の値を返します.
return 0; の場合,符号付き整数の値 0を返します.
え!? メイン関数の戻り値はどこで読まれるのかって?
そこまで気にする貴方が大好きです.
次のコードをコピー&ペーストして,プロジェクト名「SystemTest」でコンソールアプリケーションを作ってみて下さい.
実行結果は次のようになると思います.
このプログラムは実行ファイルの戻り値を調べることが出来ます.
重要なのは res = system("MainTest.exe"); の行だけです.
このシステム関数の機能は,コマンド文字列を引数として,処理系が用意しているコマンドを実行することです.
MainTest.exeが見つからないから,res = 1 だそうです.
では見つけられるように,この関数がMainTest.exeを探したフォルダにMainTest.exeを入れてあげましょう.
まず,最初に作ったプロジェクトが保存されている場所に行きましょう.
普通はC:\Users\Administrator\Documents\Visual Studio 2008\Projects\MainTest
にあると思います.無いなら,自分で指定したフォルダを見て下さい.
そこにDebugフォルダがあると思います.
この赤枠で示したフォルダです.中にMainTest.exeがあるでしょう.
これを SystemTest のプロジェクトがあるカレントディレクトリに入れてあげるのです.
カレントディレクトリってのは,基準となる実行ファイルが置いてあるフォルダのことです.
デバッグ開始とか,開発環境での実行の場合はプロジェクトが置いてあるフォルダを指します.
こんな風にソリューション(.sln)とプロジェクト(.vcproj)が置いてあるフォルダにMainTest.exeを入れてあげましょう.
入れた後,もう一度SystemTestプロジェクトを実行してみます.すると結果は次のようになります.
res = 0 となりました.この値がMainTest.exe のメイン関数の戻り値なのです.
つまり,system() の戻り値がメイン関数の戻り値になっています.
これで,メイン関数の戻り値も扱えるようになりました.
さて,ここで紹介した system() は大変危険な関数なのでしばらく初心者の方は使わない様にして下さい.
コマンドはPCを制御する恐ろしい命令だからです.パソコンのデータを全て消去するコマンドも存在します.
書いていて,何だか怖くなってきました.
一応免責を書いておきます.
当サイトの御利用につき,何らかのトラブルや損失・損害等につきましては一切責任を問わないものとします.
便利なプログラムを考えたとしても,それらは全て自己責任で行ってくださいね.
最後にコマンドプロンプトという,コンソールウィンドウに似ているアプリケーションを紹介します.
その前に,準備をします.
さっきSystemTestのカレントディレクトリに入れたMainTest.exeの実行ファイルを今度はCドライブに入れて下さい.
では,コマンドプロンプトの起動の仕方を紹介します.
図のように,すべてのプログラム→アクセサリ→コマンドプロンプト,と見つけてクリックで起動させます.
「cd ¥」とコマンドを打って,場所ををC:¥>としてください.
次にMainTest.exe とコマンドを打って下さい.キー入力が苦手な方はmain の後にTab キーを押すと楽ができます.
改行キーを押すと,MainTest.exe を起動します.
これが出力結果です.
注目してもらいたいのは,MainTest.exeの後ろに半角スペースで区切った文字列を入力している行です.
そして,その実行結果を確認してみて下さい.
このように,起動時に実行ファイル名に続いて半角スペースで区切りながら引数を渡すことを,コマンドライン引数を渡すといいます.
この結果から,次の事がわかります.
int argc について,argc にはコマンドライン引数の総数が入ります.
char *argv[] について,argv[0], argv[1], ... には,コマンドライン引数の文字列のポインタが順番に入ります.
みなさんにここで「そうだったのかぁ」と納得していただけると,私は最高にうれしいです.
◆これにてメイン関数についての初心者向けの説明を終わります.
いかがでしたか?たったの5行のプログラムも,初心者にとっては難しいものだったと思います.
ですが,今回のレッスンを通して実践における第一歩を踏み出せました.
「こう書けば,こうなるはずだ」とプログラムを作り「実際にそうなった」という体験は
初心者にとって最高に楽しい一時です.ぜひ,プログラミングの楽しさを味わってみてください.
重ねて注意しておきますが,今回で知ったsystem()を使って,データ破壊プログラムを作らないでくださいね.
何事も自己責任でお願いします.
(char 型について,英数字は記号の数が少ないので問題は起きませんが,日本語は文字が多く 1byte じゃ足りません.
2byte を使って漢字などを表せるようにしています.文字化けの原因の一つです.)
2009/10/18 初記.
2009/10/24 追加.
2009/10/25 追加.
研究室では論文を投稿しました.
査読,受かっているといいですね!
第14話が完成! Main関数ってのは最初に呼び出される関数です.
ただそれだけなのですが,理解するのは結構難しいんですよ?