C++プログラミングを始めよう

この章では,C++言語を用いた標準出力とよばれる画面(コンソール)への文字や数字の出力方法について学ぶ.

出力ストリーム(Output Stream)

C++には<<("〜へ")という画面に表示するための出力演算子(output operator)} << が用意されている.
この演算子は第1引数へ第2引数を書きこむ.つまり,
std::cout << " ";
によって,2重引用符" "内の文字はそのまま標準出力ストリームstd::coutに渡され表示される.coutはcアウトと読む.日本語(全角文字)は2重引用符の中とコメントとして利用可能である.それ以外はすべて英数字(半角)であることに注意すること.改行(new line)するには$\yen$nと2重引用符内で書く.また,段落(tab)を取るには, 2重引用符内で$\yen$tと書けばよい.

例題 1..1   画面への出力
Hello world
初めてのC++
と画面に表示せよ.ただし,初めてのC++の前には段落をとるとする.

解答 C++で画面へ出力するにはヘッダファイル(header file)が必要である.プログラムの先頭部分にくるので,ヘッダファイルと呼ばれる.ここで用いるヘッダファイルは,$<$iostream$>$である.ヘッダファイル$<$iostream$>$には,coutなどがどのような働きをするのかについての宣言や定義が格納されている.このヘッダファイルを用いるためには,#includeを用いて,#include$<$iostream$>$と書く.

次にプログラムの中で最初に実行されるmain()関数とよばれるものが必要となる.関数とは,あるまとまった処理を行なう一連のプログラムで,{から}までが1つの関数の単位となる.すべてのプログラムはmain()という名前の関数を持たなければならない.また,出力演算子$<<$の前に出力ストリームオブジェクト(output stream object) std::coutが必要となる.これより,次のようなプログラムを書けばよい.

#include <iostream>
int main( )
{
    std: : cout << "Hello world \n \t初めてのC++\n";
}

実行結果

\begin{figure}% latex2html id marker 97
\centering\includegraphics[width=7.8cm]{CPPPIC/reidai1-1.eps}
\end{figure}

このプログラムをエディタ(vi,emacs,秀丸,MKEditor,メモ帳等の文書を書く機能を持ったもの)を使って書き,hello.cppという名前を付けて保存する.次に,hello.cppをコンパイル(complile)(C++言語をコンピュータが理解できる言語に変換)する.
下に,何種類かのコンパイラの用い方について記しているので,自分の使っているコンパイラでのコンパイルの仕方を学ぶ.

g++ hello.cpp -oまたはgpp hello.cpp -oの-oはオブジェクトファイルの生成を意味している.

Windowsを用いている場合,メモ帳を使って書くとhello.cpp.txtと保存されてしまうことがある.その場合(WindowsXPの場合)は,「スタート(右クリック)」→「エクスプローラ」→「ツール」→「フォルダオプション」→「ファイルの種類」→「新規」で拡張子の関連付けを行う.

プログラムhello.cppの解説(Explanation of hello.cpp)

練習問題 1..1   コンソールへの出力
こんにちは
誰々さん
と表示するプログラムを作成せよ.ただし,誰々さんには自分の名前を入れる.

エスケープ文字 エスケープ文字には,次のようなものがある.

エスケープ文字  機能
\a ベルを鳴らす
\b カーソルを1文字分戻す
\f 次のページの先頭にカーソルを移動する(改頁)
\n 次の行の先頭にカーソルを移動する(改行)
\r 同じ行の先頭にカーソルを移動する(復帰改行)
\t 次の水平タブ位置にカーソルを移動する(水平タブ)
\v 次の垂直タブ位置にカーソルを移動する(垂直タブ)
\\ \記号を示す
\' 引用符を示す
\" 2重引用符を示す
\? ?記号を示す
\0 ナル文字を示す
\DDD 8進数DDDで表される文字を示す
\xHH 16進数HHで示される文字を表す

もう一つのHello World(Another Hello World)

