ホーム » 2009 (ページ 23)
年別アーカイブ: 2009
泡は出ないのかょ…
職場の売店の新商品のお茶。 ラベルを見ると泡を期待してしまう…
純粋仮想クラス
先週の仮想関数のより実践的な使い方として、 純粋仮想クラスの使い方を紹介する。
この方法を使えば、新しいデータ構造が必要となっても、 基底クラスから派生させたデータ構造と、 必要最小限の仮想関数の定義だけで、プログラムが書けることを強調する。
C言語を習っただけの学生対象の授業であるため、"using namespace std;" といった文法は一切使わない。
#include <stdio.h> #include <string.h> // 純粋仮想基底クラス // 処理を呼び出すためだけの目的の入れ物クラス class Object { public: // データを比較するための仮想関数。 // 単なる入れ物なので、比較する処理を書けない virtual int cmp( Object* ) = 0 ; // データを表示するための仮想関数 virtual void print() = 0 ; } ; // データの並べ替えをする関数 void sort( Object* array[] , int size ) { // 最大選択法 for( int i = 0 ; i < size - 1 ; i++ ) { int m = i ; for( int j = i + 1 ; j < size ; j++ ) { // array[i]とarray[j]を比較。 // array[i]>array[j] なら正の値 // = なら0 , < なら負の値 int ans = array[m]->cmp( array[j] ) ; // より大きい値を見つけたらmに場所を保存 if ( ans < 0 ) m = j ; } // i+1〜最後の範囲の最大(m番目)と先頭を入替え Object* tmp = array[ i ] ; array[ i ] = array[ m ] ; array[ m ] = tmp ; } } // Objectに整数を追加したデータ class Integer : public Object { private: int data ; public: // 整数データのコンストラクタ Integer( int x ) : data( x ) {} // 整数の比較を行う仮想関数を具体的に定義 virtual int cmp( Object* p ) { return data - ((Integer*)p)->data ; } // データを表示する仮想関数を具体的に定義 virtual void print() { printf( "%d\n" , data ) ; } } ; // Objectに文字列を追加したデータ class Cstring : public Object { private: char const*const data ; public: Cstring( char const*const s ) : data( s ) {} // 整数の比較を行う仮想関数を具体的に定義 virtual int cmp( Object* p ) { return strcmp( ((Cstring*)p)->data , data ) ; } // データを表示する仮想関数を具体的に定義 virtual void print() { printf( "%s\n" , data ) ; } } ; int main() { // 配列aに72,12,25,6を保存 Object* a[] = { new Integer( 72 ) , new Integer( 12 ) , new Integer( 25 ) , new Integer( 6 ) } ; // データを並び替える sort( a , 4 ) ; // 並び替えた結果の表示 for( int i = 0 ; i < 4 ; i++ ) a[ i ]->print() ; // Cstringでも使えることを実験 Object* b[] = { new Cstring( "orange" ) , new Cstring( "grape" ) , new Cstring( "apple" ) , new Cstring( "pine apple" ) , new Cstring( "peach" ) , } ; sort( b , 5 ) ; for( int i = 0 ; i < 5 ; i++ ) b[ i ]->print() ; return 0 ; }
C++の文法をちゃんと使おう
比較関数int cmp( Object* ) における、型キャストが説明不足なので、 C言語の基礎知識としてのキャスト演算子の説明(実数整数変換を例とした)を行う。
ただし、C言語の型キャストでの方式は、時代に乗り遅れているので、 このページ上は最近のキャストの使い方を記載しておこう。
最近のC++であれば、以下のような書き方をすべき。
virtual int cmp( Object* p ) { Integer* ip = dynamic_cast<Integer*>(p) ; if ( ip != NULL ) return data - p->data ; } else { return 0 ; // 比較に失敗 } }
工場見学旅行の行き先選定中
3EIの担任として、工場見学旅行の見学先を選定中。 今のところの腹案は、下記4ヶ所。
- 東芝セミコンダクタ四日市工場
- 三菱重工飛島工場
- 中部国際空港(セントレア)
- トヨタ九州・宮田工場
これに加え、九州の観光地を抜粋一覧として、特活時間に配布して、アンケートに 記入してもらった。予想外に「温泉」の希望が多かった。
# 毎日温泉つかるのかよぉ….
この後は、見学工場を最終決定し、観光見学先希望を提出すると、 複数業者が複数の工程案を示してくれ、その中から1つを選び、 選定旅行会社と最終的な細かな調整を経て、最終案とする予定。
6/4追記:集計結果(上位のみ)
- スペースワールド(14)
- マリノアシティ福岡(アウトレットモール)(10)
- 別府温泉(地獄めぐり)(28) / (2:湯布院(17),3:霧島(11))
- 阿蘇山(16)
最近のGC
4年の情報構造論では、最後にはガベージコレクタなどの話を行うが、 最近のGCの情報。 Java SE6 では、G1 GC なるガベージコレクタが実装されているらしい。 寿命の短いデータ用の領域(Young領域)と、寿命の長いデータ用(Old領域) に分け、Young領域のEden領域がいっぱいになれば、Survivor領域なりOld領域に、 Copy法で移動したり廃棄したり。Old領域はMark&Sweep法でやるそうな…
人間の脳みそで、睡眠時に短期記憶領域から長期記憶領域にコピーされるのと 似ているんだけどね。
2進数の扱いとビット演算
N進数の話が大体終わったけど、計算機構成論の内容にも関連するということで、 2進数演算・ビット演算の演算子の説明と、2進数を用いた乗算処理を説明する。
int mul( int x , int y ) { int s = 0 ; while( y != 0 ) { if ( y % 2 != 0 ) s += x ; y /= 2 ; x *= 2 ; } } void main() { printf( "%d\n" , mul( 11 , 10 ) ) ; }
この関数を示し、計算結果を予想してもらい、その後でこの計算が、 2進数による乗算であることを示し、この考え方を計算機構成論の 乗算回路あたりで習うであろうことを説明する。
1011 x)1010 ------ 0000 10110 000000 +)1011000 --------- 1101110)2 = 110)10
ビット演算子
乗算の説明の後、2での割り算や乗算がビットシフトであることの説明をして、 この結果を踏まえ、<<>>,^,~などの演算子を説明する。
AND | & | ビット論理積 |
OR | | | ビット論理和 |
EXOR | ^ | ビット排他的論理和 |
左シフト | << | ビット左シフト |
右シフト | >> | ビット右シフト |
これに加え、このような演算子には、自己代入型の、 *=,/=,&=,|=,<<=,>>= などの紹介も行う。
2009年5月31日 (第114回)
- 英語の囃子 第10回 吉田三先生、電子情報4年丸山さん
eng090531.mp3 - 福井大学大学祭会場から生電話 高専ライブ特派員 山本さん
歯科健康フェアで工作教室
6月4日虫歯の日を前に、歯科健康フェアの会、場ににて「歯みがきロボット工作教室」を 行ってきました。午前中に2家族の工作を終え安心していたら、途中参加の2名が加わり、 時間内に工作を終えようと、アシスタントの学生さんも協力しながらの工作教室となりました。 無事に完成しましたが、参加者数は少なかったものの予想外に疲れました。
派生クラスの説明
先週の問題提起をうけて、その解決手段でもある派生クラスについて説明する。
// 基本となるクラス // ⇒ "基底クラス" ("親クラス"と呼ぶ場合もある) class Person { private: char name[20] ; int age ; public: Person( char s[] , int a ) { strcpy( name , s ) ; age = a ; } void print() { printf( "name=%s , age=%d\n" , name , age ) ; } } ; // Personのデータにbukaをちょっとだけ加えたクラス // ⇒ 派生クラス(導出クラスと呼ぶ場合もある。) class Joshi : public Person { private: Person* buka ; public: // 上司のデータ構造のコンストラクタ Joshi( char s[] , int a , Person* b ) : Person( s , a ) , // 上司の名前と年齢を初期化 buka( b ) // 部下の情報を保存 {} void print() { Person::print() ; // Joshiの名前と年齢を // Personのデータとして表示 buka->print() ; // 部下の情報を表示 } } ; int main() { Person saitoh( "T-Saitoh" , 44 ) ; saitoh.print() ; Joshi ashida( "Ashida Noboru" , 55 , &saitoh ) ; ashida.print() ; // 上司の情報と部下の情報がペアで表示される。 // テーブルという配列に、saitohとashidaを登録。 // table[]は、「Personへのポインタ」の配列。 Person* table[2] ; table[0] = &saitoh ; table[1] = &ashida ; // table[]に格納された、saitohとashidaを表示する。 for( int i = 0 ; i < 2 ; i++ ) table[i]->print() ; // ただし、table[1] に代入する時点で、Joshi は Person に // 降格させられているので、部下の情報は表示されない。 }
プロジェクタ&エディタそのままで
いつもは、ホワイトボードにコードを書きながら説明を行っているが、 今日はEmacsを24ポイント表示にして、直接コードを入力しながらの説明を行った。 すぐにプログラムを実行した結果を見せながらだったので、ある意味便利。 しかしながら、継承の説明の前に、Joshi::print() を書いたコードを示し、 説明の順序を間違えた点で反省。
プロジェクタの説明では、エディタでスクロール移動をしすぎると、どこを見るべきか 追従できずに不満がでるだろうと、注意しながら…と思っていたが、 やっぱり画面移動が激しくなってしまった。 試験的に、プロジェクタを使ってみたけど、あまり巧い使い方ではなかったと反省。 「学生さんからは、この資料印刷して…」と頼まれたけど、 『そのまま日記にあげておく…』と説明する。
2009年5月24日 (第113回)
- バララット大学留学交換留学報告会 前半
- F-レックスの福井仕事塾のお知らせ F-レックスのサイトは こちら
- ゲスト F-レックス学生チーム 木下さん、三田村さん
メモ:LEGO MindStorm NXT に拡張インタフェース
MindStorm NXT に自作のハードウェアを接続するためのノウハウ?
- RCX変換ケーブル
- NXT拡張センサ
- NXT拡張センサ
- LEGO MINDSTORMS NXTグレーブック プログラムノツヅラ (単行本)
- NicoSensor
- NXTに自作センサを繋ごう
- NXTに自作のタッチセンサを付けるには
- NXTにLEDを繋ぐ
NXTにLEDをつなげる回路をそのまま使って、フォトカプラにつなげてやれば 自作モータも簡単にまわすことができるだろう。 また、通常のタッチセンサーであれば、1つのポートにスイッチ1つが基本。 だけれども、自作のタッチセンサーを接続させる回路の例をみると、 単純にアナログセンサーに接続されているだけみたい。 リンク先の記事では、抵抗値の違うスイッチを並列接続することで、 2つのスイッチを確認する方法が記載されている。