情報処理Ⅱ 2005年11月25日(金) 本日学ぶこと ポインタのポインタ ポインタを使ったプログラミング コマンドライン引数 回文判定(コマンドライン引数から語を獲得) 任意型のビットパターン出力 さまざまな「空」 NULLポインタ void型 ナル文字('\0') 空文 2 ポインタのポインタ 指し示すものを指し示す 例: char **p; p はchar **型 p[0] および *p はchar *型 p[0][0] および **p はchar型 • 適切に指し示していれば,p, p[0], p[0][0]はいずれも左辺値 p p[0] p[0][0] (参考)多次元 配列の模式図 3 多次元配列とポインタのポインタ 配列とポインタが異なるように,「多次元配列」と「ポインタと ポインタ」も異なる. × int a[2][3]; int **p = a; ○ int b[2][3]; int (*q)[3] = b; 一次元配列に限り, ○ int c[2]; int *r = c; a と b は「int [2][3]」型,ただしポインタ値としては「int (*)[3]」型 c は 「int [2]」型,ただしポインタ値としては「int *」型 int *q2[3]; と書くと,これは「int *[3]」型,ポインタ値としては「int **」型 4 コマンドライン引数 コマンドライン引数とは 例: cc program.c でコンパイルするとき, 「cc」はコマンド名,「program.c」はコマンドライン引数と呼ば れる. argv はchar **型の C言語でコマンドライン引数を獲得するには ポインタ変数 main関数を main(int argc, char *argv[ ]) と宣 言する. argv argv[0] argv[1] argv[2] = NULL "cc" argc = 2 "program.c" 5 NULLポインタ NULLは特殊な扱いをする定数であり,空ポインタ定数 (null pointer constant)とも呼ばれる. キャスト(明示的な型変換)なしで, 任意のポインタ型オブジェクトへの代入や, 任意のポインタ値との比較が可能 if,for,whileなどの条件式に,ポインタ値が指定可能 真…NULL以外のすべてのポインタ値 偽…NULL 6 コマンドライン引数とargv(1) 「./commaneline abc」を実行したときの 初期状態 argv argv[0] argv[1] argv[2] = NULL "./commandline" "abc" 7 コマンドライン引数とargv(2) argv++; としたとき argv argv[-1] argv[0] argv[1] = NULL "./commandline" "abc" 8 コマンドライン引数とargv(3) さらに argv++; としたとき argv argv[-2] argv[-1] argv[0] = NULL "./commandline" "abc" *argv はNULL(偽) 9 回文判定にコマンドライン引数を 仕様 入力は,コマンドライン引数から獲得する. コマンドライン引数の各文字列が回文になっていれば「Yes」を, そうでなければ「No」を出力する. あとは前述の回文判定と同じ. 例 ./palindrome2 12321 123321 noon Noon 12321 : Yes 123321 : Yes noon : Yes Noon : No 10 ここまでのまとめ ポインタは「型 *変数名;」で宣言し,式の中では その参照先を「*変数名」により得ることができる. 値として参照するときは,ポインタ変数でも配列変数でも同じ 書式. 変数宣言により生じる効果は,配列とポインタとで異なる. ポインタ値の加減算はポインタ変数の得意技. コマンドライン引数は,ポインタのポインタで獲得できる. 11 任意型のビットパターン出力:仕様など 仕様 出力したいオブジェクトの型や値は,プログラムの中で与える. 各ビットは上位から下位の順に出力する. 1バイトごとに空白文字を置いて出力する. 例 入力: 出力: 入力: 出力: int x = -40; 11011000 11111111 11111111 11111111 float f = 40; 00000000 00000000 00100000 01000010 12 任意型のビットパターン出力:方針 float f = 40; char *p = (char *)&f; とすると, *p, *(p + 1), ..., *(p + sizeof(float)-1) は,fの「バイトごとの」中身である. 1バイトのビットパターンを求めるプログラムを活用して, バイトごとに出力すればいい! float f : char *p : p p+1 p+2 p+3 は1バイト 13 ポインタのキャストが必要な理由 float f = 40; としたとき, float *p1 = &f; としてもうまくいかない. char *p2 = &f; は,型が合わない. char *p3 = (char *)&f; とすればうまくいく. float *p1 : p1+1 float f : char *p3 : p3+1 は1バイト 14 ビットパターン出力 float f = 40; の結果 バイトごとに逆順に出力すると 00000000 00000000 00100000 01000010 01000010 00100000 00000000 00000000 fを-10から10まで変えてみると 15 「空」とプログラム プログラミングと関係のない「空」の例 「部屋がない」と「空室がある」は違う. 空集合φ={}と,空集合のみからなる集合{φ}={{}}は違う. Cにおける「空」とは,「それは空である」,「空の…がある」など を明示するための概念 16 void型 voidは「何もない」や「無効な値」を表す型名 × void x; ○ void *x; ただし,sizeof(void)は0ではなく1 用途 関数が引数や戻り値を持たないことを明示するとき • void exit(int status); プログラムを終了するライブ ラリ関数.通常,exit(0); • void procedure(void); もしくは exit(1); のいず 任意のポインタ型を表現するとき れかで呼び出す. • void *p; • void *malloc(size_t size); 17 ナル文字 '\0' をナル文字(null character)という. ○ '\0' == 0 × '\0' == '0' × '\0' != NULL 文字列の末尾につく. ナル文字は,文字列の字数には数えられないが,char型の 1要素分(1バイト分)を占める. 18 空文 「式;」を式文という.式文から式を取り除いたものを空文 (null statement)という. 「{}」は,空ブロックと呼ばれる. 用途 for文の初期化,条件,増分の省略 • for (;;) ... 反復の処理 • for (p = "abcdef"; *p && *p != 'c'; p++) – ; 'a' 'b' 'c' 'd' 'e' 'f' '\0' p 19 まとめ int main(int argc, char *argv[])で,コマンドラ イン引数(文字列の配列)を獲得できる. ポインタ型の値は,キャスト演算子で任意のポインタ型に変 換できる. 文字列の走査には,char *型のポインタ変数を活用すると よい. 空ポインタ定数のNULL,void型,ナル文字,空文といった 「空(null, empty, void)」の概念がある. 20 第1回レポートについて 配布資料の通り 提出は,来週金曜日(12月2日)の授業開始時 配点は,10点 演習室等でプログラムを打ち込み,実行すること 21
© Copyright 2024 ExpyDoc