// hello.cpp
#include <iostream>
using namespace std;
int main( )
{
    cout << "Hello world\n\t初めてのC++" << endl;
}
3行目の
using namespace std;
endl(end of line)
$\yen$nと同じ働きをする.さらに,出力バッファを捨てる働きもある. 1行目の//はコメント行であることを表している.この記号により,この後続く文はコメントとして扱われる.C++には他にも/*ではじまり*/で終わるコメントの書き方もある.

名前空間(namespace)

ヘッダ$<$iostream$>$をプログラムにインクルードすると,そのヘッダの内容がstd名前空間に含まれる.名前空間(namespace)とは,単に宣言された領域のことである.名前空間の目的は,名前の競合を防ぐために,識別子の名前を局所化することである.

例題 1..2   出力ストリームへの数値の挿入
次の文章を出力せよ.
20世紀は2000年12月31日で終わった.

解答

#include <iostream>
using namespace std;
int main()
{
    cout << "20世紀は" << 2000 << "年" << 12 << "月"
    << 31 << "日で終わった。" << endl;
}

実行結果

\begin{figure}% latex2html id marker 173
\centering\includegraphics[width=8.8cm]{CPPPIC/reidai1-2.eps}
\end{figure}

当然,cout $<<$ "20世紀は200年12月31日で終わった。" $<<$ endl;と書くこともできる.ここでは,出力ストリームがいかに柔軟であるかを示すためと,数字はそれ自体がリテラルなので,2重引用符で囲む必要がないことを示すためにこんな書き方をしてみた.

練習問題 1..2   出力ストリームへの数値の挿入
自分の生年月日を出力せよ.

文字とリテラル(Characters and Literals)

文字とは文章を書く文字に10個の数字と句読点を含めたものをいう.文字は整数としてコンピュータに格納される.格納方法で最も有名なのがASCIIコード(ASCII code)である.ASCIIはAmerican Standart Code for Information Interchangeの略で,英数字をISOコードにパリティビットをつけた8ビットで表す.

例えば大文字のAは10進数で65として格納される.ちなみに,65は2進数で表すと

$\displaystyle (65)_{10} = 2^{6} + 1 = (1000001)_{2}$

16進数で表すと

$\displaystyle (1000001)_{2} = 0100 \vert 0001 = (41)_{16} = {\rm0x41}$

8進数では

$\displaystyle (1000001)_{2} = 001 \vert 000 \vert 001 = (101)_{8} = 0101$

となる.

データ型の具体的な値,つまり定数のことをリテラル(literal)という.例えば,文字型(char)のリテラルの例として'A',string型のリテラルの例として上の例題の"20世紀",整数型のリテラルとして2000などがある.

改行文字 '\n' は余白文字(whitespace character)の1つで,表示されない文字の1つである. \n で1つの文字を表している.これと同じ方法で作られている文字には, '\t' (タブ), '\a' (アラート)などがある.

変数とその宣言(Variables and Their Declarations)

変数はコンピュータのメモリへの格納場所を表す識別子である.その場所に格納された情報を変数の値という.変数は使用する前に必ず宣言されなければならない.変数の値を取り出すには,代入が用いられその構文は
変数 = 式;
となる.最初に式が求められ,その結果が変数に代入される.ここで,等号"="はC++では代入演算子である.

例えば,メモリに格納された整数型の変数mの値5を表示するには,

cout << m;
と書くことができる.

例題 1..3   数値の代入
整数44を変数mに代入し,式m + 33の結果をnに代入するプログラムを作成せよ.

解答 整数44を変数mに代入するには,まず,整数44を格納するための場所と名前が必要なので,int m;と宣言する.同様に,nにはmと整数33の合計が格納されるので,int n;の宣言も必要である.出力は2重引用句の中は記された通りに出力されることを利用し,cout $<<$ "m= " $<<$;とすれば,何を出力しているのか分かりやすくなる.これより,次のようなプログラムとなる.

#include <iostream>
using namespace std;
int main()
{
    int m,n;
    m = 44;
    cout << "m = " << m;
    n = m + 33;
    cout << " and n = " << n << endl;
}

実行結果

\begin{figure}% latex2html id marker 216
\centering\includegraphics[width=8.9cm]{CPPPIC/reidai1-3.eps}
\end{figure}

