C++/文法の基礎

出典: フリー教科書『ウィキブックス(Wikibooks)』
< C++
ナビゲーションに移動 検索に移動

メッセージ表示するプログラムを作成してみる[編集]

ソースコードの記述から実行までの仕方は、箇条書きにすると、

  1. ソースコードをテキストエディタで書いて、sanpru.cpp のような名前で保存。
  2. ソースコードをコンパイルする。
  3. コマンドプロンプト(DOSプロンプト)などで実行する。

です。

「sanpru」の部分は半角入力の英語ならお好きな別の名前でいいですが、しかし末尾の「.cpp」は絶対にこの .cpp にしてください。

ソースコードの作成と確認方法[編集]

まず、「ようこそ」とメッセージ表示をするプログラムを、作成してみましょう。

(C++言語のコード)

#include <iostream>
using namespace std;

int main()
{
	cout << "ようこそ、Cプラスプラス言語へ。";
	return 0;
}

まず、このコードを「メモ帳」アプリなどのテキストエディタに書いて、「sample.cpp」とか「sanpru.cpp」のように拡張子cppをつけて、保存します。必ず最後に拡張子「.cpp」をつけてください。つけないと、コンパイルのコマンド実行時に、コンパイラがコードのあるファイルを発見できず、エラーを起こします。

また、けっして、「Word」などのワープロソフトに保存しないでください。wordなどに保存すると、エラーになります。(※ 詳しくは、『プログラミング/プログラミング初心者むけの共通知識』で紹介してある。)

ちなみに、上記のコードの発音は、一例として以下のようになる。

#インクルード <アイオーストリーム>
ユージング ネームスペース エスティーディー;

イント メイン()
{
	シーアウト << "ようこそ、Cプラスプラス言語へ。";
	リターン ゼロ;
}

さて、メモ帳の種類によっては、拡張子「.cpp」をつけて保存することにより、そのファイルの内容がc++コードである事を認識して、

#include <iostream>
using namespace std;

int main()
{
	cout << "ようこそ、Cプラスプラス言語へ。";
	return 0;
}

のように、色が付く場合もあります。

内容をおおまかに解説すると、「cout」とは、「出力表示しろ」というような意味です。 cout は「シーアウト」と読みます。

さて、「<<」は、左向き矢印「←」のような意味です。二重引用符" "は、この引用符で囲まれた内容が文字列である事を示します。「;」は、直前の命令の終わりです。

つまり

cout << "ようこそ、Cプラスプラス言語へ。";

とは、「処理『cout』に、文字列『ようこそ、Cプラスプラス言語へ。』を渡せ」というような意味です。そして、処理『cout』の機能は出力表示であるので、よって、処理『cout』に文字列を渡すことにより、文字列表示が表示できるという仕組みです。

ですが、そこまで厳密に考える必要もなく、「『cout』とは、文字列表示をする命令だ」と覚えてしまっても、かまいません。

「include」などのような他の単語は、まだ気にしなくても、かまいません。(include <iostream> の場合、ある関連ファイル <iostream> を導入しています。)


(なお、もしコピーペーストではなく、キーボードから1文字ずつ入力したい場合は、「ようこそ、Cプラスプラス言語へ。」以外の文字の入力では、かならず直接入力で入力してください。日本語の両側にある引用符「"」も直接入力にしなければなりません。

cout << 」も、直接入力にしなければなりません。「cout」と「<<」のあいだにある半角スペース「 」も、直接入力にしなければなりません。

半角英数ではダメです。半角英数では、コンパイルのためのコマンド実行時にエラーになり(「コンパイルエラー」)、コンパイルできません。とにかく、日本語メッセージ以外はすべて、直接入力です。
同様に、「using namespace std;」も「return 0;」も、直接入力です。
ともかく、これらを直接入力にしないと、コンパイルエラーになり、コンパイルできません。)

コンパイルから実行まで[編集]

コンパイル[編集]

  1. ソースコードをテキストエディタで書いて、sanpuru.cpp のような名前で保存。
  2. ソースコードをコンパイルする。 ← 今ここ
  3. コマンドプロンプト(DOSプロンプト)などで実行する。


