プログラミング言語論 第九回 理工学部 情報システム工学科 新田直也 課題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; } : メンバ変数 メソッド
© Copyright 2024 ExpyDoc