をるふちゃんのブログ

めもっぽいやつ

C++入門 0x0002回 さようなら世界

C++入門 0x0001回 環境構築なんてしない - をるふちゃんのブログ
から続く。

最終回のタイトルみたいになっているが。
だってHelloWorldとか出力するのダサダサじゃん。

> Goodbye, World

こっちのほうがかっこいいと思う。さようなら普通の世界。ようこそプログラミングの世界へ。

コンソールアプリケーション

上にも書いたが、普通の入門書は「Hello, World」と画面に出力するプログラムを書かせる。
がその前にコンソールについて説明しておく。

コンソールとは

むかしむかし、あるところにコンピュータがありました。それはウィンドウもボタンもアイコンもなく、黒い画面に白い文字が表示されているだけでした。

……いわゆるMS-DOS時代の話だが、その後Windows1.0から3.1、そしてWindows9xを経て現在のNT 10.0に至るまでMS-DOS互換環境はずっと残されている。
この通称「コマンドプロンプト」はWindows NT系統ではcmd.exeという端末ウィンドウ兼コマンドラインシェルに姿を変えたが、とにかく初期のコンピュータのようにキーボードだけで操作するプログラムを動作させることができる。
Linuxのことは知らんけど同じようなものがあるはずだ。

なのでまずはこれを使ってプログラムを試してみよう……と言いたいのだがとりあえずは https://wandbox.org を使う。
だって環境構築なんて最初からやると心が折れるからね。

Wandbox

f:id:wolf_cpp:20180313083457p:plain こんな画面が広がっていることと思う。
左側は特に気にしなくて良い。中央にプログラムを記述しよう。

#include <iostream>

int main(){
  std::cout << "Goodbye, World" << std::endl;
}

とりあえずここまで書いたら「Run (or Ctrl+Enter)」というボタンを押す。コンパイルし、実行した結果が下の黒い部分に出てくる。
f:id:wolf_cpp:20180313113906p:plain
Start,0,Finishの文字については気にしなくていい。自分のWindowsLinuxで直接動かすときには出てこないので。

ざっくりと言うと、これが最初のプログラムだ。

一行目

#include <iostream>

#から始まる命令はプリプロセッサディレクティブという。コンパイルの前の下ごしらえと言ってもいい。
#includeはその行に指定されたファイルの内容をそのまま挿入する。
この場合はiostreamというファイルを読んでくれているということになる。

#include <hoge>の場合はコンパイラのデフォルトやオプション指定された追加のファイルパスから検索を行い、#include "hoge"の場合はそのソースコードが記述されているファイルのあるディレクトリ(カレントディレクトリ)を検索した後、見つからなければ<>のときと同じ検索を行う。

iostreamは標準入出力のオブジェクトを宣言しているヘッダファイルだ。
オブジェクトつまり物体?と疑問が膨らむがここは 今は スルーしてほしい。

ヘッダファイル

とりあえず対応するヘッダを読んでおけば(includeしておけば)色々使えるから気にしなくていいよと言いたいところだがここはきちんと説明しておく。環境構築端折ったくせに

C++のコードはヘッダとソースに分けることが多い。
通常、ヘッダには宣言を書き、ソースには定義を書く。
この二組のファイルをいくつも生産しながら一つのプログラムができていくのが常だ。

コンパイルについて前回簡単に説明したが、C++においてコンパイルはソースファイルごとに行い、リンクファイルと呼ばれるバイナリ(0と1でごりごり書かれたやつ)を出力する。
それらリンクファイルをさらにリンカというプログラムが結合し、最終的に実行可能なファイルを出力する。Windowsでは通常、.exeという拡張子になる。
この、一連の作業をひとまとめにしてビルドと呼んだりもする。

