第二回-01 : C/C++ プログラムの構造

ここでは、典型的な C/C++ プログラムがどのような構造をしているかを提示し、 同時に今後頻出する用語の解説を行う。


C プログラムの構造

典型的な C プログラムは以下のような構造をしている。
このプログラムの意味は解説しないので、実際に動作させて意味を理解すること。

#include <stdio.h>

int factorial(int n);  // 関数のプロトタイプ (宣言)

int factorial(int n){  // 関数の定義
  int i;
  int val=1;

  for(i=1; i<=n ; i++){
    val = val * i;
  }

  return(val);
}

int main(){            // main 関数

  int x=5;
  int y;

  y = factorial(x);

  printf("%d! is %d\n",x,y);

  return 0;
}


C 言語で最も重要な機能の一つが上の例にあるような「関数」であろう。

関数とはいくつかの処理をまとめ、一つの機能として提供するモジュールである。
関数には任意の処理をさせることができるが、 上の例のように、ある数値に対する操作を関数として提供する場合を考えよう。

このとき、関数が処理する対象 (数値) は引数として処理の結果は戻り値として渡されることが重要である。

上の例では、「y=factorial(x);」なる命令が呼び出されたとき、 xの値が引数として渡され、またその結果は y に格納される。
このとき、関数 factorial は x の値に対して処理を行うのであるが、 関数 factorial 自体はどのような変数が引数として渡されるか 想定していない。
すなわち、関数 factorial と変数 x の結びつきは弱い

以上を念頭において、次の C++ プログラムの構造へ進もう。

C++ プログラムの構造

C プログラムが関数を基礎としていたのに対して、C++ プログラムはクラスを基本としている。
上の C プログラムに対応する C++ プログラムは以下のようになるだろう。

#include <iostream>
using namespace std;

// クラス宣言部
class myclass{
  private:
   int n;            // データメンバの宣言

  public:
   int factorial();  // メンバ関数の宣言
   int get();
   void set(int m);
};

// クラス実現部
int myclass::factorial(){  // メンバ関数の定義は 「(戻り型) (クラス名)::(関数名)」のように行う
  int val=1;

  for(int i=1; i<=n ; i++){   // C++ では for 文の () 内で int i の宣言が可能
    val = val * i;
  }

  return(val);
}

int myclass::get(){
  return(n);
}

void myclass::set(int m){
  n=m;
}

// クラス利用部 (main 関数)
int main(){

  myclass x;   // 定義したクラスを新しい型として利用

  x.set(5);

  cout << x.get() << "! is "  << x.factorial() << "\n";

  return(0);
}

この例では「myclass」というクラスを例として定義し、main 関数で利用している。
そもそもクラスとは何であるかを定義しなければならないが、ここでは と考えよう。この定義に従って上のプログラムを解説する。

まず、下の図に示すように、myclass クラスは、データメンバ n およびメンバ関数 get()set(m)factorial() からなる。

これらは以下の特徴を持っている。 このように、クラスのメンバ関数はデータメンバ (ここでは n) に対する処理を専門に行う。
すなわち、クラスのメンバ関数は、Cの関数と異なり、処理の対象が明確であるという特徴がある。

さらに、宣言したクラス (myclass) は、プログラムの他の部分 (ここでは main 関数) において新しい型として利用できる。
上の例では main 関数の「myclass x;」という行が myclass クラスのオブジェクト x の宣言である。
これは、C プログラムの「int x;」のように myclass を新しい型として用いていることになる。

C++ を代表とするオブジェクト指向言語では、データメンバとメンバ関数で構成されるクラスを基礎としてプログラミングを行う。
上のような小さな例では、「データ+メンバ関数」という組でプログラミングを行うメリットが見えにくいかもしれない。
しかし、例えば以下のような GUI (Graphical User Interface) を持つアプリケーションを考えてみよう。



このようなアプリケーションでは、ボタンを押すと何か処理が行われるのが普通である。
アプリケーションの内部を考えると、これはボタンを押すことで関数が呼ばれて処理が行われることに相当する。
この「ボタンを押したときに呼ばれる関数」は「ボタン」というオブジェクトと強い結び付きがあることがわかるだろう。
すなわち、「ボタンを押したときに呼ばれる関数」は「ボタンクラス」のメンバ関数として実現されるのが自然である。

このように、Windows を含め、GUI を持ったアプリケーションのプログラミングには クラスの知識はほぼ必須と言える。
そして、GUI アプリケーションに限定せず、クラスを基礎にすえてプログラミングを行おうという方法論がオブジェクト指向プログラミングである。

なお、C 言語版との違いとして「画面出力用に printf ではなく cout を用いている」点に気づくかもしれないが、これはさほど重要ではない。
C++ は (ほぼ) C を拡張する形で作られているので、C++ で printf を用いることも可能である。
同様に、C++ で C 言語的な関数を用いることも可能である。(ただし、あまり行われない)



←第一回演習第二回-02 : stack クラスの動作→

第二回演習用 web ページへ

クラスから入る C++ へ戻る