練習問題 1..3   数値の代入
整数44を変数mに代入し,式m/12の結果を予想し,自分の予想が正しいかプログラムを書いて調べよ.

変数mとnは次のように考えることができる.

\begin{figure}\centering\includegraphics[width=4.9cm]{CPPPIC/fig1-1.eps}
\vskip -0.3cm
\end{figure}

これはまるで郵便受けのようである.変数名mが住所で,44は郵便受けの中身,そして型intが郵便の種類(速達,書留など)である.

この例題で,変数m,nはint m,n;と宣言されているが,同じ型の変数はこのようにまとめて宣言することができる.

C++プログラムでは,全ての変数は使う前に宣言されていなければならない.
その記述法は
    [記憶クラス] [型修飾子] データ型 変数名
となる.

変数の初期化(Initializing Variables)

変数の初期化とは,初めて変数の宣言をしたときに変数に値を代入することである.多くの場合,変数を宣言するときに同時に初期化を行っておくほうが賢明である.C++には,変数の初期化の方法が2通りある.一つは,
int x = 1024;
と書く方法で,もう一つは
int x( 1024 );
と書く方法である.

例題 1..4   初期化していない変数
変数を初期化せずに用いた場合,次のプログラムは何を表示するか調べよ.

{\small #}include <iostream>
using namespace std;
int main()
{
    int m;
    int n = 44;
    cout << "m = " << m << " and n = " << n << endl;
}

実行結果1.

\begin{figure}% latex2html id marker 242
\centering\includegraphics[width=8.2cm]{CPPPIC/reidai1-4.eps}
\end{figure}

実行結果1.はg++で行った結果である.

実行結果2.

\begin{figure}% latex2html id marker 247
\centering\includegraphics[width=8.0cm]{CPPPIC/reidai1-4-1.eps}
\end{figure}

実行結果2.はVC++で行った結果である.

初期化されていない変数は,それぞれのコンパイラで特別な方法で扱われる.

大きなプログラムでは初期化されていない変数がしばしばエラーの原因となるので,変数は初期化するように心がけよう.C言語と異なりC++言語では,変数は使う直前で定義する.そのことにより,プログラムが読みやすくなる.

練習問題 1..4   ()を使った初期化
変数mを3にxを3.1415に2通りの方法で初期化するプログラムを作成せよ.

プログラムトークン(Program Token)

コンピュータプログラムはトークン(token)と呼ばれる要素の並びである.トークンはintなどのキーワード,mainなどの識別子,{などの句読点,$<<$などの演算子を含んでいる.このプログラムをコンパイルするとき,コンパイラはソースコードを走査し,構文解析する.もし,構文エラーを見つけると,コンパイルをやめエラーメッセージを出す.例えば,文の終わりにセミコロンを付けるのを忘れたりすると,セミコロンが欠けているとのメッセージを出す.しかし,括弧を閉じるのを忘れたり,ダブルコーテーションの2つ目を忘れたりした場合は,コンパイラはプログラムのどこかがおかしいとのエラーメッセージを出すだけである.

例題 1..5   プログラムトークン
次のプログラムには何個のトークンがあるか調べよ.

int main()
{ // prints "n = 44";
    int n=44;
    cout << "n = " << n << endl;
}

解答 このソースコードには19個のトークンがある. "int", "main", "(", ")", "{", "int", "n", "=", "44", ";", "cout", "$<<$", ""n= "", "$<<$","n", "$<<$", "endl", ";", "}"

コンパイラはコメントは無視するので,トークンの数には含まれない.

入力演算子(The Input Operators)

C++では入力は,出力と同じくらいに簡単である.入力演算子 $>>$ (get 演算子ともよばれる)は出力演算子と同じように働く.例えば,整数型の変数mにキーボードから数値を呼び込むには,

int m;
cin >> m;
と書けばよい.また,整数型の変数mと2倍長の実数型の変数xにそれぞれ値を読み込むにも,
cin $>>$ m $>>$ x;
でよい.これは,
cin $>>$ m;
cin $>>$ x;
と書くのと同じである.

例題 1..6   型のチェック
次のプログラムを実行するとどんな結果が得られるか考えよ.

#include <iostream>
using namespace std;
int main()
{
    int m,n;
    cout << "2つの整数を入力してください.";
    cin >> m >> n;
    cout << "m = " << m << ", n = " << n << endl;
    double x,y,z;
    cout << "3つの実数を入力してください.";
    cin >> x >> y >> z;
    cout << "x = " << x << ", y = " << y << ", z = " << z << endl;
    char c1, c2, c3, c4;
    cout << "4つの文字を入力してください.";
    cin >> c1 >> c2 >> c3 >> c4;
    cout << "c1 = " << c1 << ", c2 = " << c2 << ", c3 = " << c3
   << ", c4 = " << c4 << endl;
}

実行結果

\begin{figure}% latex2html id marker 285
\centering\includegraphics[width=10.5cm]{CPPPIC/reidai1-6.eps}
\end{figure}

練習問題 1..5   型のチェック
キーボードから入力した356, 3.141592, Aを読んで出力するプログラムを作成せよ.

オブジェクト,変数,定数(Object, Variable, and Constant)

オブジェクトとは,アドレス,サイズ,型,値を持ったメモリの一部である.このオブジェクトは,後に学ぶクラスのオブジェクトとは違うものである. 例えば,オブジェクトnが

int n = 22;
と与えられたとしよう.このとき,メモリのアドレスは0x3fffcd6,サイズは4,型はint,値は22である. 型と値はプログラマーによって決められるが,サイズは使っているコンパイラーによって決められる.例えば,GNU C++ではint はサイズ4だが,Boland C++ではint はサイズ2である.アドレスは使っているコンピュータのオペレーティングシステムによって決められる.
const
をつける.つまり,
const int n = 22;
のようになる. 定数は,宣言されるときに初期化もされなければならない.

例題 1..7   定数の指定
次のプログラムは定数の定義のしかたを表している.

#include <iostream>
using namespace std;
int main()
{
    const char BEEP = 'a';
    const int MAXINT = 2147483647;
    const int N = MAXINT/2;
    const float KM_PER_MI = 1.60934;
    const double PI = 3.14159265358979323846;
}

定数は大文字であらわすのが決まりになっている.

整数と実数(Integers and Real Numbers)

C++では数値を実数と整数で区別する.もっと詳しくいうと,1/2と1/2.0ではまったく違う値になる.1/2は0になり,1/2.0は0.5になる.これは,/という記号が商を表すということが理解できれば簡単になる.

C++の基本データ型の詳しい紹介は2章で行なうが,プログラミングは"習うより慣れろ"なので,幾つか紹介しておく.

例題 1..8   基本データ型(=の両側にはスペースをいれるようにする)
基本データ型を調べよ.

char c = 'A'; /* 文字型*/
short k = 32456; /* 整数型(-32,768 〜 32,767)*/
int i = 2442343434; /* 整数型(-2{31} 〜 2{31}-1の10進整数)*/
long l = 1234L; /* 長い整数(最後尾にLまたはlを付ける)*/
float f = 124.56; /* 実数型(小数点または10の累乗で表し,単精度)*/
double d = 3.1415E3; /*実数型(floatと同形式)d=3141.5を表す*/
double pi = 3.14159265358973; /*実数型(floatと同形式で倍精度)*/
char* p = "C++"; /*"と"で囲まれた文字列*/

charはcharacter(文字)の略,int はinteger(整数),floatはfloat(浮動小数点),voidはvoid(無)のことである.

浮動小数点出力(Floating Point Output)

次のような小数点を含んだデータX,Y,Zがある.

  X[i] Y[i] Z[i]
1 12.24 13.456 234.2345
2 23.345, 32.12, 26.1235
3 432.2, 67.3, 45.2331

これをcoutを用いて

for(int i=1;i <= 3; i++){
    cout << X[i] << " " << Y[i] << " " << Z[i] << endl;
}
と書くと,
12.24 13.345 234.234
23.345 32.12 26.1235
432.2 67.3 45.2331
と表示される.これを桁数を決めて表示したりすることをフォーマット(format)という.C++で,$n$桁表示するには,cout $<<$ の前に,cout.precision(n);が必要である.また,$n$桁に満たない数に0を付けるには,showpointを用いて
for(int i=1;i <= 3; i++){
    cout << showpoint << x[i] << "\t << y[i] << "\t << z[i] << endl;
のようにすればよい.

例題 1..9   フィールド幅 次のデータを桁数4桁で左揃えで出力せよ.

  X[i] Y[i] Z[i]
1 12.24 13.456 234.2345
2 23.345 32.12 26.1235
3 432.2 67.3 45.2331

解答

#include <iostream>
using namespace std;
int main()
{
    float x[3], y[3], z[3];
    x[0] = 12.24, x[1] = 23.345, x[2] = 432.2;
    y[0] = 13.345, y[1] = 32.12, y[2] = 67.3;
    z[0] = 234.2345, z[1] = 26.1235, z[2] = 45.2331;
    cout.precision(4);
    for(int i = 0; i <= 2; i++){
        cout << x[i] << "\t" << y[i] << "\t" << z[i] << endl;
    }
}

実行結果

\begin{figure}% latex2html id marker 336
\centering\includegraphics[width=8.0cm]{CPPPIC/reidai1-7.eps}
\end{figure}

練習問題 1..6   フィールド幅
12.3456を桁数4桁で左揃えで出力するプログラムを作成せよ.

表記(Representation)

CやC++では10進数(decimal),8進数(octagonal),16進数(hexadecimal),指数(exponent)の表記が可能である.8進数の表記には0を数字の前に付け,16進数では0xを付ける.例えば,10進数40を16進数に直すと

    40 = 2 × 16 + 8
となるので0x28となる.C++では,

cout $<<$ hex $<<$ 40;

と書くと,28と表示される.

指数表記では $\rm 1.2 \times 10^{15}$を1.2e15と表す.12.24を科学記号で表すには,

    cout << scientific << 12.24;
と書けばよい.

練習問題 1..7   表記
10進数40を16進数と8進数で出力するプログラムを作成せよ.

確認問題 1..1  

1. C++の2通りコメントの方法を示せ.

2. 次のCスタイルのコメントはどこがいけないのか説明せよ.

cout << "Hello, /* 変更 */ World. \n";

3. 宣言は何をするか.

4. C++で最も短いプログラムは何か

5. 次の宣言はどこがいけないか

int first = 22, last = 99, new = 44, old = 66;

6. 次の2つの文の誤りを見つけ,正しなさい.

a. cout >> count;
b. int double=44;

7. ASCIIコードが100である文字を見つけるためにはどんなプログラムを書けばよいか

8. 次のプログラム中の予約語,識別子,演算子,リテラル,句読点シンボル,コメントを捜し出せ.

int main()

{

int n;

cin $>>$ n;

n *= 3; // n = n*3

cout $<<$ "n = " $<<$ endl;

}

9. 次の2つの文の違いを説明せよ.

char c = 'A';

char c = 65;

10. aのASCIIコードを見つけるコードを書きなさい.

演習問題 1..1  

1. 次のプログラムの誤りを見つけよ.

#include <iostream>
int main()
{
    // "n=22"を表示:
    n = 22;
    cout << "n =" << n << endl;
}

2. 次のような実行結果を得られるように,プログラムの中の□を埋めて,プログラムを完成せよ.

Mainは最初に動く関数.
    coutは表示するための関数.

#include <iostream>
using namespace std;
int main()
{
    cout << "Mainは最初に動く関数.□ coutは表示するための関数.\n";
}

3. 以下の項目で,実数型で表す必要のあるものはどれか.

ア 体重の平均を計算する.

イ 人数の合計をカウントする.

ウ 実行回数をカウントアップする.

4. 以下の空欄を埋めよ.

10進数 16進数 8進数
18
0x25
012
8

5. 以下にC++の構文で表した数字がある.同じ値のものどうしのグループに分けよ.

.25e2, 0x25, 25, 012, 37, 8, e1, 8.e0