1 / 18

情報処理 Ⅱ

情報処理 Ⅱ. 2006年11月24日(金). 本日学ぶこと. ポインタを使ったプログラミング 反復語判定の拡張版 対象語は,コマンドライン引数から獲得 文字列走査 ビットパターン出力 int 型, float 型の値に対して出力 ポインタ値の型変換 コマンドラインオプション. これまでの,補足(1). for 文を「 for ループ」, while 文を「 while ループ」と呼ぶことがある. ループ = loop = 糸・ひもなどの輪 for 文で計数に使用する変数を「ループカウンタ」という.. これまでの,補足(2).

asher
Download Presentation

情報処理 Ⅱ

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 情報処理Ⅱ 2006年11月24日(金)

  2. 本日学ぶこと • ポインタを使ったプログラミング • 反復語判定の拡張版 • 対象語は,コマンドライン引数から獲得 • 文字列走査 • ビットパターン出力 • int型,float型の値に対して出力 • ポインタ値の型変換 • コマンドラインオプション

  3. これまでの,補足(1) • for文を「forループ」,while文を「whileループ」と呼ぶことがある. • ループ = loop = 糸・ひもなどの輪 • for文で計数に使用する変数を「ループカウンタ」という.

  4. これまでの,補足(2) • char *p = "abc"; としたとき,「文字列p」と書くことがある. • 文字列が等しいかを比較するときに,演算子 == は使用できない. • char *p = "abc"; char *q = "abc";のとき,p == qは偽(異なるオブジェクトを指し示している)と考える • char p[] = "abc"; char *q = "abc";のとき,p == qは偽(異なるオブジェクトを指し示している) • char p[] = "abc"; char *q = p;のとき,p == qは真(同じオブジェクトを指し示している) • 文字列比較は,ライブラリ関数の strcmpを使用する

  5. 反復語判定にコマンドライン引数を • 仕様 • 入力は,コマンドライン引数から獲得する. • コマンドライン引数の各文字列について,反復語(2回以上の繰り返し)になっていれば「Yes」を,そうでなければ「No」を出力する. • 例 • ./iterative2 muumuu MuuMuuMuu MuuM • "muumuu" : Yes • "MuuMuuMuu" : Yes • "MuuM" : No

  6. プログラミングの 前に,ちょっと 検討する習慣を! 反復語判定:アイディア • 反復語は,先頭何文字か(「部分文字列」とここでは言う)の繰り返しである • ①部分文字列の候補を見つけ,②繰り返しになっているかを確認すればよい. • 例1: m u u m u u m u u m u u • 例2: a a b b a a b b • 部分文字列の性質 • その直後の文字が,先頭の文字と一致する. • 反復語の長さは,部分文字列の長さで割り切れる. • ある語に対して,部分文字列(の候補)は複数あり得る.

  7. 反復語判定(部分文字列の候補発見) 1文字ずつ見ていく処理を 文字列の「走査(scan)」という • 先頭から1文字ずつ見て,部分文字列の候補を求める. • 部分文字列は p から q - 1 までの文字配列 p q ヌル文字がないので,実は文字列ではない argv[i] 'm' 'u' 'u' 'm' 'u' 'u' '\0'

  8. 反復語判定(繰り返しの確認) • 対応する文字を1文字ずつ見て比較する. • r が q まで来たら,文字列の先頭に戻る. • 繰り返しになっていないか,sが文字列の末尾まで来たら終了. p q argv[i] 'm' 'u' 'u' 'm' 'u' 'u' '\0' r s

  9. 反復語判定:ポインタ変数の役割 • char *p = argv[i]; • 対象文字列 • char *q; • 部分文字列(の候補)の次の位置を指す. • p から始まり,文字列走査により1ずつ増える. • char *r; • 繰り返し確認用 • p から始まり,反復語であれば,部分文字列を(反復回数-1)回,巡回する • char *s; • 繰り返し確認用 • q から始まり,1ずつ増える.

  10. ビットパターン出力1 • 仕様 • int型の値を,バイト単位で最上位ビットから最下位ビットの順に,2進数で出力する.バイト間には空白文字を置く. • 入力は,プログラム内で指定する. • 例 • 40 ⇒ 00101000 00000000 00000000 00000000 • 応用すれば,任意のアドレスの値を獲得したり,書き換えたりできる.(Cが適度に低水準な理由の一つ!) 40の2進表記 ???

  11. ビットパターン出力1:アイディア • int x = 40; char *p = (char *)&x;とすると,*p, *(p + 1), ..., *(p + sizeof(x) - 1)は,xの「バイトごとの」中身である. • 1バイトのビットパターンを求めるプログラムを活用して,バイトごとに出力すればいい! int x : p p+1 p+2 p+3 char *p : は1バイト はオブジェクト,

  12. p1+1 int *p1 : p3+1 char *p3 : は1バイト ポインタ型のキャストが必要な理由 • int x = 40;としたとき, • int *p1 = &x;としてもうまくいかない. • char *p2 = &x;は,型が合わない. • char *p3 = (char *)&x;とすればうまくいく. int x :

  13. ビットパターン出力2 • 仕様 • int型のほか,float型の値を,バイト単位で最上位ビットから最下位ビットの順に,2進数で出力できるようにする. • 入力は,コマンドラインから指定する.最初の1個の数値のみでよい.数値が指定されなければ,1とする. • 数値の前にオプション(コマンドラインオプション)を指定可能 • -f : float型の値を出力する(float) • -r : バイト単位で逆順に出力する(reverse) • -p : バイトごとにそのアドレスも出力する(pointer) • 「-frp」のように一括指定も可能

  14. ビットパターン出力2(続き) • 実行例 • ./intfloatbit⇒ 00000001 00000000 00000000 00000000 • ./intfloatbit -f 1⇒ 00000000 00000000 10000000 00111111 • ./intfloatbit -f -r 1⇒ 00111111 10000000 00000000 00000000 • ./intfloatbit -pr 1⇒ 0x22eec7:000000000x22eec6:000000000x22eec5:000000000x22eec4:00000001 コマンド名(必ず1つ) コマンドラインオプション(任意個) コマンドパラメータ(任意個) すべて合わせて「実行コマンド」

  15. ビットパターン出力2:構成要素 • コマンドラインオプションの獲得(コマンドライン解析)方法 • intでもfloatでも出力できる方法 • 逆順の出力方法

  16. バイトオーダ • 実行例 • ./intfloatbit 1⇒ 00000001 00000000 00000000 00000000 • ./intfloatbit -r 1⇒ 00000000 00000000 00000000 00000001 • 値が「バイト単位で」メモリにどのように格納されるか(バイトオーダ)は,処理系により異なる. • 最下位バイトから最上位バイトの順に格納していくのを,リトルエンディアンという.演習室のLinux環境も該当する. • 逆に,最上位バイトから最下位バイトの順に格納するのは,ビッグエンディアンという.ネットワークバイトオーダともいう.

  17. この表現形式も,処理系に依存する(Cの規格この表現形式も,処理系に依存する(Cの規格 ではない)が,多くの処理系で採用されている float型のビットパターンの意味 • ./intfloatbit -fr 1⇒ 00111111 10000000 00000000 00000000 • ./intfloatbit -fr 2⇒ 01000000 00000000 00000000 00000000 • ./intfloatbit -fr 3⇒ 01000000 01000000 00000000 00000000 • ./intfloatbit -fr -3⇒ 11000000 01000000 00000000 00000000 符号(1bit) 0なら正 1なら負 仮数部(23bit) 2進数,小数点以下 1を加えれば,実際の仮数になる 指数部(8bit) 底は2,整数値127を引けば 実際の指数になる.

  18. まとめ • int main(int argc, char *argv[])で,コマンドライン引数(文字列の配列)を獲得できる. • argv[0]はコマンド名,argv[argc]はNULL • 残りの文字列をどう扱うかは,プログラム内で決める • 文字列の走査,バイト単位での処理には,char *型のポインタを活用するとよい. • ポインタ値のキャスト(型変換)により,アドレスを変えることなく,任意のポインタ型に変換できる.

More Related