人に聞けない痔の悩み、これでスッキリ >>

================
for(pp = path; *pp != '\0' && *pp == '.';){
if(!strncmp(pp, "../", 3)){
pp += 3;
while(bp > base && *--bp != '/');
}
================
http://xn--n9q36mh1hnxuksz7wt.jp/FE21a-pm/t09.html

この処理について教えてください。

if文の実行条件がどうしても分からないのです。
!strncmp(pp, "../", 3)はppの要素の先頭3文字と"../"の先頭3文字を比較して
一致しなかった場合にpp += 3;とwhile文を実行すると解釈しています。

つまり、ppの要素の先頭3文字が"../"だった場合は一致するのでif文は
実行されないと思うのですが、解説をみると逆になっています。
(ppの要素の先頭3文字が"../"だった場合は一致するのでif文は実行される。)
http://www.kmctec.net/k_gogo/gogo11/gogoans1144. …

if(!strncmp(pp, "../", 3))をどのように解釈すればいいのでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (3件)

(1)strncmpは比較した文字列が等しい場合は0を返します。


(2)ifは式の真偽を判定して真の時の処理を実行します。

ここで、C言語では偽の定義を整数の0、真の定義を0以外としています。したがって文字列が等しい場合はstrcmpの結果が0となり、偽と判定されますが、前に「!」が付いてるので真偽が反転して真になり、if分の{}内の処理が実行されるわけです。

本来ならこのif文は
if (strncmp(pp, "../", 3)==0) {
と書かれるべきですが、たまたま0が偽と定義されているので、比較式を書かずに関数の返り値を直接判定させるような使われ方がされることも多いのです。

ただし、これはC言語の真偽の定義が整数の0と0以外だからこそ使える裏技的な手法なので、C#のように真偽を表す論理型が整数型とは明確に別の型だと規定されている場合には使えません。
    • good
    • 0
この回答へのお礼

ありがとうございます!
「C言語では偽の定義を整数の0、真の定義を0以外」の部分を理解できていませんでした。
また、if (strncmp(pp, "../", 3)==0)だと偽になってしまい、if文が実行されないということも理解できました。
もの凄く良く理解できました。

お礼日時:2010/06/27 13:05

strncmp(pp, "../", 3) はppの先頭が"../"であったとき0となります。


それに!がついているので、一致したとき1となり、if文が実行されます。
    • good
    • 0
この回答へのお礼

そもそもの真偽判定での1と0の取り扱い方法を理解できていませんでした。

先頭3文字が一致でstrncmpから0が応答

それを!で否定するので0→1となる。

結果、if(1)となり偽(0)→真(1)となる

if文が真なので実行される。

ということですね。
ありがとうございました。

お礼日時:2010/06/27 13:15

直感に反するかもしれませんが、strcmp関数は二つの文字列が等しい場合に「0」を返します。


http://www9.plala.or.jp/sgwr-t/lib/strcmp.html

したがって、ppの要素の先頭3文字が"../"だった場合は一致するので if文は
if( ! 0 )となり、実行されます。

この回答への補足

回答ありがとうございます。
自分のトレースした自体は間違っていない事がわかりました。
strcmp関数で文字列が一致していれば、0を返すというのは分かるのですが、
if( ! 0 )というのがどういう状態なのでしょうか?
「比較対照の文字列は一致していなければ実行」

「比較してみたら一致したので戻値の0(等しい)を応答」

「!があるので、一致しているが否定される=『ゼロではない』となる」=「一致していない」

実行

だとすると、if(!strncmp(pp, "../", 3))は、if(strncmp(pp, "../", 3)=0)と解釈しても良いのでしょうか?

補足日時:2010/06/27 02:41
    • good
    • 0
この回答へのお礼

そもそもの真偽判定の考え方が分かっていませんでした。
完全にハマってしまっている状態だったので、
とっかかりを頂けた気がします。ありがとうございました。

お礼日時:2010/06/27 13:18

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


人気Q&Aランキング