UP | HOME

第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 というファイルを作り,ソースコードを書き込む.

  1. Emacs を起動して ~/cpp/sample1-1.cpp というファイルを作成する(C-x C-f ~/cpp/sample1-1.cpp)
  2. 作成した 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::coutstd::endl というマニピュレータ(操作子)を渡している. 出力ストリームが std::endl を受け取ると,それまでに蓄えていたバッファと改行を出力し,バッファをフラッシュする.

  • 最後のセンテンス
    return 0;
    

    は, main 関数ブロックを抜け出し, main 関数の呼び出し元(この場合はシェル)に整数(int)型のオブジェクト 0 を返すことを指示している.

5 サンプルプログラム1-2 を実行しよう

5.1 サンプルプログラム 1-2 を作る

~/cpp ディレクトリの下に sample1-2.cpp というファイルを新に作り,別のソースコードを書き込もう.

  1. Emacs を起動して ~/cpp/sample1-2.cpp というファイルを作成する(C-x C-f ~/cpp/sample1-2.cpp)
  2. 作成した 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::coutstd::endl というように 名前空間 つきで呼んでいた. しかし, 他に coutendl がいないのに,わざわざ名字をつけてフルネームで呼ぶのは面倒くさい.
  • そこで,3行目のセンテンス
    using namespace std;
    

    で,名前空間として std をデフォルトの名前空間として使うことを宣言している.これにより, std::coutstd::endl を, 名字なしで coutendl と呼び出せる.

  • 7行目のセンテンスで
    cout << "私の" << "名前は ";
    

    としていることに注意されたい.出力演算子 << は,その左辺にストリーム, と右辺にオブジェクトを引数とし, 「左辺のストリームに右辺のオブジェクトを渡す」という動作の後, ストリームを戻り値として返すように定義されている. つまり,上述の式は,まず

    cout << "私の"
    

    の部分が評価されて cout に "私の" という文字列オブジェクトが格納(バッファ)された後, それ自体が cout として評価され,その次に << "名前は"=

    << "名前は ";
    

    の部分が評価される際に,出力演算子の右辺として cout が渡され,

    cout << "名前が ";
    

    として評価されるのである.

  • C++ はセンテンス途中の改行やインデントに関する規則がかなりルーズである.従って, 8〜9行目のように
    cout << "川内 情太郎"          // センテンスの途中で改行を入れてもよい
         << " です";               //
    

    としても,

    cout << "川内 情太郎" << " です";
    

    と同じ内容として解析される.

7 サンプルプログラム1-3 を元に自分の名前と誕生日を出力させよう

7.1 サンプルプログラム 1-3 を作り,コンパイルし,実行してみる

~/cpp ディレクトリの下に sample1-3.cpp というファイルを新たに作り,別のソースコードを書き込もう.

  1. Emacs を起動して ~/cpp/sample1-3.cpp というファイルを作成する(C-x C-f ~/cpp/sample1-3.cpp)
  2. 作成した sample1-3.cpp の中身を以下のように編集して保存する(C-x C-s)
  3. 端末もしくは Emacs 上で sample1-3.cpp をコンパイルして sample1-3.o という実行ファイルを作る
    g++ sample1-3.cpp -o sample1-3.o
    
  4. 生成されたファイルを実行してみる
    ./sample1-3.o
    

7.2 C++ の型について

C++ では,ダブルクォートで囲まれた文字:

"文字列"

文字列オブジェクト (特に指示が無ければ char 型の定数配列)として認識する.

ダブルクォートで囲まない数値は,その内容に応じて, int (整数)型 もしくは double (倍精度実数)型の(数値)オブジェクトと認識される. 例えば, 1998, 4, 31 などは,いずれも int (整数)型として認識される.

ダブルクォートで囲まれておらず,数値でないもの (coutendl)は, 定義済み のオブジェクトと認識される. 例えば,学籍番号 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 をベースにして,自分の名前,学籍番号および生年月日を出力させるプログラムを作ってみよう.

Author: Takeshi Nagae

Created: 2014-06-06 Fri 15:56

Emacs 24.3.1 (Org mode 8.2.5h)

Validate