• ベストアンサー

論理演算子について

◎1----------------------------- int main(void) { int a=10,b=20; while(1){ if(a= =12 && b= =25){ break; } ++a; ++b; } return 0; } -------------------------------- ◎2------------------------------------------------------- #include<stdio.h> #include<ctype.h> int main(void) { char ss[256]="10%%'%shin(no((100!w**a'16&'shi&%$#n~|=~de)&64"; int dt,i=0; printf("右の文字列には言葉が隠れています: "); printf("%s\n",ss); puts(""); printf("1を入力すると言葉が分かります: "); scanf("%d",&dt); puts(""); while(dt!=1 && ss[i] !='\0'){ if( !isalnum(ss[i]) ){ ss[i]=' '; } ++i; } printf("%s\n",ss); puts(""); return 0; } ------------------------------------------------------------ 以上2つのプログラムにおいて疑問があります。 まず◎1のプログラムで、aが12、bが25になるという2つの条件を満たしたら、プログラムを終了させようと思ったのですが、条件を満たしても、ずっとデクリメントし続け終了しません。 「if(a= =12 && b= =25)」の部分を「if(a= =12 || b= =25)」とすれば、aが12になった時点で終了しました。 ◎1では「if(a= =12 && b= =25)」という条件が何故適用されないかという疑問があります。 次に、◎2ではdtが1になり、配列ssに格納されている文字列が、'\0'になるという2つの条件を満たしたら終了させようとしたのですが、1を入力すると、「ss[i]!='\0'」の条件が偽にもかかわらず、while文が一度も実行されませんでした。 そこで、1以外を入力すると、while文は実行されましたが、dtの条件が真になる事はないのに、ちゃんと終了しました。 プログラム◎1、◎2について何故こうのようになってしまうのか、教えていただければ嬉しいです。

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

  • ベストアンサー
  • Kennis
  • ベストアンサー率100% (1/1)
回答No.8

◎2に関して。 表示部分等を省いて敷き詰めて書くと、 char ss[256]="10%%'%shin(no((100!w**a'16&'shi&%$#n~|=~de)&64"; int dt,i=0; scanf("%d",&dt); while(dt!=1 && ss[i] !='\0'){ if( !isalnum(ss[i]) ){ ss[i]=' '; } ++i; } こういう文なわけですが、 while文はwhile(…)の…の部分が「真」であれば{}内の処理を実行します。 上の…の部分を見てみると、 dt != 1 && ss[i] != '\0' 訳すと、dtが1じゃない かつ ss文字列のi文字目が'\0'じゃない ならば真 &&演算子は、左辺と右辺どちらも真ならば真を返します。 >>1を入力すると、「ss[i]!='\0'」の条件が偽にもかかわらず、while文が一度も実行されませんでした。 1を入力すると、「dtが1じゃない」という条件に対しては「偽」を返します。 よって、どちらも真ならば…という条件を満たさないので、dt != 1 && ss[i] != '\0'は「偽」が返され、while文は{}内の処理を1度も実行しません。 >>「ss[i]!='\0'」の条件が偽にもかかわらず &&演算子を理解しているなら、「「ss[i]!='\0'」の条件が真にもかかわらず」という勘違いの方がましだと思います。 どちらも真であれば、while文の{}内の処理が実行されます。 >>そこで、1以外を入力すると、while文は実行されましたが、dtの条件が真になる事はないのに、ちゃんと終了しました。 1以外を入力すると、「dtが1じゃない」という条件に対しては「真」を返します。 ちゃんと終了したのは、「ss文字列のi文字目が'\0'じゃない」が途中で「偽」になったからです。 文字列についても一応説明しておくと、 char ss[4]="abc"; とすると、実際には ss[0] = 'a' ss[1] = 'b' ss[2] = 'c' ss[3] = '\0' と格納されているので、途中で\0が現れます。 一通り答えてみてから気づきましたが、&&演算子以前に、 >>dtの条件が真になる事はないのに、 が一番の勘違いの原因かな。 dt != 1 訳すと、「dtが1じゃない ならば真」 dtに1以外を入力すると真です。 dtに1を入力すると偽です。 上に書いた内容を理解すれば、「回答番号:No.2へのお礼」での疑問も解決すると思います。 理解できなければ、参考URLを熟読したら理解できると思います。 「真理値表 C言語」でググって2番目に出ました。

