プロが教える店舗&オフィスのセキュリティ対策術

strstr()関数が、どのように実装されてるか知りたかったため、strstr.cの中身を見てみたのですが、
分らない処理がありました。

char * __cdecl strstr (const char * str1, const char * str2)
{
 char *cp = (char *) str1;
 char *s1, *s2;

 if ( !*str2 )
  return((char *)str1);

 while (*cp)
 {
  s1 = cp;
  s2 = (char *) str2;

  while ( *s1 && *s2 && !(*s1-*s2) )
   s1++, s2++;

   if (!*s2)
    return(cp);

    cp++;
   }

 return(NULL);

}

while文のネストの部分で、*s1 && *s2 && !(*s1-*s2)とありますが、
(*s1 && *s2) または !(*s1-*s2) のどちらか一方のみではまずいのでしょうか?

解説、アドバイスの程よろしくお願い致します。

A 回答 (3件)

>(*s1 && *s2) または !(*s1-*s2) のどちらか一方のみではまずいのでしょうか?



while ( *s1 && !(*s1-*s2) )

で十分です。
*s1、*s2ともナル文字以外の時は、!(*s1-*s2)の結果、等しい間のみループします。
*s1がナル文字以外、*s2がナル文字の時は、!(*s1-*s2)が0になるのでループを抜けます。
*s1がナル文字、*s2がナル文字以外の時と、*s1、*s2ともナル文字の時は*s1が'\0'ですのでループを抜けます。
    • good
    • 0
この回答へのお礼

お返事が遅くなってしまいありがとうございました。
大変分かりやすい場合分けをして頂いたお陰で理解できました。
ありがとうございました。
標準関数の実装内容をより簡単に(シンプルに?)できる場合もあるんですね。勉強になりました。

お礼日時:2007/07/13 09:44

*s1 && *s2


これで、両方の文字がまだあるかを検査しています。
どちらかが文字列の終了になると、この条件は成立しなくなります。

!(*s1-*s2)
これで、文字の一致を見ています。
*s1と*s2が同じ文字の場合は0(偽)になりますので、それの否定(真)ですので一致している間ループ処理が行われます。
一致しないと0では無くなります(真)ので、それの否定(偽)ですのでループ脱出となります。

ということで、どちらの条件も必要不可欠ということになります。
    • good
    • 1
この回答へのお礼

お返事が大変遅くなってしまい申し訳ありませんでした。
大変分かりやすい回答を頂き、ありがとうございました。

お礼日時:2007/07/13 09:37

両方が同時に文字列末の \0 に到達したときにどうなるか考えてみてください。

    • good
    • 0
この回答へのお礼

大変遅くなってしまい、申し訳ありません。
的確なアドバイスありがとうございました。

お礼日時:2007/07/13 09:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!