情報処理II

情報処理Ⅱ
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