参考URL:
http://www.asahi-net.or.jp/~AX2S-KMTN/ref/logicope.html
muffler
質問者

お礼

ご回答ありがとうございます。 どちらかの条件式が偽になれば処理をしないという理解が、完全に曖昧でした。そして「!=」という記述に対して、どちらが真偽であるか混乱してしまいました。    条件式1     条件式2     結果      真        真         真      真        偽         偽      偽        真         偽      偽        偽         偽 論理積演算子は左辺式、右辺式が両方真でない限り処理が行われないという事と、以上の真偽関係をしっかり頭に入れておきます!

その他の回答 (7)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.7

>aが12になった時点で、aはデクリメントされないという デクリメントするコードは、もともとどこにも見あたらないです。 もしかすると、インクリメント(++)とデクリメント(--)とを 取り違えられているのかもしれません。

muffler
質問者

お礼

お礼内容、質問内容の記述はインクリメントの間違いでした。 すいません。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.6

>ここにそのまま書き込むと、代入演算子のように見えた 一見そのように見えますが、=の長い短いで判断できます。 なるべく、お手持ちのソースコードに手を加えることなく、 そっくりそのまま載せてくださる方がよいです。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.5

◎2 dtの値はループの中で変化しません。 したがって、while文の条件にする必要がありません。 if文で1回だけ判断すればじゅうぶんです。

muffler
質問者

お礼

確かにdtは常に一定なので、条件式としては意味はないですね。。 でも今回、dtを条件式に入れた事によって何故このような処理が行われたのか、疑問に思いました。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.4

== 演算子を = = のように空白をあけて書くと、 コンパイルエラーが出ませんか?

muffler
質問者

お礼

ご回答ありがとうございます。 ここにそのまま書き込むと、代入演算子のように見えたので、スペースを入れて書き込みいたしました(;^_^)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

◎1だけ回答します。 if(a= =12 && b= =25){ break; } の意味は、 aが12で かつ bが25の場合、breakが実行されます。 従って、aが12になったとき、bは22なので、breakは実行されません。 >>「if(a= =12 && b= =25)」の部分を「if(a= =12 || b= =25)」とすれば、aが12になった時点で終了しました。 if(a= =12 || b= =25){ break; } の意味は、aが12 または bが25 の場合、breakが実行されます。 従って、aが12になった時、bは何でもよいので(b=22ですが) breakが実行されます。 && の意味と || の意味をきちんと理解することが大切です。

muffler
質問者

お礼

ご回答ありがとうございます。 aが12になった時点で、aはデクリメントされないという、馬鹿な考えをしていました。恥ずかしい限りです。。 詳しくご説明ありがとうございました。 後、&&の意味と||の意味をきちんと理解しておきます!

  • yokomaya
  • ベストアンサー率40% (147/366)
回答No.2

◎2 dt!=1 ですからdtが1ではないという条件を求めていますが? 「dtの条件が真になる事はないのに」というのは たんなる勘違いでは?

muffler
質問者

お礼

ご回答ありがとうございます。 まずdt側の終了条件をscanf入力によりあらかじめ満たしておいて、その後、デクリメントされた後、ss[i]側が'\0'になり、2つの終了条件を満たし、終了させるという事をさせようと思ったのですが、何かやはり勘違いがありますかね? 後、1以外を入力した場合、「1以外の場合はループを続ける」ということで、ループが終わらないと思ったのですが、終わってしまいました。 以上についてご回答いただければ嬉しいです。

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

> ◎1では「if(a= =12 && b= =25)」という条件が > 何故適用されないかという疑問があります。 a==12の時はb==22でありb==25の時にはa==15なので、 a==12 && b==25という条件は永遠に有り得ません。 集合はやらなかった世代か弱いですか? あまり考える所ではないのですが、センスなのかな? 2はパスです。

muffler
質問者