テキストエディタに保存するだけでは実行できません。

まず、コンパイルをして実行ファイルに変更する必要があります。『DOSプロンプト』などと言われるコマンドライン端末を使います。Windowsの場合、『アクセサリ』にある「コマンドプロンプト」はそれです。

さて、コマンドラインだけでなく、コンパイラも必要なので、インストール済みである必要があります。 『C++/はじめに』にコンパイラのインストール方法などを書いておいたので、必要なら、お読みください。

コンパイル方法の結果だけ、まとめると、

  1. ホームフォルダにソースコードを置き、
  2. そしてコンパイラで下記のコマンドを入れます。

コンパイラの種類によって、コマンドなどが違います。

gcc-c++ の場合
g++ ファイル名.cpp
clang の場合
clang++ ファイル名.cpp

詳しくは『C++/はじめに』をお読みください。

ホームフォルダ以外での作業は初心者には不要なので、ホームフォルダ以外にあるソースコードをコンパイルする方法は、説明を省略します。

上記コマンドでは、出力ファイル名を指定していないので、コンパイルしたら「a.out」というファイルが作成されます。

※ a.out についての詳しい解説は本ページの末尾にあるハズなので、今の節では説明を省略します。詳しくはページ末尾を参照。

もし出力ファイルに名前を「sanpru.p」をつけたいなら、

g++ sanpru.cpp -o sanpru.o

あるいはclangなら

clang++ sanpru.cpp -o sanpru.o

で可能です。


実行[編集]

  1. ソースコードをテキストエディタで書いて、sanpuru.cpp のような名前で保存。
  2. ソースコードをコンパイルする。
  3. コマンドプロンプト(DOSプロンプト)などで実行する。 ← 今ここ


コンパイル時に出力ファイル名を作成していない場合、gccやclangでのコンパイルなら、コマンド

./a.out 

で実行できます。なぜなら、a.outが、上述のコンパイラの作成した実行ファイル名です。出力ファイル名を指定しない場合、「a.out」という名前になるからです。

もし実行ファイルをコンパイル時に「sanpru.o」と命名したなら、そういう名前の実行ファイルが存在しているので、

./sanpru.o

で実行できます。


改行を追加するなら[編集]

上の節のプログラムの実行直後、コマンド端末の入力カーソルの位置が、文字列「ようこそ、Cプラスプラス言語へ。」の右どなりにあると思います。

つまり

ようこそ、Cプラスプラス言語へ。[ユーザ名@localhost ~]$ ■

みたいな、ちょっとカッコ悪い表示になってると思います。(■の部分はカーソルに対応する部分で、実機では半角サイズの四角が点滅する。)

こうカッコ悪くならないように改行するためには、

(修正版)

#include <iostream>
using namespace std;

int main()
{
	cout << "ようこそ、Cプラスプラス言語へ。" << endl;
	return 0;
}

というふうに、「<< endl」を末尾に追加しましょう。「endl」とは、「改行しろ」という意味です。

そして再び、コンパイルしなおすために

g++ sanpru.cpp

を実行しましょう。そして、

./a.out

と入力して実行することで、「a.out」を実行して、確認しましょう。

今度は、コマンド端末の入力カーソルの位置が、

ようこそ、Cプラスプラス言語へ。
[ユーザ名@localhost ~]$ ■

のように、文字列「ようこそ、Cプラスプラス言語へ。」の次の行の、左端(最初の位置)にあると思います。


ソースコードだけを書き換えてみる[編集]

書き換えてみる[編集]

では、さきほどの「ようこそ、Cプラスプラス言語へ。」と表示するプログラムを実行してメッセージ表示させた直後に、

ソースコードだけを書き換えてみると、どうなるのでしょうか。

さきほどの「ようこそ、Cプラスプラス言語へ。」と表示するプログラムを実行してメッセージ表示させた直後に、

#include <iostream>
using namespace std;

int main()
{
	cout << "ようこそ、12345。" << endl;
	return 0;
}

と入力して、さきほどのソースコードのファイル「sanpru.cpp」で上書き保存したら、どうなるでしょうか?

