プログラム再構成に関する 特許申請について

プログラミング言語論
第九回
理工学部
情報システム工学科
新田直也
課題2のプログラムについて

掟その1: 式の型を調べること.
main() {
int *a;
func(&a);
*a = 10;
printf("before dummy: [%d]\n", *a);
dummy();
printf("after dummy: [%d]\n", *a);
}
func(int **x) {
int y = 0;
*x = &y;
}
int
*a
a
&a
**x
*x
x
y
&y
課題2のプログラムについて

掟その2: 確保されている領域を調べること.
main() {
int *a;
func(&a);
*a = 10;
printf("before dummy: [%d]\n", *a);
dummy();
printf("after dummy: [%d]\n", *a);
}
func(int **x) {
int y = 0;
*x = &y;
}
main 内の
自動変数
int
定数
*a
a
&a
**x
*x
x
y
&y
func 内の
自動変数
func 内
の仮引数
課題2のプログラムについて

掟その3: 代入文を調べること.
main() {
int *a;
func(&a);
*a = 10;
printf("before dummy: [%d]\n", *a);
dummy();
printf("after dummy: [%d]\n", *a);
}
func(int **x) {
int y = 0;
*x = &y;
}
int
*a
**x
a
*x
&a
**x
*a
**x
y
*x
x
&y
オブジェクト指向の歴史

実は起源は明らかではない.



チューリング賞:



Simula67: クリステン・ニガード, オルヨハン・ダール
SmallTalk72: アラン・ケイ
2001年 クリステン・ニガード, オルヨハン・ダール
2003年 アラン・ケイ
現在の主流


C++: ビャーネ・ストロヴストルップ (1979年)
Java: ジェームズ・ゴスリング, SUN (1991年)
オブジェクト指向の主要概念

オブジェクト指向を特徴付ける3つの概念:

カプセル化(クラス):
データとそれに関連する手続きを一体化し,他の部分から
分離(隠蔽)すること.分離した部分をクラスと呼ぶ.クラス
は言語中では型としての役割を持つ(抽象データ型).

継承:
あらかじめ基本となる機能を(親クラスとして)定義し,その
機能を引き継ぐ形で拡張機能(子クラス)を定義すること.

多態性(ポリモルフィズム):
オブジェクトの種類(クラス)を知ることなくその機能を使える
ようにする仕組み.(遅延束縛,動的結合)
モジュールプログラミング

カプセル化はC言語でも実現されている.

モジュールプログラミング:
プログラムを機能毎に複数のモジュール(ファイル)
に分けて開発する手法.C言語では分割コンパイル
でサポートされている.

情報隠蔽,関心事の分離,カプセル化.
モジュールの例

配列を用いたリストモジュール(list.c)
《list.c》
《list.h》
#include “list.h”
#define MAX_LIST 1000
void init_list(List *lp) {
lp->num = 0;
}
typedef struct LIST {
int num;
int v[MAX_LIST];
} List;
int read_list(List *lp, int k) {
return lp->v[k];
}
:
void init_list(List *lp);
int read_list(List *lp, int k);
:
モジュールによる情報隠蔽

関数の定義(実装)はカプセル化され隠蔽される.
《list.c》
#include “list.h”
void init_list(List *lp) {
lp->num = 0;
}
int read_list(List *lp, int k) {
return lp->v[k];
}
:
情
報
隠
蔽
他のファイル
から見えない
モジュールの利用方法

モジュールはヘッダ(list.h)を通じて利用.
《list.c》
#include “list.h”
void init_list(List *lp) {
lp->num = 0;
}
int read_list(List *lp, int k) {
return lp->v[k];
}
:
#include “list.h”
:
List l;
init_list(&l);
:
list.h が橋渡し
(インタフェース)の役割
実装の変更(1)
たとえばリストを線形リストを使うように変更.
 赤で示した部分が変更箇所,インタフェースは固定.

《list.c》
#include “list.h”
void init_list(List *lp) {
lp->next = NULL;
}
int read_list(List *lp, int k) {
List *p;
int n;
for (n = 0; n < k && …) {
:
《list.h》
typedef struct LIST {
int v;
List *next;
} List;
void init_list(List *lp);
int read_list(List *lp, int k);
実装の変更(2)

呼び出し側はまったく変える必要がない.
《list.c》
#include “list.h”
void init_list(List *lp) {
lp->num = NULL;
lp->next
0;
}
int read_list(List *lp, int k) {
List
return
*p; lp->v[k];
}int n;
for (n = 0;
: n < k && …) {
:
#include “list.h”
:
List l;
init_list(&l);
:
list.h が橋渡し
(インタフェース)の役割
モジュールプログラミングのまとめ

モジュールプログラミング:

モジュール中の大域変数と関数定義はカプセル化され,
他のモジュールから隠蔽される.

モジュールのインタフェースは公開される.

利用者はインタフェースのみ知っていれば利用できる.

利用者は実装の変更の影響を受けない.
クラス

抽象データ型を直接表現したもの.
関数を構造体の中に入れたものと考えてもよい.
struct List {
int list[LIST_MAX];
int num = 0;
};
void init_list(struct List *lp) {
lp->num = 0;
}
int get_list_num(struct List *lp) {
return lp->num;
}
:
class List {
int list[LIST_MAX];
int num = 0;
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
}
クラスの定義

クラスは,メンバ変数(フィールド)とメンバ関数
(メソッド)によって構成される.
class List {
int list[LIST_MAX];
int num = 0;
}
void init_list(void) {
num = 0;
}
int get_list_num(void) {
return num;
}
:
メンバ変数
メソッド