他のソースファイルに書かれている関数やクラスを使いたい場合、ヘッダに書かれている宣言だけとりあえず読んでおかないといけない。
でないと「なにこれ」状態になってしまうし、ヘッダさえ読んでおけば「詳しいことはわからないけどリンクすればきっと使えるから今は気にしなくていい」ということでもある。目次のようなものだと今は思ってほしい。
このあたりの関係は「関数」の説明で詳しく取り扱う。

※テンプレートというC++の文法を使うときはソースファイルに記述しない。これは今は説明しないけど許して。

3行目と5行目

int main(){

}

これはメイン関数などと呼ばれる。
関数と言っても数学のそれとは違う。一言で言うなら「命令をまとめたもの」だ。C++ではmainという名前のこれを最初に呼び出すことになっている。
しばらくは別の関数を作ることはないのでこのmain(){}において{}の内側に色々な「文」を書いていけばよい。
intだとか()についてはお預けだ。許してね。

4行目

std::cout << "Goodbye, World" << std::endl;

これがwandboxの下側に文字を出すための記述だ。 std::coutとは標準出力に対するマルチバイト出力ストリームオブジェクトだ。といってもさっぱりわからないことと思う。

標準ストリーム

標準ストリームというのはシェルの機能として実装されていて、簡単にプログラムと端末を接続してくれる仕組みのことだ。要するにコマンドプロンプト上に文字を出力したり、キーボードからの入力をプログラムに突っ込んだりできる。
マルチバイトというのは……そもそも英語圏では大小のアルファベットと数字といくつかの記号で事足りていた。1byte(=8bit)つまり256通りもあれば十分だったのだが、日本を含めた様々な文字を表現しようと思ったら当然足りないのでこれを倍などに拡張して文字を表現する仕組みが色々考えられた。UTF-8やShift-JISというのがそれだ。複数の規格が出てしまったので混乱することになるが、ともあれ。

そういう2byte以上の入力も扱える、コマンドプロンプトで簡単に使える入出力の仕組みだということだけ覚えておいてほしい。
オブジェクトってなんだよって?だから今は説明できないって


話を戻そう。 std::cout << ""のこの""の中になにか文字を入れておけばそれを出力できる。
std::endlというのは改行を行いバッファをフラッシュする。

バッファ

バッファとは何らかのデータを一時的に蓄えておくための何かを指して言う単語だ。この場合、出力したいデータを貯めておくデータ領域のことを言う。
なぜ貯めておく必要があるのか?それは毎回毎回いちいち書き込みに行くと時間がかかるし手間が無駄だからだ。ビュッフェのレストランで複数の料理を皿に山盛りにしてからテーブルに戻るのと同じだと考えておけばいい。それをフラッシュ、つまり反映させるという効果を持つ。
std::endlしなくてもフラッシュされることはあるし、プログラムの最後になれば反映されるだろうから絶対書かなきゃいけないわけではないが。


そしてそれらをつなぐのが<<だが、詳しいことは置いておいて、とりあえず<<の後に書かれた何かを標準出力に突っ込むための記号だと思っておけばいい。
演算子オーバーロードという文法を使って「そういう動作」をさせるようにC++のライブラリに書かれているのだが今は気にしないでね

そして忘れてはいけないのが行末の;だ。これはC++の文末表現である。「。」のような効果だが、我々人間が文を読むのと違ってコンパイラは色んな意味で融通が効かない。どこで文が終わりなのかこれで示してやる必要がある。

改行や空白について

C++において改行や空白は解釈に影響を与えない。
だからどれだけ改行を入れようが空白をはさもうがコンパイルされてしまえば特に違いはない。
例外として""の内側だけは改行を挟む場合、行末に\を入れないといけない。

#include <iostream>

int main(){
  std::cout << "Goodbye,\
\
\
World" << std::endl;
  return 0;
}

このようなこともできる。もちろんこの例のように不必要に多用するものではないけれど。

とりあえずここで筆を置いておくね。

前回: C++入門 0x0001回 環境構築なんてしない - をるふちゃんのブログ
次回: 執筆中