「sanpru.cpp」で保存した直後に、 コマンド端末で

./obufai

を実行すると、「ようこそ、Cプラスプラス言語へ。」と表示されます。つまり、上書き保存した内容は、まだオブジェクトファイルには、反映されていません。

こうなる理由は、ソースコードを書き換えて保存しても、それだけでは、オブジェクトファイルは、何も書き変わらないからです。

オブジェクトファイルを、内容「ようこそ、12345。」のものに書き換えるには、

g++ sanpru.cpp -o obufai

をもう一度、実行して、オブジェクトファイルを上書きする必要があります。

このあとに、コマンド端末で

./obufai

を実行すると、今度は「ようこそ、12345。」と表示されます。


まとめ[編集]

オブジェクトファイルを、内容「ようこそ、12345。」のものに書き換えるには、

g++ sanpru.cpp -o obufai

をもう一度、実行して、オブジェクトファイルを上書きする必要があります。

このあとに、コマンド端末で

./obufai

を実行すると、今度は「ようこそ、12345。」と表示されます。

練習問題: 「hello,world」と表示させてみましょう[編集]

アメリカのプログラミングの入門書では、「hello,world」とメッセージ表示をするプログラムが、さいしょのほうに紹介されることが、多くあります。

ここwikibooksでも、さきほど習った知識をつかって、「hello,world」とメッセージ表示するプログラムを書いてみましょう。

答えのコードは、例えば、

#include <iostream>
using namespace std;

int main()
{
	cout << "hello, world" << endl;
	return 0;
}

のように、なります。

コードを書き替えたあとに、コマンド端末で、コマンド

g++ sanpru.cpp -o obufai

などを実行して、コンパイルしなおしましょう。そしてコマンド端末で、コマンド

./obufai

を実行して、「hello.world」を表示しましょう。


オブジェクトとは[編集]

C++でメッセージ表示をする場合のコードでは、

coutと呼ばれるデータに"ようこそ、Cプラスプラス言語へ。"という文字列を与えて、cout自身にそれを解釈させる

という考えかたをしています。

ここで、coutのように、ある演算に対してどう振る舞えばよいか知っているデータのことを、オブジェクトと呼びます。


コンソール入出力[編集]

基本[編集]

標準C言語でコンソール入出力する場合、printf関数やscanf関数を使う。(文字表示ならコンソール出力なのでprintf。キーボード入力ならコンソール入力なのでscanf。)

※ printf や scanf を知らないなら、この文は読み飛ばして斜め読みでいい。

C++では、下記のようなcout やcin などの命令を用いて、体系的な新しい方法でコンソール入出力を行うことができる。


coutやcinを使うには、 <iostream> ヘッダをインクルードする必要がある。

コンソールへの出力は次のように行う。

cout << ;

<<演算子を複数使うことで、複数の項目を出力することもできる。

キーボードからの入力は次のように行う。

cin >> 変数;

不等号っぽいものの向きが変わっている事に注意。演算子 << と >> はまとめて「入出力演算子」と呼ばれる。

またなお cin について、scanf関数とは違い、右辺の変数に「&」が付いていないことに注意。

※ coutやcinの演算子<<と>>の向きが覚えづらいかもしれないが、しかしcoutを使うのはあくまでもコンソール画面での文字出力の場合だけであり、WindowsでのグラフィカルなGUIアプリでの文字出力命令はまったく別の関数であり(詳しくは『Windows API/文字表示の命令』)、GUIアプリ作成では演算子<<と>>を使わないので、覚えられなくても気にしなくてイイ。

cout や cin で複数の項目を扱うには、空白文字(スペース、タブ、改行)で区切る必要がある。

#include <iostream>
using namespace std;

int main()
{
	int i = 1234;
	cout << "iの値は" << i << "です" << endl;
	return 0;
}
//例 コンソールから入力
#include <iostream>
using namespace std;

int main()
{
	int i;
	cout << "整数を入力してください。" << endl;
	cin >> i;
	cout << "入力された値は"<<i<<"です。" << endl;
	return 0;
}


