PHP7の初級試験の勉強を開始した矢先にstrcmp関数で詰まったのでメモ。
初心者のため間違い等あったら教えてほしいです。
strcmp関数は、文字列の大小を比較する?
string compeare(文字列比較)の略でstrcmp
です。引数で与えられた2つの文字列を比較し、
- 一致すれば「0」
- 第一引数が大きければ「1より大きい数字」
- 第一引数が小さければ「1より小さい数字」
を返します。ここで疑問に思いました。文字列の大小って何だ?と。
文字列の大小とは、「同一でない文字」の「バイト列の差」のこと
文字列の大小とは、 「同一でない文字」 の 「バイト列の差」 のことを言っています。その比較方法として、文字列の頭から順に比較し、同一でなかった時点で処理を停止して、その文字の「バイト列の差」を返してくれます。
strcmp("ABCD", "ABBE");
# 1
ここでは、strcmp関数で第一引数"ABCD"
と第二引数"ABBE"
を比較しています。
一文字目の'A'
から比較していき、3文字目の'C'
と'B'
で同一でなくなります。ここで処理は停止し、それ以降の文字('D'
と'E'
)は無視されます。
結果として、出力は'1'
となります。その理由が3文字目の 「バイト列の差」 になります。
同一でなくなった3文字目'C'
と'B'
のバイト列の大きさを比較し、第一引数である'C'の方が第二引数である'B'よりもバイト列の値が1大きいため、その差の'1'
を返却していることになります。
数字も文字として扱われる
strcmp関数は、数字も文字列として扱い、比較します。数字の大小を比較するものではないです。
数字の場合でも文字列と同様に1文字目から比較し、不一致の時点で停止、その文字のバイト列の差を返す、ということです。
例えば、第一引数"12330"と第二引数"1234"を比較する場合。
strcmp("12330", "1234");
# -1
数字の大小で言えば確かに"12330"の方が大きいです。しかしstrcmp関数では、頭の一文字目から比較し、4文字目の'3'と'4'が不一致になったところで処理を停止して、この文字同士のバイト列の差を返却します。
結果として、'3'の方がバイト列が1小さいため、strcmp関数は'-1'を返却します(5文字目以降は無視されます)。
上記以外のパターン(同一の文字が存在無い場合)
例えば次のパターンですと、一文字目の'a'は一致していますが、2文字目が第二引数に存在しないため、処理が変わってきます。
strcmp("acccc", "a");
# 4
この場合は、第一引数の'a'以降の文字数の分だけ返します。シングルバイト文字1文字につき、'1'を返すので、この場合cが4つで'4'を返します。マルチバイト文字(全角文字)の場合は、1文字につき'3'を返します。
このあたりの仕様については、すみませんがよくわりませんでした。が、挙動の記録として一応残しておきます。
参考
上記サイトを参考の上検証してみました。
strcmp関数で検索してみると、「文字列の長さ」を比較している、というような情報が目に入ったりしますが、そうではないようです。
情報に振り回されないよう、初心者の私も気をつけていきます。目指せPHPマスター!