追試
試験の採点をしたら、思ったより成績が悪い。 基本情報処理あたりで出題傾向の高い浮動小数点とビットパターンの 問題を導入したが、基本情報処理などを受けた学生以外は、 単純ミスも含めて酷い結果。 平均点も60点程度。
ということで、水曜の段階で追試をアナウンスし、今日の講義中に 追試を実施。しかし、結果を見ると、補数を求めたけど最終結果に マイナスが無かったり、基数が間違っていたり、単純な誤解が残っている。
夏休みは、たっぷり補講か…….はぁ….
リスト処理の導入
前回説明した、配列に次のデータの場所を保存する手法と対比しながら、 リスト構造の説明を行う。次のデータの場所を覚える、末尾には目印として NULLを入れておくなど。
struct List { int data ; struct List* next ; } ; // 最初は、手作業で示す。 struct List* top ; top = (struct List*)malloc( sizeof( struct List ) ) ; top->data = 12 ; top->next = (struct List*)malloc( sizeof( struct List ) ) ; top->next->data = 34 ; top->next->next = (struct List*)malloc( sizeof( struct List ) ) ; top->next->next->data = 56 ; top->next->next->next = NULL ; struct List* p ; for( p = top ; p != NULL ; p = p->next ) printf( "%d\n" , p->data ) ;
簡単な練習として、リスト処理で合計やら検索などを演習させる。 来週は、入力しながらリスト生成などを示す予定。
グラフィックスを用いた仮想関数の演習前説明
グラフィックス表示を例題とした、仮想関数の演習を来週にかけて実施予定。 表示だけの仮想基底クラスをもつ図形クラスから、 異なる図形(三角、丸、四角)のクラスを導出し、 配列に異なる図形クラスを入れ、仮想関数の呼び出しを体験してもらう演習。
機械系・電気系学生は、グラフィックスの扱い自体の経験が少ないので、 Visual C++ を使ったグラフィックスの基礎の説明も行う。
傾向を読まれたか?
情報構造論のテスト結果は、同じ問題は出していないものの、 出題傾向を読まれたのか、思ったより良い成績。 83.1 というのは、なかなか。
# 採点も落ち込むことなく、すんなり終了した。今からレポート採点だ!
仮想関数
6/7(Mon)は、Happy Monday 法の逆の余波により、火曜日の授業に振り替え。 おかげで、6/7,8の連日でオブジェクト指向の授業。 このため講義メモは 2 日分を一括記載。
共用体による異なるデータを1つの配列に保存するプログラム例
導出の概念を簡単に復習し、導出の便利な使い方の一例ということで、 コンテナクラスの概念を説明。コンテナクラス側で、データを扱う 一般的な処理を作成しておき、コンテナクラスを使う時は、自分用 のデータを追加した導出クラスを作成し、継承概念を利用し、 あらかじめ作られているアルゴリズムを使うという説明を行う。
仮想関数の説明として、基底クラスを作成し、導出したクラスで 異なる処理を呼び出すという概念を述べる。しかしこれだけでは、 判りにくいので、C言語による共用体の使い方を説明し、 別に仮想関数の話しをすることにする。
union A { int x ; float y ; char z[ 10 ] ; } ; struct AA { int type ; union A data ; } ; void set_int( struct AA*p , int d ) { p->type = 1 ; p->data.x = d ; } void set_float( struct AA*p , float d ) { p->type = 2 ; p->data.y = d ; } void print( struct AA*p ) { if ( p->type == 1 ) // ディスパッチ処理が羅列される例 printf( "%d\n" , p->data.x ) ; else if ( p->type == 2 ) printf( "%f\n" , p->data.y ) ; } void main() { struct AA a[ 2 ] ; set_int( &a[ 0 ] , 1234 ) ; // a[] に異なるデータが保存できる例 set_float( &a[ 1 ] , 1.234 ) ; for( int i = 0 ; i < 2 ; i++ ) // 異なるデータにメソッドは同じだけど print( &a[ i ] ) ; // 異なる処理が実行されるという説明 }
仮想関数のプログラムの実例
仮想関数の最も簡単な実例として、以下のプログラムを提示する。
// 1行記述が多いのは、シンプル日記の都合上。 class Data { public: virtual void print() = 0 ; // virtual は仮想関数を表すキーワード // =0 は、基底クラスでのメソッドが無いことを表す } ; class DataInt : public Data { private: int x ; public: void set( int d ) { x = d ; } virtual void print() { printf( "%d" , x ) ; } } ; class DataFloat: public Data { private: float y ; public: void set( float d ) { y = d ; } virtual void print() { printf( "%f" , y ) ; } } ; void main() { DataInt b ; b.set( 1234 ) ; DataFloat c ; c.set( 1.234 ) ; Data* a[ 2 ] ; a[0] = &b ; // 派生クラスポインタは基底クラスポインタに型変換可能 a[1] = &c ; for( int i = 0 ; i < 2 ; i++ ) a[ i ]->print() ; // 仮想関数の呼び出し }
仮想関数と union での事例の比較として、次の点を強調する。
- if文ディスパッチャが無くなっている事、
- 型識別ID の保存処理が無い事、
仮想関数の実装のための補助知識
仮想関数の実装方法の知識として、関数ポインタの説明を行う。
switch文、文字列処理、試験後の範囲の前説(OSについて)
プログラムの基本文法の説明時に、switch 文の説明が不完全で、過去問が 解らないという質問者があったので、switch 文の説明。 よくある間違った使用例ということで、定数式部に、文字列を書く間違いを紹介す る。 これに伴い、C言語の文字列処理の標準関数として、strcmp , strcpy 等を、 コーディングと共に処理を説明する。
この際に、strcmp,strcpy を文字列処理を配列的に記述する例や、ポインタ操作で行 う例を 示す。そのときに、while( *p++ = *q++ ) ; といったC言語特有の省略記法の解説、 i++,++iの違いなどを説明する。
後半は、中間試験後の導入として、ファイル処理の講義予告と、OSに関連した説明を 行う。 特に、OSはコンピュータ資源アクセスのための共通処理の提供と、 コンピュータ資源の不当アクセスを許さないための機能の話しを、 特権モード・ユーザモードの話しを交えながら口頭で説明する。
ヒープ総括+リスト構造導入ネタ+試験勉強
シラバスの予定を見ると、今回は無理に授業を進める必要はなさそうなので、 復習を中心とした話しと、試験勉強とする。 最初に、1/4程度の時間で malloc の説明を実施。 次に中間試験後の授業のために、リスト構造のイメージを説明する講義。 整列された配列データの中間にデータを挿入しようとするときの、 O(N)の処理効率の悪さを説明し、 次のデータの場所を配列のindexで実装した例を、イメージ+簡単なプログラムで説明。
残りの半分の時間は、自由な試験勉強時間とする。 半数は演習室にて課題作成。 残りの学生は、オーダ記法や再帰方程式などの質問をしてきたので、解説を行う。 前回フィボナッチ数列の説明が怪しかった時の宿題を、 教室に掲示していないことが判明。印刷して掲示しに行こう!
シラバスデータの整理
JABEEの自己点検表のためのデータ整理として、シラバス記載の中から目標と評価方 式を 抜粋した資料を作成している。まだ終らない….
WWWによる一括データ管理システムがあれば理想なんだが、 福井高専内部のシラバスの細かい記載ルールに対応したものが簡単に作れる訳でもな く、 延々とExcel整理。下手にWWWで管理すりゃ便利なのに、なぜしないの?というと、 「じゃぁ、斉藤さんお願いします!!」になりかねない。
Excelから必要なものを抜き出しながら、2次資料、3次資料をまとめるシステムがあ れば それなりに可能なんだろうけど、 これまた「できる!」というと、「お願いします!」になるんだろーな。
継承の説明
隠蔽化の次のネタということで、継承(inheritance)・導出の説明。 社員・上司・社長といったデータ例を説明し、 C言語レベルで社員を要素に持つ上司という構造体を作ると、 上司のデータアクセスに余計な手間がかかる例を説明。 こういった共通部分が多いけど、 オプショナルな要素を加えた新規データの事例が多いことを説明。 このなかで GUI などの事例で、OOPが成功したことを話す。
以下のようなプログラムを示し、基底クラス、派生(導出)クラス といった用語を説明する。 別表現でスーパークラス・サブクラスなどの用語も示す。
class Syain { // 日記の都合上、1行書きスタイル private: char name[ 30 ] ; int age ; public: void set( char s[] , int a ) { strcpy( name , s ) ; age = a ; } void print() { printf( "%s %d" , name , age ) ; } } ; class Jyoshi : public Syain { private: Syain *buka[ 10 ] ; int size ; public: Jyoshi() { size = 0 ; } void add( Syain* p ) { buka[ size++ ] = p ; } } ; void main() { Syain a ; a.set( "斉藤" , 39 ) ; Syain b ; b.set( "坂本" , 39 ) ; Jyoshi m ; m.set( "柴田" , 65 ) ; // 継承だからできる技であることを強調 m.add( &a ) ; m.add( &b ) ; }