第8回 アカデミックスキルII C言語(1) 「端末」の使い方とC言語さいしょの一歩
Table of Contents
1 このページの更新履歴
2 「端末」の使い方に慣れる
2.1 端末の使い方の基本を学ぶ
端末の使い方 を読んで端末の起動方法や基本的なコマンドを学ぶ
2.2 前回のレポートを適当なディレクトリに整理する
多くの人が,現在,全てのファイルをホームディレクトリ(~/
)の下に置いているものと思われる.
まずは,適当なディレクトリを作って,その中にこれらを整理しておこう.
その際,練習のつもりで「端末」を使ってみよう.
例えば, ~/2014ICL-B/report1
というフォルダを作成するには,端末で
mkdir ~/2014ICL-B # ~/ の下に 2014ICL-B を作成 mkdir ~/2014ICL-B/report1 # ~/2014ICL-B の下に report1 を作成
を順に実行すればよい.
3 C++プログラミングことはじめ(サンプルプログラム1-1)
3.1 作業用ディレクトリを作り,移動する.
まずは C++プログラム用に ~/cpp
というディレクトリを作り,そこに移動しよう.
これは,端末で以下を入力することでできる.
mkdir ~/cpp # ~/cpp というフォルダを作る cd ~/cpp # ~/cpp に移動する
3.2 サンプルプログラム 1-1 を作る
~/cpp
ディレクトリの下に sample1-1.cpp
というファイルを作り,ソースコードを書き込む.
- Emacs を起動して
~/cpp/sample1-1.cpp
というファイルを作成する(C-x C-f ~/cpp/sample1-1.cpp
) - 作成した
sample1-1.cpp
の中身を以下のように編集して保存する(C-x C-s
)
3.3 コンパイルする
作成した ~/cpp/sample1-1.cpp
を計算機上で実行可能な形式になるようにコンパイルする.
コンパイルするには g++
というコマンドを使う. 一般的によく使う g++
の書式は以下の通り:
g++ ソースファイル名 [-o 出力ファイル名]
例えば, 現在のディレクトリにある sample1-1.cpp
というソースファイルをコンパイルして sample1-1.o
という実行可能ファイルを作りたい場合は,
g++ sample1-1.cpp -o sample1-1.o
とする. -o 出力ファイル名
は省略できる(省略した場合はデフォルトで a.out
というファイルになる).
上述のコマンドは Emacs からでも端末からでも実行できる.どちらも試しておこう.
3.3.1 Emacs で g++ を実行する場合
platex
などと同じく,Emacs で M-!
(shell-command)としてからコマンドを入力する:
M-! g++ sample1-1.cpp -o sample1-1.o
Emacs 上の shell-command にはこれまで入力した履歴が保存されており,カーソルの上下で呼び出せる.
3.3.2 端末で g++ を実行する場合
- まずは,端末を立ち上げ
~/cpp
ディレクトリに移動するcd ~/cpp # cd はディレクトリを移動するコマンド
- コマンドを入力する
g++ sample1-1.cpp -o sample1-1.o
端末でのコマンド入力をよりスムーズに行うために,以下の2つは覚えておくと良いだろう:
- Emacs と同様,これまでに入力したコマンドの履歴が保存されており,カーソルの上下で呼び出せる
- ファイル名などをある程度(e.g.
sam
くらいまで)入力してからTAB
を押すと,ファイル名を補完してくれる.
3.4 コンパイルしたファイルを実行する
生成された sample1-1.o
を実行しよう. ~/cpp
は実行ファイルを検索するパスに含まれていないため,
端末から実行する際には, ./sample1-1.o
と「現在のディレクトリ(./
)にある sample1-1.o
」であることを明示的に指定してやる必要がある.
3.4.1 端末から sample1-1.o
を実行する場合
- 端末を起動して
~/cpp
に移動する.既に端末が動いているなら,pwd
コマンドを使って現在のディレクトリが~/cpp
であればそのままでよい.pwd # pwd は現在のディレクトリを調べるコマンド ~/cpp # ~/cpp と表示されれば OK cd ~/cpp # 違うディレクトリが表示された時は cd コマンドで移動
sample1-1.o
を実行する../sample1-1.o # ./ を頭につけて現在のディレクトリであることを明示 ### どんな結果が表示される? ###
3.4.2 Emacs から sample1-1.o
を実行する場合
コンパイル時と同様に M-!
(shell-command) を使えばよい
M-! ./sample1-1.o
4 sample1-1.cpp
の解説
4.1 C++ プログラムの(荒っぽい)基本的構成要素
- C++ プログラムの基本的構成要素は センテンス および ブロック である.
- センテンスは
;
で区切られる. - センテンスは,宣言(定義), 評価, 命令 などの種類がある.
- ブロックは, 宣言の後,
{
(波開き括弧) で始まり,}
(波閉じ括弧)で終わる. - 1つのブロックの中には複数のセンテンスや,別のブロックが含まれることがある.
- C++は,センテンスの区切り(
;
)やブロックの開始/終了({}
)には厳しいが, 改行やインデントについてはルーズ. //
から行末まではコメントとして判断され,解析されない
4.2 main
関数の構造
- C++ プログラムの中心的挙動は
main
関数で定義される. main
関数は以下のような構造をしている.int main (void) { センテンス1; センテンス2; : : }
int main (void)
の行は関数の戻り値(型) 関数名 (引数の宣言)
の書式で記述されている.
- 最初の
int
は,main
関数が「整数型」と呼ばれる オブジェクト を 戻り値 とすることを意味している. 言い換えると,main
関数を評価したものは,整数型のオブジェクトとして扱われる. - 次の
main
は 関数の名前を指示している. (void)
は,main
関数が引数をとらないことを指示している.
- 最初の
4.3 C++ での標準出力
- C++ で画面に何かを出力するには,標準出力ストリームを用いる.標準出力ストリームを使うためには,ライブラリとして
<iostream>
を読み込む必要がある.これは,以下のセンテンスで指示されている.#include <iostream>
- 標準出力ストリームは
std::cout
という名前で<iostream>
ライブラリ内に定義されている std::
は<iostream>
で使われる 名前空間 である.名前空間は「名字」のようなもので,cout
という名前が他で使われた時にバッティングしないようにできる.- C++ のセンテンスは
;
で区切られる. - 出力ストリームに何らかの オブジェクト を渡すには,出力演算子
<<
を用いて出力ストリーム << オブジェクト
とする.
- 最初のセンテンス
std::cout << "私の名前は 川内 情太郎 です";
では,標準出力ストリーム
std::out
に文字列オブジェクト"私の名前は 川内 情太郎 です" を渡している.
- 次のセンテンス
std::cout << std::endl;
は,標準出力ストリーム
std::cout
にstd::endl
というマニピュレータ(操作子)を渡している. 出力ストリームがstd::endl
を受け取ると,それまでに蓄えていたバッファと改行を出力し,バッファをフラッシュする. - 最後のセンテンス
return 0;
は,
main
関数ブロックを抜け出し,main
関数の呼び出し元(この場合はシェル)に整数(int
)型のオブジェクト 0 を返すことを指示している.
5 サンプルプログラム1-2 を実行しよう
5.1 サンプルプログラム 1-2 を作る
~/cpp
ディレクトリの下に sample1-2.cpp
というファイルを新に作り,別のソースコードを書き込もう.
- Emacs を起動して
~/cpp/sample1-2.cpp
というファイルを作成する(C-x C-f ~/cpp/sample1-2.cpp
) - 作成した
sample1-2.cpp
の中身を以下のように編集して保存する(C-x C-s
)
5.2 コンパイルする
いま作った sample1-2.cpp
をコンパイルして sample1-2.o
という実行ファイルを作成しよう.
sample1-1
に対する処理と同じように,端末や Emacs で以下を実行する:
g++ sample1-2.cpp -o sample1-2.o
5.3 コンパイルしたファイルを実行する
端末や Emacs から sample1-2.o
を実行してみよう. 現在のディレクトリ(./
)を指定するのを忘れないように!
./sample1-2.o
6 sample1-2.cpp
の解説
sample1-1.cpp
では, 標準出力ストリームやマニピュレータをstd::cout
やstd::endl
というように 名前空間 つきで呼んでいた. しかし, 他にcout
やendl
がいないのに,わざわざ名字をつけてフルネームで呼ぶのは面倒くさい.- そこで,3行目のセンテンス
using namespace std;
で,名前空間として
std
をデフォルトの名前空間として使うことを宣言している.これにより,std::cout
やstd::endl
を, 名字なしでcout
やendl
と呼び出せる. - 7行目のセンテンスで
cout << "私の" << "名前は ";
としていることに注意されたい.出力演算子
<<
は,その左辺にストリーム, と右辺にオブジェクトを引数とし, 「左辺のストリームに右辺のオブジェクトを渡す」という動作の後, ストリームを戻り値として返すように定義されている. つまり,上述の式は,まずcout << "私の"
の部分が評価されて
cout
に "私の" という文字列オブジェクトが格納(バッファ)された後, それ自体がcout
として評価され,その次に << "名前は"=<< "名前は ";
の部分が評価される際に,出力演算子の右辺として
cout
が渡され,cout << "名前が ";
として評価されるのである.
- C++ はセンテンス途中の改行やインデントに関する規則がかなりルーズである.従って,
8〜9行目のように
cout << "川内 情太郎" // センテンスの途中で改行を入れてもよい << " です"; //
としても,
cout << "川内 情太郎" << " です";
と同じ内容として解析される.
7 サンプルプログラム1-3 を元に自分の名前と誕生日を出力させよう
7.1 サンプルプログラム 1-3 を作り,コンパイルし,実行してみる
~/cpp
ディレクトリの下に sample1-3.cpp
というファイルを新たに作り,別のソースコードを書き込もう.
- Emacs を起動して
~/cpp/sample1-3.cpp
というファイルを作成する(C-x C-f ~/cpp/sample1-3.cpp
) - 作成した
sample1-3.cpp
の中身を以下のように編集して保存する(C-x C-s
) - 端末もしくは Emacs 上で
sample1-3.cpp
をコンパイルしてsample1-3.o
という実行ファイルを作るg++ sample1-3.cpp -o sample1-3.o
- 生成されたファイルを実行してみる
./sample1-3.o
7.2 C++ の型について
C++ では,ダブルクォートで囲まれた文字:
"文字列"
を 文字列オブジェクト (特に指示が無ければ char
型の定数配列)として認識する.
ダブルクォートで囲まない数値は,その内容に応じて, int
(整数)型 もしくは
double
(倍精度実数)型の(数値)オブジェクトと認識される.
例えば, 1998
, 4
, 31
などは,いずれも int
(整数)型として認識される.
ダブルクォートで囲まれておらず,数値でないもの (cout
や endl
)は,
定義済み のオブジェクトと認識される.
例えば,学籍番号 B4TB9999
などは数値ではないため,
cout << B4TB9999;
とすると,コンパイルの際に
sample1-3-error.cpp:7:11: error: use of undeclared identifier 'B4TB9999' cout << B4TB9999; ^ 1 error generated.
というエラーメッセージ(「 B4TB9999
という定義されていない識別子が使われました」)が表示される.
学籍番号 B4TB9999
を標準出力ストリームに渡したい場合には,
cout << "B4TB9999";
とダブルクォートで囲んで「文字列オブジェクト」としなければならない.
7.3 自分の名前,学籍番号および生年月日を出力させるプログラムを作ってみよう
sample1-3.cpp
をベースにして,自分の名前,学籍番号および生年月日を出力させるプログラムを作ってみよう.