C言語では「文字列」は,宣言と同時に配列型変数に代入する場合は**「NULL終端する文字の配列」**と一般的には等価です。
(厳密には,ポインタ型変数に代入したりインラインリテラルとして使用する場合はメモリ確保の方法が少し異なります)
c
1static char text[] = "This is a pen.That is a pensil.";
c
1static char text[] = {'T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 'p', 'e', 'n', '.', 'T', 'h', 'a', 't', ' ', 'i', 's', ' ', 'a', ' ', 'p', 'e', 'n', 's', 'i', 'l', '.', '\0'};
上記2つは等価です。
- 整数としておなじみの
int
は一般的には値の範囲が -2147483648
~ 2147483647
の数値です。(環境に左右されます)
- 文字としておなじみの
char
も実は値の範囲が -128
~ 127
の数値です。各番号に形式上文字が割り当てられているだけの話です。ASCII文字コード - IT用語辞典
char
のアドレスを表す char *
もまた数値です。32ビット環境では -2147483648
~ 2147483647
,64ビット環境では -9223372036854775808
~ 9223372036854775807
になります。
ここでたとえば text
が 0x80000000
番地(16進数表記)から始まっていると仮定すると,各アドレスに対応するデータは以下のようになります。
c
10x80000000 84 (T)
20x80000001 104 (h)
30x80000002 105 (i)
40x80000003 115 (s)
50x80000004 32 ( )
60x80000005 105 (i)
70x80000006 115 (s)
80x80000007 32 ( )
90x80000008 97 (a)
100x80000009 32 ( )
110x8000000a 112 (p)
120x8000000b 101 (e)
130x8000000c 110 (n)
140x8000000d 46 (.)
150x8000000e 84 (T)
160x8000000f 104 (h)
170x80000010 97 (a)
180x80000011 116 (t)
190x80000012 32 ( )
200x80000013 105 (i)
210x80000014 115 (s)
220x80000015 32 ( )
230x80000016 97 (a)
240x80000017 32 ( )
250x80000018 112 (p)
260x80000019 101 (e)
270x8000001a 110 (n)
280x8000001b 115 (s)
290x8000001c 105 (i)
300x8000001d 108 (l)
310x8000001e 46 (.)
320x8000001f 0 (\0)
C言語においては int
型に限らず char
や char *
も加算・減算することができます。今回は char *
の加算を利用しています。
一般的にC言語における文字列はNULL終端している必要がありますが,strncmp
に関しては,「探される文字列」側はNULL終端している必要がありません。(strncmp を参照)そのため,今回のコードで書いているような以下のアルゴリズムが利用できます。
- 「探される文字列」の先頭アドレスを1つずつずらしていく
- 現在のアドレスから「探す文字列」の長さのぶんだけ
strncmp
関数にチェックさせる
1回目: Thi
と pen
が一致するか?
2回目: his
と pen
が一致するか?
3回目: is
と pen
が一致するか?
4回目: s a
と pen
が一致するか?
5回目: a
と pen
が一致するか?
6回目: a p
と pen
が一致するか?
7回目: pe
と pen
が一致するか?
8回目: pen
と pen
が一致するか?
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/06/11 13:15