人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHPのstrcmp関数の挙動について教えて下さい。

オライリーの「プログラミングPHP(第三版)」には以下のような旨の記述があります。
「$n=strcmp("PHP最高!",5)の出力結果は1となる。」

こちらの環境では出力結果は59となりました。


また、適当な入門サイトを見ると下記のようなことが書いてありました。
$str1 = 'PHP入門';
$str2 = 'php関数入門';
$str3 = 'PHPタグ入門';
$str4 = 'PHP入門';

echo strcmp($str1, $str2);
出力→-1
echo strcmp($str1, $str3);
出力→1
echo strcmp($str1, $str4);
出力→0

こちらの出力結果は上から-32,2,0となりました。

環境はmacのxampp1.7.3beta1(PHP5.3.1)です。
バージョンによってこんなに関数の挙動が変わってくるとも思えないので、何か他の原因があるのでしょうか?また、その他で何か間違ってそうなところはありますか?

以上お願い致します。

●質問者: kojikoji75
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

質問者から

Windowsのxamppでは正常な結果が得られました。

質問の内容が分散していました。
ここでききたかったことは、"PHP最高"と5を比較して、どうして1を返すかということでした。その辺りについて解説をなかなか見つけることができないのでここで質問させていただきました。

あらためてよろしくお願い致します。


1 ● soqans
●100ポイント ベストアンサー

戻り値が異なる理由は突き詰めると「PHPを実行するプログラムを作り出したプログラム」に依存する、というものです。

説明をしますと、PHPのstrcmp関数は内部的に
・比較対象の値を強制的に文字列に変換する(型キャストにより文字列型に変換したときと同じ動作)
・文字列化したそれぞれの値をC言語のmemcmp関数で比較(短い方の長さまで)
・異なる場合はmemcmp関数の結果、同じ場合は長さの差を返す
という動作をおこなっているようです。ところが、このmemcmp関数は「比較対象の文字列が前にあるときは負の値、等しいときは0、後ろにあるときは正の値を返す、という仕様を満たす動作を行う」としか決められていません。そのため、仕様が満たされていれば返す値は何でも良い、ということになっています。

このmemcmp関数ですが、いくつかのコンパイラで動作を見てみると、
・VisualStudio系(Windows):-1or0or1の3値のみ返す
・Xcode系(Mac):バイナリの差分値を返す
・GCC系(主にLinux):-1or0or1の3値のみ返す
という結果となりました。
おそらくこれが書籍とMacの環境で結果が異なる理由だと思います。

初めの質問文ですが5を文字列に変換して文字コード(UTF-8)を取ると
"P":0x50
"p":0x70
"5":0x35
ですので、"php最高"と5をstrcmpで比較すると"p"-"5"=59となって、正の数なので1が返される、という処理と考えられます。
(小文字でも大文字でも正の数ですのでWinもしくはLinuxでは1ですが、Mac環境では小文字では59、大文字では27になると思います)

もう一つの質問にある-1および1を返す例ですが、UTF-8を使用している場合(0xというのは16進数表記を表しますが)
"入":0xE5 0x85 0xA5
"タ":0xE3 0x82 0xBF
となるので、(初めに異なっている位置だけ見ると)"P"-"p"=-32、"入"-"タ"=2となり、Macの結果は記述の通りとなり、値を-1?1へ変換するものでは-1と1を返す、という動作だと思われます。


kojikoji75さんのコメント
ありがとうございました。 知りたい部分を知ることができました。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