なお、<<や>>は同じ形の演算子が、ビット計算のシフト演算子としても使われているが、たまたま形が同じだけで、cout や cin のそれとは意味がまったく異なる。

cout と printf の相違点[編集]

C++におけるcoutには、出力の書式を指定しなくていいという利点があります。

printfには、出力書式の指定が必要です。

コード例
#include <iostream>
#include <string> // 文字列を扱うコードなので

using namespace std;


int main() {

  int e=3;
  cout << e << endl;
  
  string moji="aaaa";   
  cout << moji << endl;

}
表示結果
3
aaaa


いっぽう、printfを使うと、下記のように出力書式の設定が必要です。

コード例
#include <iostream>
#include <string>

using namespace std;


int main() {

  int e=3;
  printf("%d\n",e);
  
  string moji="aaaa";
  printf("%s\n", moji.c_str() ); 

  cout << moji << endl; // 比較用

}
出力結果
3
aaaa
aaaa


C++ にはstring型というのがあります。いっぽう、標準Cにはstring型が無いです。

printfが標準Cに由来するため、C++のprintfも標準Cの仕様に合わせてあるため、そのままではprintfではstring型を表示できないので、 .c_str() というメソッド(命令のようなもの)を使ってprintfでも表示できるようにデータを取り出して命令する必要があります。

.c_str() メソッドを使っても、もとのオブジェクト(上記コードでいうmojiの部分)はそのままなので、ひきつづき cout で、もとのオブジェクト moji を表示できます。

詳しい解説[編集]

基本[編集]

ファイル名は「sanpru.cpp」でも「test.cpp」でも平気でして、最後の「.cpp」以外は何でもいいのですが、とにかく最後にかならず拡張子「.cpp」をつけてください。

とりあえず、コードのファイルを「sanpru.cpp」という名前で保存したとしましょう。

このファイル「sanpru.cpp」は、まだ何もコンパイルされていません。

コマンド端末で

g++ sanpru.cpp

のように入力して実行すると(リナックスfedora26で動作を確認)、もしコードに間違いがなければ、「a.out」というファイル名でコンパイルされます。

コンパイラの実行後、ホームフォルダをよく見ると、「a.out」という一時的な実行ファイルが作成されています。「a.out」の内容は、直前にコンパイルしたコードを、アセンブリ言語にそのまま変換した内容です。

このファイル「a.out」の中に、アセンブリ言語にコンパイルされた一時ファイルがあります。

コンパイル時に、出力先のファイル名などを指定しないでおくと、かわりに一時ファイルとして「a.out」という一時的な実行ファイルが作成されるのです。「a.out」はあくまで一時的なコンパイルファイルを置く場所でしかないので、もし、あとから別のコード(かりに「コードH」とする)をコンパイルすると、「a.out」の内容はその別のコード(我々の言う「コードH」)に置き換わってしまいますが、我々はコンパイル後にすぐに「a.out」を使用する予定なので、C++初心者のうちは「a.out」の使用でも問題ありません。


なお、もしコードにエラーがあれば、「a.out」は作成されずに、かわりにコマンド端末にエラーのある事を伝えるメッセージが表示されます。

(エラー時のメッセージ文章は、著作権の問題でwikiでは表示できかねますので、読者は自分でエラーメッセージを確認してください。)

ファイル「a.out」そのものの使用をするには、コマンド端末で、

./a.out

と入力して実行することで、「a.out」を実行できます。「./」を冒頭につけるのを、忘れないようにしてください。「./」とは、現在のフォルダ位置を意味します。通常、OSを起動した直後の状態では、現在のフォルダはホームフォルダに設定されている場合が多いと思いますので、ホームフォルダを探してください。きっと、「a.out」という名前のファイルがホームフォルダ内に追加されているはずです。

「./a.out」というコマンドの意味は、「現在のフォルダにあるファイル『a.out』を実行しろ」という意味です。


この「a.out」に、さきほどコンパイルした「sanpru.cpp」がアセンブリ言語にコンパイルされた状態で置かれているので、よってコマンド「./a.out」の実行により、コード「sanpru.cpp」の内容が実行されます。

