• ベストアンサー

論理演算について

Cを勉強中の者です。論理演算についてよくわからいことがあります。 以下のソースコードを実行し結果が真なら0001、偽なら0000が出力されるプログラムを作りました。 #include <stdio.h> int main(void) { unsigned short a = 0x1234; unsigned short b = 0xfafc; unsigned short c = 0xcdef; unsigned short x, y; x = a && b; y = b && c; printf("x=%04x\n", x); printf("y=%04x\n", y); return 0; } 結果はx=0001, y=0001となります。y=0001はbとcの文字列がそれぞれfとcをを持っているので演算による結果は納得できますが、x=0001はaとbの文字列には共通するものがないのになぜx=0000ではないのでしょうか? また0xが頭に付く表現は16進数だと強調するためにあるのですか? 説明に不足があればまた足しますのでよろしくお願いします。

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

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

まず認識間違いを >y=0001はbとcの文字列 >x=0001はaとbの文字列には aもbもcも「数値」です。「文字列」ではありません。 >y=0001はbとcの文字列がそれぞれfとcをを持っているので演算による結果は納得できますが 「代入している内容の一部に同じ『文字』があるから」 というおかしな考え方で納得していませんか? >共通するものがないのになぜx=0000ではないのでしょうか? a~cまでは「0」ではないため「真」の扱いです。 「真 && 真」なら、導きだされる解は「真」です。 >また0xが頭に付く表現は16進数だと強調するためにあるのですか? 強調ではなく「仕様」です。 そうでないと8/10/16進数の区別がつきません。

shomarket
質問者

お礼

結果が0でなけれ真ということですね。真 && 真 とう書き方で納得しました。aもbもc 0ではないから 真 && 真の結果は真で0001ということですね。理解しました。ありがとうございます。

その他の回答 (5)

  • Interest
  • ベストアンサー率31% (207/659)
回答No.6

ビット単位でみた論理演算の過程を示します。 a = 0x1234 = 0001 0010 0011 0100 b = 0xFAFC = 1111 1010 1111 1100 c = 0xCDEF = 1100 1101 1110 1111 a && b =   0001 0010 0011 0100 && 1111 1010 1111 1100 --------------------------   0001 0010 0011 0100 = 0x1234 --> 0(偽)ではないので真 以下、エンディアンって何?と思ったら無視してください。 上記の例はビッグエンディアンを仮定しました。リトルエンディアンの場合ビットの並び方が変わるのでご注意を。

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.5

a,b,cとも数値であって文字列ではありません。文字判断をしたいなら相応の処理が必要です。 また&&の演算結果はともに真(非0)なら真を返しますから、a&&b, b&&c, a&&cいずれも真です。 なお > 0xが頭に付く表現 は「16進表記であることを示すもの」です。 強調ではなく0xがないと16進表記であることをコンパイラは判断できません。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.4

aもbもcも文字列ではありません。数値です。 また、&&を使っているので、ビット演算ではありません。ただの論理演算です。 cでは0が偽、0以外が真として扱われます。 なので、a&&bは真アンド真なので、真です。 cで、真を数値に変換すると、1になりますので、 xの値は1となります。 yも同様。 論理演算ではなくビット演算を行いたい場合は&&ではなく&を使います。 >また0xが頭に付く表現は16進数だと強調するためにあるのですか? 強調ではなく、16進数で書くためには、必ず0xをつけなくてはなりません。

shomarket
質問者

お礼

なるほど、少し頭の中を整理することができました。結果が0でなければ真であると考えてよいわけですね。ありがとうございました。

回答No.2

ちなみに論理演算である場合文字列で見るわけではないので >bとcの文字列がそれぞれfとcをを持っている という解釈はおかしいです。 0x1234 は2進数表示だと 1001000110100 0xfafc は2進数表示だと 1111101011111100 となり論理和は 0001001000110100 1111101011111100 ---------------- 0001001000110100 → 0x1234 となります。 0xfafcと0xcdefの論理和はご自分で考えてみてください。

回答No.1

>x = a && b; >y = b && c; & では? && だと x : a かつ b → aは真、bも真なのでxは真になる→数値で1。 y : xと同様。