お礼

ご回答ありがとうございます。 >a==12の時はb==22でありb==25の時にはa==15なので、 >a==12 && b==25という条件は永遠に有り得ません。 そうですよね♪ 何か恥ずかしいです(;^_^) ありがとうございました。

関連するQ&A

  • 数値連続入力プログラムでの配列に格納される文字について

    -------------------------------------------------------- #include<stdio.h> int main(void) {    double sum=0.0;    double dt,x    int ret,n;    char ss[80];    ret=scanf("%lf",&dt);    while(1){       if(ret==1){          x=sum;          sum+=dt;          n=getchar();         if(n=='\n'){            printf("入力された数値=%f\n");            puts("");            sum=sum;         }         else{          printf("正しく入力してください\n");          puts("");          gets(ss);          sum=x;          dt=0.0;         }       }       else if(ret!=0){          gets(ss);          dt=0.0;          printf("正しく入力してください\n");          puts("");       }       else if(ret==EOF){          break;       }       ret=scanf("%lf",&dt);    }       printf("合計=%f\n",sum2);       return 0; } -------------------------------------------------------- 前回、「scanfの入力をgets関数で読み捨てることについて」というタイトルで数値連続加算のプログラムを作り、皆様からいろいろとアドバイスを受けた者です。 いろいろとプログラムを改良し、「Ctrl+Z」の入力でプログラムを終了しようとし、後、前のプログラムでは「10abc」などと打ち込んでも「10」は読み込んでしまうので、「10abc」などと打ち込んだ時点で、エラー表示をさせるようにしました。 ここで疑問なのですが、例えば、 ------- enter enter abc ------- と入力した場合、改行文字が配列ssに格納され、いろいろと複雑になってしまうのかと思ったのですが、ssにはしっかり「abc」だけが格納されていました。 以上のプログラムに不備がないかも含めて、何故そうなるのか教えていただけると嬉しいです。

  • for文内でscanf関数により配列に数値を格納することについて

    プログラミング初心者です。 よろしくお願いします。 ◎1------------------------------------ #include<stdio.h> int main(void) { int i,dt[3]; for(i=0;i<3;++i){ printf("dt[0]=%d\n",dt[0]); printf("dt[1]=%d\n",dt[1]); printf("dt[3]=%d\n",dt[3]); scanf("%d",&dt[i]); printf("i=%d\n",i); puts(""); if(dt[i]==0){ break; } } printf("dt[0]=%d\n",dt[0]); printf("dt[1]=%d\n",dt[1]); printf("dt[2]=%d\n",dt[2]); printf("dt[3]=%d\n",dt[3]); printf("i=%d\n",i); puts(""); i=1; while(1){ printf("%d ",i); if(1000<i){ break; } i*=2; } puts(""); return 0; } ---------------------------------------- ◎2------------------------------------ #include<stdio.h> int main(void) { int i,dt[2]; for(i=0;i<3;++i){ printf("dt[0]=%d\n",dt[0]); printf("dt[1]=%d\n",dt[1]); printf("dt[2]=%d\n",dt[2]); scanf("%d",&dt[i]); printf("i=%d\n",i); puts(""); if(dt[i]==0){ break; } } printf("dt[0]=%d\n",dt[0]); printf("dt[1]=%d\n",dt[1]); printf("dt[2]=%d\n",dt[2]); printf("i=%d\n",i); puts(""); i=1; while(1){ printf("%d ",i); if(1000<i){ break; } i*=2; } puts(""); return 0; } ---------------------------------------- 以上2つのプログラムについて疑問があります。 まず◎1については、あえて添え字のdt[3]の値を見てみようと思ったら、iの値が入っているとわかりました。 しかし、何故添え字の番号の配列にiの値が入っているのかがわかりません。 次に◎2ですが、3回目のループで、添え字の番号の配列自身に入力した数値を格納すると、iと添え字番号配列に入力した数値が入っていました。 何故このようになっているのか疑問です。 以上のような疑問があります。 添え字の番号の配列とiが何か関連があるようですがいまいちわかりません。 教えていただけると嬉しいです。

  • scanfの入力をgets関数で読み捨てることについて

    -------------------------------------- #include<stdio.h> int main(void) { double dt=0.0,sum=0.0; char ss[80]; int ret; ret=scanf("%lf",&dt); puts(""); if(ret!=1){ gets(ss); printf("数値を入力してください\n"); puts(""); } while(dt!=999){ sum=sum+dt; ret=scanf("%lf",&dt); puts(""); if(ret!=1){ gets(ss); printf("数値を入力してください\n"); puts(""); } } printf("合計=%f\n",sum); return 0; } -------------------------------------- 以上のプログラムで、入力した数値の合計を出し「999」が入力されたら終了させ、数値以外が入力されたら、gets関数で読み捨て入力を続けていくということをしたいのですが、例えば、 ◎1----------- 2 3 4 999 合計=9.000000 --------------- ◎1のように数値のみだと正しく表示されます。 次に、 ◎2-------------------- a 整数を入力してください b 整数を入力してください 2 3 999 合計=5.000000 ------------------------ ◎2のように数値以外を先に入力し、その後に数値を入力しても正しく表示されます。 次に、 ◎3------------------- 2 3 a 数値を入力してください b 数値を入力してください 999 合計=11.000000 ----------------------- ◎3のように数値を入力した後に、数値以外を入力したら正しく表示されません。 次に、 ◎4-------------------- 2 a 整数を入力してください b 整数を入力してください 3 999 合計=9.000000 ------------------------ ◎4のように数値をまず入力しその後、数値以外を入力する。その後、数値を入力して終了させても、合計値が正しく表示されません。 まだ、バッファについて完全に理解していないということもあり、何故こうなってしまうのか分かりません。 教えていただけると嬉しいです。

  • scanf関数の戻り値について

    --------------------------------------- #include<stdio.h> int main(void) { int dt; while(scanf("%d",&dt)==1){ if(dt==0){ printf("0は入力しないでください\n"); puts(""); } else if(dt<0){ dt=-dt; printf("入力値の絶対値は「%d」です\n",dt); puts(""); } else{ printf("入力値の絶対値は「%d」です\n",dt); puts(""); } } return 0; } --------------------------------------- 以上のプログラムについて疑問があります。 scanf関数の戻り値が1の間、繰り返すというもので、入力の時に整数入力ですが、あえて実数である1.1を入れたとします。 scanfの戻り値は1で、dtには整数部の1だけ設定されていたので、これでもうまくいくのかと思ったのですが、次の入力はscanfの戻り値が0になっていて出来ませんでした。 何故0になっているのかわかりません。 入力バッファに何か残ってしまっているということなのでしょうか? 以上教えていただけると嬉しいです。

  • 条件演算子

    このプログラムをIF文じゃなくて条件演算子を使って書き換えることはできますか? #include <stdio.h> int main(void) { int vx; printf("整数入力しなさい:"); scanf("%d,&vx"); if(vx) puts("その数は非0");   else puts("その数は0"); return(0); }

  • 2進数の加算の繰り上がり

    2進数の四則演算のプログラムを作りたいと思い、2進数を表示するところまではできたのですが、加算になると繰り上がりという壁にぶつかってしまいました。繰り上がりや桁上げなどがよく分からないので、お教えください。(下のソースコードが繰り上がりのない加算をするまでのものです) #include <stdio.h> int main(void) { int a,b,i,j,x[8],y[8],z[8]; do{ puts("二つの符号なし整数を入力してください。(ただしa>bとし、bはのべき乗の値とする)"); printf("a="); scanf("%d",&a); printf("b="); scanf("%d",&b); if(a < = b) puts("入力した値がa>bになっていません。\a"); }while(a < = b); for( i = 0; i < = 7; i + +){ x[i] = a % 2; a = a / 2; y[i] = b % 2; b = b / 2; } puts("aとbをそれぞれ二進数で表すと"); printf("a="); for( i = 7; i > = 0; i - -){ printf("%d",x[i]); } puts(""); printf("b="); for( i = 7; i > = 0; i - -){ printf("%d",y[i]); } printf("となります。\n\n"); printf("<加算>\n"); printf("c=a+b="); for( j = 7; j > = 0; j - -){ z[j]=x[j]^y[j]; printf("%d",z[j]); } return(0); }

  • C言語の演算式

    C言語のプログラミングで、4×(1-1/3+1/5-1/7+・・・・・)の式を100000項まで合計した式を作りたいです。答えは3.141591になります。 自分で作成してみたのですが、なかなか上手くいきません。 どうすればよいでしょうか?以下自分の作成したプログラムを「」内に載せます。 答えは0になってしまいます。 「 #include <stdio.h> int main(void) { int i=0,a=1,b; do{ i++; if(i%2) { a+=(-1)/(2*(i-1)+1); } else{ a+=1/(2*(i-1)+1); } }while(i<100000); b=4*a; printf("π=%f\n",b-1); putchar('\n'); return (0); } 」

  • 素数判定の繰返し

    繰返し素数判定を行ない、CtrlーDで終了するプログラムをつくっています。 まず繰返しなしの素数判定プログラムを作り #include<stdio.h> int main(void) { int a,i; printf("自然数を入力:"); scanf("%d",&a); if(a<=0) printf("入力エラーです。\n"); else if(a==1) printf("1は素数ではない。\n"); else{ for(i=2; i*i<=a; i++){ if(a%i==0) break; } if(i*i>a) printf("%dは素数です。\n",a); else printf("%dは素数ではない。\n",a); } return(0); } これはちゃんとできたのですがそれを繰り返すことができません。 #include<stdio.h> int main(void) { int a,i; printf("自然数を入力:"); scanf("%d",&a); while((a=getchar())!=EOF){ if(a<=0) printf("入力エラーです。\n"); else if(a==1) printf("1は素数ではない。\n"); else{ for(i=2; i*i<=a; i++){ if(a%i==0) break; } if(i*i>a) printf("%dは素数です。\n",a); else printf("%dは素数ではない。\n",a); } printf("自然数を入力:"); scanf("%d",&a); } printf("プログラムを終了します。\n"); return(0); } これは訳わからないことになっちゃいます。。。 どうしたらいいんでしょうか??

  • 条件演算子論理ORについて

    すみません、独学でC言語を学んでいるものです。 どうかお助けいただけませんか? テキストに載っているものをそのままコンパイラしているのに エラーがでました。どこがいけないのか確認していただけませんか? *Memopad.cppで作ったプログラム* #include<stdio.h> void main(void) { int a,b,c; a=0; b=0; c=0; if((a=1)||(b=2)||(c=3)) { printf("%d\n",a); printf("%d\n",b); printf("%d\n",c); } } *エラーメッセージ* 添付を参照下さい。 うまくいくと 1 0 0 と表示されるようです。ずっと考えてもわからなかったのでお力を貸して頂ければ助かります。 よろしくお願いします。

  • cプログラム

    #include<stdio.h> /*Calc MAX of (a,b)*/ int max(int x,int y) { if(x>y) return x; else return y; } /*Calc n!*/ void fact(int n) { int i,ans; ans=1; for(i=n;i>=1;i--){ ans*=i; } printf("ans=%d\n",ans); } /*END*/ void end() { printf("Thanks\n"); exit(0); } /*Main*/ int main() { int key; int a,b,saidai; int n; while(1){ puts("\n=====Main MENU ====="); puts("1.......max(a,b)"); puts("2.......n!"); puts("9.......END\n"); printf("Input No(1,2,9)=?"); scanf("%d",&key); switch(key){ case 1: printf("Inputs:a,b?"); scanf("%d,%d",&a,&b); saidai=max(a,b); //Call max(a,b) printf("max(%d,%d)=%d\n",a,b,saidai); break; case 2: printf("Input:n?"); scanf("%d",&n); fact(n); break; case 9: end(); break; default: printf("!!!!!Miss Input_No!!!!!\n"); break; } } のプログラムなのですが、1の処理を行った場合max(a,b)の値が正しく表示されません どこを直せばいいでしょうか? return(0);

専門家に質問してみよう