strcmp関数の中身について二つ質問があります。
①*s1=='\0'が成り立つことでで二つの文字列が等しいとしていますが、これはs1とs2の要素数が同じであることを前提としているのですか?
②最後のreturnでunsigned charにキャストしている理由がわかりません。
int strcmp(const char *s1, const char *s2) { while(*s1==*s2){ if (*s1=='\0') return 0; s1++; s2++; } return (unsigned char)*s1 - (unsigned char)*s2; } ```よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答5件
0
①*s1=='\0'が成り立つことでで二つの文字列が等しいとしていますが、これはs1とs2の要素数が同じであることを前提としているのですか?
いいえ、違います。引数としては別に異なる長さの文字列2つでも良いです。たとえばs1とS2が全て等しい場合、S1の要素が\0の時、S2の要素も\0となり、その時は文字列数も同じで retuern 0
つまりstrcmpの文字列が等しいときの戻り値0になります。
しかし要素数が等しくない場合でも先にどちらかの文字終端\0がでてきた時点で*s1==*s2が満たせずwhile文をぬけるので問題なし
②最後のreturnでunsigned charにキャストしている理由がわかりません。
はじめて*s1==*s2が成り立たなくなった時、それまでの文字は等しかったのでその文字で大小で比較します。
その大小ですが、charは文字とはいえコンピュータ的には8bitの数値なので単純に数値としての大小を判定します。
この時unsigned charにキャストしているのはsigned charでは大小がおかしくなるからです。
たとえば(unsigned char)*s1 - (unsigned char)*s2が200の時
(signed char)*s1 - (signed char)*s2は−56になる(たぶん)
本来S1>S2として結果をかえしたいのに、S1<S2となってしまう。
###補足
回答を終わって他の回答者様の回答の1の方をみてぎょっとしましたので、そこだけほそく、S1==\0だけでS2のほうは評価していないのに、等しいと判断しているのはwhile文のS1==*S2がなりたっているからで、それは要素数が同じ前提という事です、私が違いますといったのは、strcmpは2つの文字列が同じ要素数しか受け付けないわけではないという意味での「違います」です。
投稿2016/11/01 15:22
編集2016/11/01 15:57総合スコア1689
0
ベストアンサー
こんにちは。
①*s1=='\0'が成り立つことでで二つの文字列が等しいとしていますが、これはs1とs2の要素数が同じであることを前提としているのですか?
その直前にwhile(*s1==s2)が成立していますのでs2も0です。従って長さも等しいです。
②最後のreturnでunsigned charにキャストしている理由がわかりません。
よく見落とすのですがchar型は符号付きの場合があります。
0x80以上の値が入っている時符号付きで比較した場合と符号なしで比較した場合、結果が逆になります。
文字コードは符号なしで比較した方が直感的な理解と一致しますので符号なしへキャストしているものと思います。
(何故にchar型を符号付きと定義する場合があるのかは知りません。単に迷惑な話のように感じますが、何か妥当な理由があるかもです。)
投稿2016/11/01 15:21
編集2016/11/02 01:57総合スコア23272
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/11/01 17:57
2016/11/01 23:50
2016/11/02 00:42 編集
2016/11/02 02:03
0
strcmp(s1,s2)の戻り値が下記のようになる様に、一文字づつ比較を行いs1の終端'\0'に到達した
場合’0’を返し、両方の文字列は同じとしています。
以外は異なった時点での文字の大小比較の結果を返します。戻る際にunsignedでcastして全ビット
での差分計算値を返します。(符号ビットを数値として扱う)
<<strcmp戻り値>>
s1 = s2のとき: 0
s1 > s2のとき: 正の整数
s1 < s2のとき: 負の整数
strで始まる関数は文字列の最後が'\0'である事がお約束ですので、そこを意識して使われると良いです。
strcat 文字列の連結
strchr 文字列の先頭から文字を検索する
strcmp 文字列の比較
strcpy 文字列のコピー
strlen 文字列の長さの取得
等々..
投稿2016/11/01 15:48
総合スコア4070
0
A1. 文字列は終端が'\0'である、という取り決めがあり、もし文字列の長さ(要素数)が違えば、どこかで一致しなくなります(長いほうの中間の要素と'\0'の比較になるから)。両方が同じで、'\0'まで読み込んだ場合は、最後まで同じとわかるので、文字列一致を意味する0を返すのです。
A2. ANSIの仕様では、strcmp関数はs1 > s2のときは正の値、s1 < s2のときは負の値、それ以外は0を返す、としか決められていません。なので、そのような結果を返すコードはすべて合法となります。途中で文字が違う場合、その文字のコードの大小で、文字列の順序が決まります。このコードを扱う際、char型では負の値が出てきてしまうので、unsignedでキャストしているのです。
投稿2016/11/01 15:27
総合スコア1720
0
答1
はい。少なくともこの実装の場合は、長さが違うならば異なる文字列となります。つまり、長さが同一であり、なおかつ内容が完全一致する場合のみ同一文字列と判定されます。
答2
文字コード(符号なし整数)順を正負の条件にするためだと思います。
投稿2016/11/01 15:11
総合スコア4830
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/11/02 01:41