2011年4月17日(第212回)
- 新入生オリエンテーションについて
- 新入生歓迎会について
- 部活紹介について
放送時間中に長水先生から写真付のメールをお寄せいただきました。
参照渡し、コンストラクタ・デストラクタ
前回の授業で、クラス宣言とメソッド定義の説明を終えているので、 今日は参照渡しの説明と、コンストラクタ・デストラクタの説明。
C言語での、値渡しとポインタ渡しの説明を行い、 関数呼び出しでの副作用の範囲を限定できることを説明。 これに加えて、ポインタ渡しを簡単に記述できる参照渡しの説明を行う。
// 参照渡しの例 void foo( int& x ) { x++ ; printf( "%d\n" , x ) ; } void main() { int a = 123 ; foo( a ) ; // 124 foo( a ) ; // 125 }
例年よりは、C言語を分かっているようなので、今後C++のコードを読むと出てきそうな、 const 宣言や、inline 宣言を説明する。 inline 宣言では、Cであれば #define マクロを使っていた様な処理を、 通常の関数呼び出しと同じように書ける。
#define SQR(X) ((X)*(X)) inline int sqr( int x ) { return x * x ; } void main() { printf( "%d\n" , SQR( 1+2 ) ) ; // SQRの冗長な()が無いと... printf( "%d\n" , sqr( 1+2 ) ) ; }
一般的に、プログラムの間違いでは、初期化しないデータによるバグが多い。 オブジェクト指向では、オブジェクトを確実に初期化するための、コンストラクタ機能がある。
class Person { private: char name[ 20 ] ; int age ; public: void print() { printf( "%s %d\n" , name , age ) ; } Person( char s[] , int a ) { strcpy( name , s ) ; age = a ; printf( "Constructor " ) ; print() ; } ~Person() { printf( "Destructor " ) ; print() ; } } ;
質問:デストラクタはユーザが明示的に呼び出せるか?→無理…
自分自身の疑問:デストラクタがprivateだったら?→エラーが出た…
情報構造論・ガイダンス
最初の授業ということで、シラバスなどのガイダンスに交えて、 「プログラムを作る時、何を考慮して書くべきか」という質問をしてみた。 こちらとしては、プログラムでのアルゴリズム評価の観点ということで、 「処理速度」、「使用メモリ量」、「アルゴリズムの複雑さ」という答えを 期待していたんだけれど、プログラムの見易さについての返答ばかり。 「処理速度」という答えがでるまでに随分と時間がかかってしまった。
速度・メモリ・複雑さの3つは、それぞれ速度優先のアルゴリズムは、メモリを大量消費したり、 プログラムが複雑になるなど、一方を優先すれば他方に悪影響のでる トレードオフの関係にあることを解説。 単純検索・2分探索法・全データメモリーマップなどの方法を例に挙げて説明を行う。 プログラム開発では、トレードオフの関係にあるからこそ、 その状況に応じたアルゴリズムを選択(デザイン)できるためにも、 速度・メモリ・複雑さを客観的に評価できる必要性がある。
速度の評価
まず手始めに、N件のデータを配列の中から探す処理で説明。
int data[ N ] ; int key = ??? ; for( int i = 0 ; i < N ; i++ ) { if ( data[ i ] == key ) break ; }
このプログラムの実行時間を考えると、最悪のケースでは、式の実行回数は、 i=0 | 1回、i < N | N+1回、i++,if(==) | N回となる。 よって、処理時間は、以下の式で示される。
このプログラムで、1000件で1msecの時間を要した場合、 10000件であれば、何秒かかるか?という問題があった場合、2変数1式であり 通常では処理時間を求めることができない。しかし、 処理速度の見積もりでは、大抵データ件数Nは巨大な場合がほとんどであり、 も、1回の初期化の時間であり、きわめて小さい値が一般的であり、無視できる。 よって、
から、10000件では、10msecという予想時間を求めることができる。
次に、もう少し複雑な例ということで、データの並び替えで最大選択法の プログラムを示し、処理時間を議論する。
int data[ N ] ; int i , j , m , t ; for( i = 0 ; i < N-1 ; i++ ) { m = i ; for( j = i+1 ; j < N ; j++ ) if ( data[ m ] < data[ j ] ) m = j ; t = data[ m ] ; data[ m ] = data[ i ] ; data[ i ] = t ; }
内部のjのループの実行回数は、(N-1-i) 回であり、 これを外側iのループで回すため、以下のような式で示される。
プログラミング応用・ガイダンス
プログラミング応用の最初ということで、授業の方針やシラバスを示しながら、 テストや評価方法などを解説。後半は、プログラミングの基礎を改めて説明。
制御構文:C言語の復習ということで制御構文について示す。 最初に文の定義として、式や制御構文、複文、空文などを説明し、 複数の文から大きな文が作られることを話す。 理解確認のために、例年通りforループの処理順序を書かせながら、 if(式)文 else 文、while(式)文、do 文 while(式) ; 、for(式;式;式) 文、break、continueなどを説明する。 breakなどで goto 文はほぼ不要となっている話の雑談として、 構造化プログラミングについて話し、処理の構造化・データの構造化を解説。 用語として、インデント、ネスティング(入れ子)など。
来週は、switch(…) case などの説明から。
2011年4月10日(第211回)
誠市、ご縁市開催中でした!
- マニアックタイムズ第1回 2年電子情報工学科 山田さん
- 高専ライブのパーソナリティ募集のお知らせ
卒研・ガイダンス
最初の卒研ということで、クラス全体のガイダンスにて、以下の点を説明。
- 卒研に取り組んだ時間は、日付・時間・内容などを記録する
- 卒研では発表等で資料を作るので日々の記録が重要(ノートを作る)
- 資料提出用のファイル共有の概略説明
斉藤卒研室のガイダンス
各卒研室に分かれた後は…ということで、自分の卒研の学生さん向けにガイダンス。 ネットワーク系テーマや、制御系テーマについて解説し、 どのような内容で取り組むか考えてもらうために、簡単な課題を示す。 また、最初は毎月1回ぐらいのペースで中間報告をしてもらう方針を話す。 その後は、自分のパソコン環境の設定をしてもらう。
2日目は、サーバにユーザ登録をして、パスワード設定やファイル共有の使い方、 Webページの作り方の説明を行う。
オブジェクト指向プログラミング・ガイダンス
専攻科2年向けのオブジェクト指向プログラミングの授業のガイダンス。 最初に授業内容の説明として、大きなプログラムを作るにあたって、分業・再利用が しやすくするためのテクニックとしての、隠蔽化・継承という概念があり、 最終的に、UMLなどの説明をすることを紹介。 その他、レポート中心での内容などを説明する。 受講者は、EIのOB3人+E科OB1人。
最初にオブジェクト指向の概念を説明するために、プログラム言語の歴史を紹介し、 FORTRANで手続き、COBOLで構造体、ALGOLで構造化プログラミングが現れた あたりを説明し、Simulaで シミュレーションの記述としてオブジェクト指向が使われ始めたことを紹介。 また、Smalltalkで、 GUI環境の構築で有用性が認知され、X11,Windowsなどのプログラミングに 波及していったことを紹介。 その元になったのが、C言語にオブジェクト指向を取り入れたC++であり、 これから Java が派生していったことを説明する。
CからC++へ
例年であれば、他学科でC言語理解の浅い人向けの説明を行うけど、今年は構造体なら 理解していそうなので、例年よりはハイペース。以下のようなプログラムを示し、 オブジェクト・メソッド・インスタンス・クラスといった用語を紹介。
struct Person { // オブジェクト(データの構造) char name[ 20 ] ; int age ; } ; void set( struct Person* p , char s[] , int a ) { strcpy( p->name , s ) ; // 初期化メソッド(データの操作) p->age = a ; } void print( struct Person* p ) { // 表示メソッド printf( "%s %d\n" , p->name , p->age ) ; } void main() { struct Person saitoh ; // saitohインスタンス(具体化) struct Person family[2] ; set( &saitoh , "saitoh" , 46 ) ; set( &family[0] , "mitsuki" , 11 ) ; print( &saitoh ) ; print( &family[0] ) ; }