• ベストアンサー

assert(!"abcd");がどうしてアサートに引っかかるのか理解できない

assert(!"abcd"); としたとき、実行すると上記文でアサートに引っかかります。 ですが、!"abcd"がどうしてfalseとして評価されるのか理解できません。 if()の()の中に"abcd"と書くと1として評価されるということなのでしょうか? char* c = "abcd"; とするとcにはaの部分のアドレスが入るのに、どうしてif("abcd")でabcdが1と評価されるのでしょうか? よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

Cでは、ポインタを定数として評価すべき場所では、以下のように扱われます。 ・ポインタの値が NULL であるとき → 定数0 と等しい ・ポインタの値が NULL でないとき → 定数0 とは等しくない さて、ちょっと回りくどい表現に見えると思います。 これは、NULL と 0 との区別などを含めたいろいろな話があるのですが、上記のような定義になります。 (NULL はあらゆる処理系で、必ずしも0番地になるとは限らないが、定数0と比較すると、必ず等しくなる、ということでありますが) ですから、"abcd" は、有効なポインタなので、「定数0とは等しくない」と評価されます。 最終的に ! (定数0とは等しくないもの) なので、0になります。 また、if("abcd") などと書くと、 "abcd" は、「定数0とは等しくない」ので、if() の条件は成立することになります。 if() をはじめとした、いわゆるCの「条件」は、「定数0と等しくないとき、真、定数0と等しいとき偽」という扱いになります。 つまり、if(何かのポインタ)は、if (何かのポインタ != 0) と等価でして、言い換えると、if( 何かのポインタ != NULL )と等価です。

rotofrot
質問者

お礼

ありがとうございます。 よく理解できました。助かりました。

その他の回答 (2)

回答No.2

> char* c = "abcd"; > とするとcにはaの部分のアドレスが入るのに、 アドレスが入る、すなわち"cは0ではない"てことです。 > どうしてif("abcd")でabcdが1と評価されるのでしょうか? 1と評価されるのではありません。"0ではない"と評価されます。 "0ではない" → "falseではない" → true となります。

rotofrot
質問者

お礼

0ではないの反対だから0というわけですね。 ありがとうございます。

  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

>!"abcd"がどうしてfalseとして評価されるのか理解できません。 仕様です。

rotofrot
質問者

お礼

ありがとうございます。

