文字のポインタ

2015/4/30
そもそも、不定長の文字列
• 例) エディタでどこまで文字を入力?
• 例) サーバから何文字送られてくる?
プログラミング演習
• コンパイル時に決定できるか!
• 出来ない
• 配列として文字列を操作するのは困難
• では?
• 文字を指し示す変数を書き換える
char型, 文字列,ポインタ
– ポインタ
文字を指し示す変数(1)
文字を指し示す変数(1)
ポインター(指し⽰す)
ポインター(指し⽰す)
⽂字を指し⽰す変数
⽂字を指し⽰す変数
これは「イングリッシュ・ポインター」
H e
l
l
o ¥0
H e
3
l
l
o ¥0
4
1
2015/4/30
文字を指し示す変数(2)
文字を指し示す変数(3)
⽂字を指し⽰す変数
H e
l
l
⽂字を指し⽰す変数
o ¥0
H e
l
l
o ¥0
5
文字を指し示す変数(4)
6
文字を指し示す変数(5)
⽂字を指し⽰す変数
H e
l
l
⽂字を指し⽰す変数
o ¥0
H e
7
l
l
o ¥0
8
2
2015/4/30
文字を指し示す変数(6)
ポインタによるアクセス
⽂字を指し⽰す変数
⽂字列の終わり
H e
l
l
指し示す変数
o ¥0
9
文字列とポインタ
文字列のポインタ宣言(1)
char *ptr;
• ポインタは難しくない
– 自分が何をしているかを理解していれば
– 「セグメンテーションフォルト」終了
– 「コアダンプ」終了
ptr
確保される変数領域
• C言語の特長はポインタにあり
– Javaではポインタ演算は導入しなかった
• 文字列(char型の配列)でポインタの練習
– 実力を発揮するのは構造体とポインタ
– メモリ取得関数 malloc() の学習後
11
12
3
2015/4/30
文字列のポインタ宣言(2)
文字列のポインタ宣言(3)
char *ptr; *ptr 「ptr変数の先は⽂字」
char *ptr;
ptr
ptr
ptrは「アドレス」を指す
H e
l
l
o ¥0
13
文字列のポインタ宣言(4)
14
文字列のポインタ宣言(5)
ptr
char *ptr;
char *ptr;
prt
prtは「アドレス」を指す
*ptr
moji
char moji[]=“Hello”;
H e
l
l
o ¥0
*をつけると、アドレスの先を文字として参照
○ printf(“%c”, *ptr);
× printf(“%c”, ptr);
15
16
4
2015/4/30
文字列のポインタ宣言(6)
文字列のポインタ宣言(7)
char *ptr;
char moji[]=“Hello”;
char *ptr;
char moji[]=“Hello”;
ptr = moji;
*prtが指し示すのは'H‘;
ptr
moji H e
l
l
ptr
moji
o ¥0
H e
l
l
o ¥0
17
18
* の利用
char c1[4]="cit";
char *ptr;
c1 =
* の利用
"cit"
char c1[4]="cit";
char *ptr;
c i t ¥0
ptr = c1;
c1 =
"cit"
c i t ¥0
ptr = c1;
ptr アドレス
c i t ¥0
c i t ¥0
*ptr 文字
19
20
5
2015/4/30
文字の配列とポインタ
ポインタ操作のよくある失敗
char moji[]="Hello";
char moji[]="Hello"
H e
H e
l
l
o ¥0
ptr = moji;
ptrptr
今は、*ptr == 'H'
ptr++;
l
l
o ¥0
配列の名前
ptr
ptr
ptr
範囲を逸脱
ptr++
moji[]の範囲
ポインタ
OSによる停止
今や、*ptr == 'e'
21
for 文をつかった文字列操作 ポインタ
22
while 文を使った文字列操作 ポインタ
char moji[]="Hello"
char moji[]="Hello"
H e
H e
l
l
o ¥0
l
l
o ¥0
char *ptr;
ptr = moji;
while ( *ptr != '¥0' ) {
printf("%c",*ptr);
ptr++;
}
char *ptr;
for (ptr=moji; *ptr != '¥0'; ptr++) {
fprintf("%c",*ptr);
}
23
24
6
2015/4/30
課題(ポインタによる印字)
• “Chiba Institute of Technology”という内容をも
つ文字配列を宣言し、その文字配列からポイ
ンタ操作によって、一字ずつ印字するプログ
ラムを作成しなさい。
• for文を使っても、while文を使っても良いが、
終端の判断には、`¥0`を使うこと。
課題(文字数を数える)
プログラム中にあらかじめ文 プロトタイプ
字列を配列として3つ宣言して,
この配列を引数として,整数
int count_char(char *string);
値で単語の文字数を返す関
あるいは,
数を作成し, 動作を確認でき int count_char(char string[]);
るプログラムを提出せよ.
文字列を表現する変数
char string1[]="Hello";
nw34j> ./sample
Hello: 5
Information: 11
Technology: 10
char string2[]="Information";
char string3[]="Technology";
26
課題(大文字化)
引数で与えられた文字列に含まれる小文字英
字[a‐z]をすべて大文字英字に変換する関数を
作成し、動作を確認できるプログラムを提出す
る
元々大文字である文字は変更してはならない
例) Hello, World ‐> HELLO, WORLDとなる
ヒント [a‐z]を[A‐Z]に変換
ASCIIで,
ʼaʼ は 97(10進数), ʻzʼは122(10進数)
ʻAʼは65(10進数),, ʻZʼは90(10進数)
その差は32(10進数)
if ( (97 <= *ptr) && (*ptr <= 122) ) {
*ptr -= 32;
}
7