「./a.out」の実行により、コマンド端末に「ようこそ、Cプラスプラス言語へ。」と表示されれば、成功です。「ようこそ、Cプラスプラス言語へ。」と表示されていれば、正常にコンパイルされた実行ファイルを、正常に実行できた事になります。


では、ここではこのソースコード「sanpru.cpp」の内容について簡単に説明します。


(C++言語のコード「sanpru.cpp」の再掲)

#include <iostream>
using namespace std;

int main()
{
	cout << "ようこそ、Cプラスプラス言語へ。" << endl;
	return 0;
}
  • 1行目の「#include <iostream>」は、新しいスタイルのヘッダです。
    C言語では「#include <stdio.h>」のようにファイル名を指定しましたが、これは古いスタイルのヘッダで、C++では新しいスタイルのヘッダを使い、標準識別子を指定します。新しいスタイルのヘッダは、ファイル名ではないので「.h」拡張子がありません。古いスタイルのヘッダは、まだ使用できますが、推奨されません。標準Cヘッダを新しいスタイルで書くと、接頭辞にcが付きます。例えば、「#include <stdio.h>」は「#include <cstdio>」となります。
  • 2行目は、std名前空間を可視状態にしています。
    C++の新しいスタイルのヘッダをインクルードすると、その内容がstd名前空間に追加されます。名前空間とは、要素の名前が衝突しても識別できるように、名前の集合に対して与えられる識別名のことです。[1]
  • 3行目は、空白行です。この空白行はなくても良いのですが、見やすくするために、空白行を入れました。
  • 4行目(「int main」)から8行目(「}」)は、main関数の定義です。C++やC言語でいう「関数」とは、なんらかの一連の処理をまとめたものです。数学用語の「関数」とは、C++でいう「関数」は意味が違いますので、気をつけてください。 「int」とは、戻り値(「出力」のような物)が 整数であることを示します。(整数は英語で integer と書く。なお、「インテジャー」と読む。) 文章「int main」で、「関数 main は、出力が整数である」という事を宣言しています。
  • 5行目(「{」)から8行目(「}」)は、ブロックというまとまりです。
  • 6行目(cout << "ようこそ、Cプラスプラス言語へ。" << endl;)は、出力演算子による出力操作です。
    Cではコンソール出力に、printf関数を用いましたが、C++では出力演算子「<<」を使って、改善された方法で出力を行うことができます。Cでは「<<」は左シフト演算子でしたが、C++ではその機能に加えて、出力演算子として用いることができます。(これは、後で解説する演算子のオーバーロードの例でもあります。) 「endl」は、「改行をする」という意味です。なお、最後の「;」は、直前のコマンドの終了を意味する記号です。もし、ここの「;」を書き忘れると、コンパイル時にエラーになり、コンパイルできません。
  • 7行目(「return 0;」)は、return文です。0は、「戻り値」と呼ばれる数値に、数値「0」を設定しています。(詳しくは、関連のページで後述します。)最後の「;」は、直前のコマンドの終了を意味する記号です。もし、ここの「;」を書き忘れると、コンパイル時にエラーになり、コンパイルできません。


  • 6と7行目が、他の行より、文字の位置が右から始まるのは、字下げです。キーボードの「Tab」キーの入力により、字下げができます。(たいてい、キーボードで左端にTabキーがある。左上に「半角/全角」キーの下にある。) この字下げは、しなくても良いのですが、見やすくするために、関数の中身などを書く際に、字下げがよく使われます。(もちろん、ここでいう関数とは、C++やC言語でいう「関数」のことであり、なんらかの一連の処理をまとめたものです。数学用語の「関数」とは、C++でいう「関数」は意味が違います。)

余談[編集]

生成されたファイル「a.out」は、あたかもファイル形式のa.out形式と関係ありそうですが、しかし、じつはファイル形式の a.out形式 とは無関係です。過去にa.out形式というファイル形式が存在していた時代があり、その名残り(なごり)で生成ファイル名がa.outのままになっています。

実際の生成ファイルのファイル形式は、ELF形式などの別の形式であるのが普通です。

脚注[編集]

  1. ^ 名前空間とは|namespace|ネームスペース|NS - 意味/定義 : IT用語辞典