関連するQ&A

  • 論理演算結果の表示について

    Cで論理演算をするプログラムを考えているのですが、少し行き詰ってしまいました。 例えば(A+B)*(A+B+C)を論理演算で考えた場合、答えはA+Bとなりますがどうすればこの結果を画面に表示させる事ができるのかが分からないのです。 ただ単に #include <stdio.h> int main(void) { int a,b,c,y ; a = 'A'; b = 'B'; c = 'C'; y = a|b & a|b|c; printf("%c\n",y); } としたら表示結果は「C」となってしまいますよね(文字を2進で計算しているからこの結果になるという事は理解しています)。 もしかしてif文を使用して総当り的に文字を調べていくしか方法がないのでしょうか?実際はもっと複雑な演算をプログラムに計算してもらいたいと考えているので、他に方法がないか考えているのですが… どうかよろしくお願い致します。

  • 論理演算子について

    ◎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について何故こうのようになってしまうのか、教えていただければ嬉しいです。

  • ビット演算について

    以下のプログラムを作成して、int型、char型、long型のAND演算・OR演算の結果の違いを見ました。 実行結果からchar型だけ結果の表示の仕方が他と異なっています。 一般的に、バイト数では、 char(1バイト) < short(2バイト) < int(4バイト) のはずなのに、出力結果は、 char(0xffffffff) > short(0xff) = int(0xff) となっていて、charが一番大きく?、shortとintが同じ結果? のようにみえてしまいよくわかりません。 私は、ビット演算が苦手なので、根本的に考え方が間違っているのかも しれませんが、どうしてこのような出力結果となるのか教えてください。 プログラム #include <stdio.h> #include <stdlib.h> int main() { int xi = 0x7F, yi=0x80; int stri1 = xi&yi; int stri2 = xi|yi; printf("** int **\n"); printf("%p\n",stri1); printf("%p\n\n",stri2); char xc = 0x7F, yc=0x80; char strc1 = xc&yc; char strc2 = xc|yc; printf("** char **\n"); printf("%p\n",strc1); printf("%p\n\n",strc2); short xl = 0x7F, yl=0x80; short strl1 = xl&yl; short strl2 = xl|yl; printf("** short **\n"); printf("%p\n",strl1); printf("%p\n\n",strl2); return(0); } 出力結果 ** int ** 0x0 0xff ** char ** 0x0 0xffffffff ** short ** 0x0 0xff

  • 4の倍数を論理演算で表す。。

    /*Prog32.cキーボードから整数型変数aへデータを入力し、aの値が4の倍数のときは“4の倍数です”と表示し、そうでないときは、“4の倍数ではありません”と表示する。ただし、整数データのビット数はわからないものとし、計算にはビットごとの論理演算のみを用いる。*/ #include <stdio.h> int main(void) { int a; printf("整数を入力して下さい! "); scanf("%d", &a); (a % 4 ) ? printf("4の倍数ではありません。\n", a) :printf("4の倍数です。\n", a); return(0); } 4の倍数を論理演算で表す方法がわかりません。。 自分では上記のように算術を使うやりかたしかわかりませんでした。 よろしくお願いします!

  • C言語の演算について

    次のプログラムを実行したらどう出力されますか。 微妙な代入演算の違いが分からないので、教えていただけないでしょうか。 #include<stdio.h> void main (void) { int x = 5; int y = 8; int z = 3; int a,b,c,d,e,f; a = y == x + z; b = !x; c = x + y / z; d = x *=z - 1; e = --y / --z; f = y+++ % x++; printf("%d,%d,%d,%d,%d,%d\n",a,b,c,d,e,f); } できれば途中のトレースも書いていただけると助かります。 よろしくお願いします。

  • 条件演算子論理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言語 文字列の比較 compare

    プログラミング初心者です。 60文字以内の文字列を入力して、 大小関係を比較・表示するプログラムなのですが・・ 「AはBより大きい」という結果しか出ません。 どこが間違っているのか、ご指摘お願いしますっ。 #include<stdio.h> int main(void) { char moji1[61]; char moji2[61]; printf("文字列Aを入力===>"); scanf("%60s" ,&moji1); printf("文字列Bを入力===>"); scanf("%60s" ,&moji2); if(moji1-moji2>0){ printf("===AはBより大きい===\n"); } else if(moji1-moji2<0){ printf("===AはBより小さい===\n"); } else if(moji1-moji2==0){ printf("===AとBは等しい===\n"); } return 0; } int compare(char *x, char*y) { while(*x==*y){ if(*x=='\0') return 0; x++; y++; } return (*x-*y); }

  • 論理演算の問題です

    論理演算の問題です if( !( a > 0 && b == 0) ) は、 if( a <= 0 || b != 0 ) になりますか? また、 if( !( x > 0 || y < 0 ) は、 if( x <= 0 && y >= 0 ) になりますか? 遅い脳みそで考えました。 このような、論理演算を分かりやすくまとめられたサイトをご存知でしたら、 どなたか教えてください。 お願いします。

  • C言語の演算について

    次のプログラムを実行したらどう出力されますか。 微妙な代入演算の違いが分からないので、教えていただけないでしょうか。 #include<stdio.h> void main (void) { int x = 5; int y = 8; int z = 3; int a,b,c,d,e,f; a = y == x + z; b = !x; c = x + y / z; d = x *=z - 1; e = --y / --z; f = y++ % x++; printf("%d,%d,%d,%d,%d,%d\n",a,b,c,d,e,f); } できれば途中のトレースも書いていただけると助かります。 よろしくお願いします。 なお、先ほど記述ミスがあるのにも関わらず投稿してしまいました…。 正しい記述はこちらの質問です。 大変失礼しました。 前の質問は削除可能になり次第、削除いたします。

  • not演算子についてなんですけど

    つまらない質問ですみません。 char x,y; x = 0x01 + 0x00 + 0x04 + 0x03 + 0x02;    y = ~x; printf("%x\n", x); printf("%x\n", y); これを実行したところ xにはaと表示されたんですが、yにはfffffff5と表示されました。 なぜ「fffffff5」なんでしょうか?ただの「5」だと思うんですけど。 xは2進数で1010で、yはnot演算子より0101になるので 16進数では5ではないんでしょうか・・・? 変な質問ですみません。 お願いします。。。

専門家に質問してみよう