関連するQ&A

  • 自作Assert関数が上手く動作しません...

    開発環境:VisualStudio2013 言語:C++ Assert関数を自作してみようと思いコードを書いてみたのですが、 上手く動作してくれません。。。 お手数をおかけしますが、どなたかご指導お願いできないでしょうか? 現状:  ・char* p=NULL; ←NULLで初期化  ・ASSERT( p ); ←これは、問題なくエラー出力してくれる 問題:  ・char* p; ←初期化しない  ・ASSERT( p ); ←エラー出力してくれない。。。。 というように、ポインタにNULLが入っていないとエラー出力してくれないのです。 ソースコード template<class T> inline void ASSERT(T&p) { if ( !( p ) ) ←p がNULLで初期化していると条件文の中に入ってくれるが、 {        初期化してないと、入ってくれない・・・・ //自作ログ出力関数 OutputLogString(TEXT("Assertion Failure:%s(%d)"), __FILE__, __LINE__); } } void main(void) { char* p; ASSERT(p); } ポインタpが、NULLならもちろん、初期化されていなくてもエラーとして受け取ってくれるには、 何が足りないのでしょうか? お手数をおかけしますが、ご回答よろしくお願いします

  • mallocについて

    mallocで得るアドレスの使い方が分からなくて困っています。 void main(){     char *mem;     char *initial_address; /*初期アドレス保持*/     mem = (char*)malloc(5);     printf("malloc mem -> %p\n", mem);     initial_address = mem;     mem = "abcd";     printf("%c - %p\n", *mem, mem);     printf("%c - %p\n", *initial_address, initial_address); } なぜかmem = "abcd";を実行するとmemのアドレスが変わってしまいます。 mallocで得た5byteはmem = "abcd";実行後のアドレスから5byteということでしょうか。。 それとmem = 'a';を実行するとmemのアドレスはなぜか変わりません。 どうか、ご教授よろしくお願いします。m(__)m

  • If文を2つ並べると2つ目の文が実行されない。

    プログラムの中で*A*のIf文は実行されますが、*B*のIf文は実行されません。 何故でしょうか?教えて下さい。 ちなみに、<中略>の部分にもIf文は同じ様にあります。(内容は違うけど) <SCRIPT language="javascript"><!-- function ka() { ******<中略>****** *A* if (document.fomu.email.value ==""){        alert ("メールアドレスを記入して下さい。");        fomu.email.focus();        return false; } *B* if (document.fomu.email.value.match(/\w+@\w+/){        alert ("正しくメールアドレスを記入して下さい。");        fomu.email.focus();        return false; } ******<中略>******* } //--></SCRIPT>

  • C言語 char 型 を数値として読み込む

    C言語において abcd5678efg abcd5679efg abcd5680efg という文字が char型であります.(fgetで読み込んだ値ですが.) でそれをif文で 5文字目~8文字目までの数値が 5679以上の場合は ** という作業をしたいのですが if ( name[5~8文字目] > '5679') みたいな感じで. どのようにしたらいいですか,よろしくお願いいたします.

  • C# こういう場合ってどうなるの?

    public void A(bool b) {   if(b ? B() : C())//分かると思いますが、三項演算子   {     //略   } } public bool B() {   return true; } public bool C() {   return false } 上記のAにtrueを渡し実行した場合、 if文の中はどうなるのでしょうか? 引数がtrueならBを実行し、Bの戻り値trueが if文で処理され、if内に入る・・・でよろしいのでしょうか? それとも引数bの評価がそのままifで使われるのでしょうか? 例えばのコードなので、bだろうがBだろうが変わらない・・・みたいな 回答はご遠慮ください。

  • 正規表現ですが・・・

    正規表現なんですが(Perlです。) Aa_abcd_aa.txt Aa_abcd_bb.txt Aa_abcd_cc.txt Bb_abcd.txt 上記のabcdの部分をマッチさせるために (?<=Aa_|Bb_).*(?=_aa|_bb|_cc|\.txt) としてみましたが、これでは Aa_abcd_aa.txt Aa_abcd_bb.txt Aa_abcd_cc.txt のabcd_aaやabcd_bbやabcd_ccとマッチしてしまいます。 なにかよい表現の仕方はありますか? まとめてマッチさせる表現が知りたいです。

  • C言語におけるif文の評価順

    たとえば以下のようなif文で、A B C が評価される順番は 言語の規約上、明確になっているのでしょうか? if ( A && B && C ) { } また例えば A, B, C の順番に評価されるとして、B が FALSE の場合は C を評価する必要はありませんが、 この場合、Cは評価されないことは言語規約上、明確に なっているのでしょうか? 手元のコンパイラで試した結果では 評価順は A -> B -> C で B で FALSE を返すようにしたら C は実行されませんでした。 ただ、これが実装依存か、言語の標準仕様かという点が 気になっています。

  • 間違いが理解できない!!

    下に投稿を行ったばかりですが 質問させてください。 #include<stdio.h> int main(void) { int a; a=3 if(a==a/2*2){ printf("%d is EVEN \n",a); }else{ printf("%d is ODD \n",a); }return(0);} 課題文 「上記のプログラムを改造して、 aが正の場合はPLUSを、 aが負の場合はMINUSを、 aがゼロの場合はZEROを 表示するプログラムを作成し、 実行しよう。」 とあったので、私は #include<stdio.h> int main(void){ int a; printf("変数aに数字を入力してください\n"); printf("a="); scanf("%d",&a); if(a>0){ printf("%d is plus\n",a); }else if(a==0){ printf("%d is zero\n",a); }else{ printf("%d is minus\n",a); } return(0); } と作成しました。 しかし、評価はFAIRでした。(PASS,FAIR,RETRYがあり、 FAIRは「課題を取り違えているがOK.ただし満点じゃない」です) なぜかと言うと、習っていないscanfを使ったかららしく、 課題と違うからだそうです。 習っていないものを使ってはいけないなど聞いてもいませんし、 (私はC言語の知識がある程度あったのでscanfを使いました) 納得いきません。 もし、課題文が、 「上記のプログラムの if文以下を改造して・・・」 となっていたら、私のプログラムは間違いです。 しかし、改造してとしか書いてなかったので、 間違いではないと思います。 皆さんはどうおもいますか?

  • C言語 動的なメモリの確保 実行できない

    malloc関数を使いメモリを確保しそこへ"ABCD"と記憶させ、ポインタ*Cを使い確保したメモリの内容を表示するプログラムです。 ********************************************* #include <stdio.h> #include <stdlib.h> int main(void) {   int i;   char *C;   C = (char *) malloc (sizeof(char) * 5);   C = "ABCD";   for(i = 0; i < 5; i++){     if(C[i] != NULL){       printf("%s", C[i]);    ←※エラー※     }   }   free(C);   return 0; } ********************************************* 正常にコンパイルできますが実行エラーになります。VCを使いF10のデバッグテストで※のところエラーになります。なぜなのでしょうか?

  • EXCELのFALSE行削除について

    EXECLでif文実施結果でFALSE行が発生してしまいます。 この行を自動で消す方法はありますでしょうか? マクロで実施する方法でもご存知でしたらご教授願います。 例 sheet1               sheet2   A  B  C  D            A      B      C      D 1 11 12  a  x         1 11     12      a     あいう      2 11 12  b  x   ⇒     2 FALSE FALSE   FALSE   FALSE 3 11 12  a  x         3 11     12      a     あいう 4 11 12  b  x         4 FALSE FALSE   FALSE   FALSE sheet2A1にif=('sheet1'!C1="a",'sheet1'!A1) B1にif=('sheet1'!C1="a",'sheet1'!B1) C1にif=('sheet1'!C1="a",'sheet1'!C1) D1にif=('sheet1'!C1="a","あいう") として、これを1行目のif文を下にコピーして使用しています。 又、もっと効率のいい方法がある! と言った答えもいただけたら非常に助かります。 よろしくお願いします。

専門家に質問してみよう