• 締切済み

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ではないんでしょうか・・・? 変な質問ですみません。 お願いします。。。

みんなの回答

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.3

>xは2進数で1010で、yはnot演算子より0101になるので ★1文字は8ビットだから、00001010 だよね。  それを「not演算」すると・・。 また、 >char x,y; として宣言しても、 ★代入など y = とした時点で y は(32ビットの)「レジスタで作られる」と考えればいいのでは。 また、 >printf( "%x\n", x ); と %x という「フォーマット指定子」を用いた時点で、x は「整数」扱いされたと。 http://www.k-cube.co.jp/wakaba/server/format.html なお、下のソースの出力をIOリダイレクトでファイルにし、◆部分をバイナリエディタで見ると 0D 0A F5 F5 0D 0A と頭に 0D がついているのは、・・・判りません(残念)。 ( %c という「フォーマット指定子」は、F5 F5 と正常(?)) ☆頭の 0D は、x が 0x0A で、たまたま改行(LF)コードだから、  ペアの復帰(CR)コード 0x0D が付加されたのかな(そんなのあり?)。 char x, y; x = 0x01 + 0x00 + 0x04 + 0x03 + 0x02; y = ~x; printf( "%02X,%02X,%02X\n", x, y, (unsigned char)y ); printf( "%c%c%c\n", x, y, (unsigned char)y ); // ◆ (「回答」でなく「疑問」になっちゃった、申し訳ない)

全文を見る
すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

まず、「not演算子」というのは ~ ではなく ! です。<iso646.h>でnotというマクロが ! に定義されます。また、C++ではnotは予約語です。 次に、~x を評価する際には、最初にxが「汎整数拡張(C99では整数拡張)」されます。その結果、xがchar型であってもint型に暗黙的に型変換されるのです。その上で ~ 演算子が適用されます。 使用されている処理系が不明ですが、結果を見る限りではint型は32ビットなのでしょう。上位のビットにも0が詰まっていますから、~ 演算子によってそれらが反転して1になります。 それをchar型の変数yに代入しているのです。これまた厳密には処理系に依存するのですが、char型が符号付きで、かつ負の整数値に1の補数や2の補数を使うのであれば、char型の表現範囲に収まりますので、そのまま代入できます。しかし、符号ビット+絶対値を使う場合には表現範囲を超えるので処理系定義のシグナルが発生するか、処理系定義の値になります。char型が符号無しであれば問題ありません(今回は違うようですが...)。 そして最後に、printfにyを渡しているわけですが、可変個実引数としてchar型の値を渡した場合、「既定の実引数拡張」が起こります。結果としてchar型の値はint型に暗黙的に型変換されます。お使いの処理系ではchar型が符号付きだったのでしょう。符号拡張されたために上位のビットが1になっているのです。

全文を見る
すると、全ての回答が全文表示されます。
  • shimix
  • ベストアンサー率54% (865/1590)
回答No.1

>xは2進数で1010で、yはnot演算子より0101になるので なぜ1バイトにも満たない2進4桁なんでしょう?最低でも(1バイトでも)11110101(f5)ですよね?で、%xが指定されているので、先行する部分にffが補われているだけだと思います。符号付整数で考えればわかると思いますが・・。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ビット演算について

    以下のプログラムを作成して、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

  • 論理演算について

    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進数だと強調するためにあるのですか? 説明に不足があればまた足しますのでよろしくお願いします。

  • インクリメント演算子について

    インクリメント演算子について プログラミング超初心者です。 大学のプログラミングの課題で インクリメント演算子を使って 数字をひとつずつ大きく(小さく)していくという課題が出ました 私が作ったプログラムは以下のとおりです #include <stdio.h> int main(void) { int x ; //変数宣言 printf("整数値を入力してください:"); scanf("%d",&x); printf("1ずつ増加\n"); printf("%d,",x++); printf("%d,",x++); printf("%d,",x++); printf("%d,",x++); printf("%d\n",x); printf("1ずつ減少\n"); printf("%d,",x--); printf("%d,",x--); printf("%d,",x--); printf("%d,",x--); printf("%d\n",x--); } ちなみに、整数値は10にしました。 結果は 1ずつ増加 10,11,12,13,14 1ずつ減少 14,13,12,11,10 と、望んでるものになったのですが、疑問があるので質問させていただきます。 xを変数にすると、x++はx+1になると思うのですが表示されたのは10、11、…と 10から表示されました。 しかも、増加していった最後のxはなぜ14になるのでしょうか? 課題は出来たのですが、頭が混乱しています… 詳しく解説をお願いします。

  • 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); } できれば途中のトレースも書いていただけると助かります。 よろしくお願いします。

  • ビット演算について

    いつもお世話になります。 ビット演算について教えて下さい。 unsigned char buf1[1]=0x5a unsigned char buf1[2]=0x04 unsigned char buf1[3]=0x38 5a0438(16)を3バイトの値を12ビットずつの整数で得るにはどうしたらいいのでしょうか? 2進数表記では、 5A | 04 | 38 01011010 | 00000100 | 00111000 12ビットずつとは、 010110100000 010000111000 と区分し、10進数の整数値で得たいです。どのようにすればよいでしょうか? また、0x5Aなどの16進数を2進数のビットで考えるときに、 01011010を下位4ビットを10進数整数を得るにはどうしたらよいのでしょうか? 上記2点、どうぞよろしくお願い致します。

  • 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); } できれば途中のトレースも書いていただけると助かります。 よろしくお願いします。 なお、先ほど記述ミスがあるのにも関わらず投稿してしまいました…。 正しい記述はこちらの質問です。 大変失礼しました。 前の質問は削除可能になり次第、削除いたします。

  • perl 条件演算子 範囲演算子についてです

    演算子 条件演算子 条件演算子 ?: は条件式の値により、2者のうちのどちらかを選択します。 $a=($x<10)?10:20; 変数$aの値が$x<10という条件において、真であれば:左側の10を選び、偽であれば:右側の20を選ぶ。 $a=10; 変数$aに10を代入する。 $a==5?print "5です。\n":print "5ではありません。\n"; 条件式でaが5であれば:左側の print "5です。\n"を表示します。 条件式でaが5でなければ:右側の print "5ではありません。\n"を表示します。 $a==10?print "10です。\n":print "10ではありません。\n"; 条件式でaが10であれば:左側の "10です。\n" を表示します。 条件式でaが10でなければ:右側の "10ではありません。\n" を表示します。 範囲演算子 範囲演算子 .. は、左側の値から右側の値まで、1つずつ増やした値の集まりです。 値には、半角英数字の数値または文字列が指定できる。 print 3..5; 3 4 5 と表示する。 一応、訳を下に書いたのですが合っていますでしょうか。

  • 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); }

  • C言語 strlen 再入力を促す

    文字列の比較で、 文字列の長さが60以上の時、再入力を促します。 while文を使って書いてみたのですが、 文字列Bの入力の前に、もう一度意味もなく 「文字列Aを入力===>」が表示されたり。 文字列Aのほうが小さいのに「Aのほうが大きい」と 表示されるようになったり、変な感じです。 どなたかご指摘・ご指導のほどよろしくお願いします。 int main(void) { char moji1[100]; char moji2[100]; while(strlen(moji1)>60){     printf("文字列Aを入力===>"); scanf("%80s" ,moji1); } while(strlen(moji2)>60){     printf("文字列Bを入力===>"); scanf("%80s" ,moji2);    } if(compare(moji1,moji2)>0){ printf("===AはBより大きい===\n"); } else if(compare(moji1, moji2)<0){ printf("===AはBより小さい===\n"); } else if(compare(moji1, moji2)==0){ printf("===AとBは等しい===\n"); } return 0; } int compare(char *x, char*y) { while(*x==*y && *x!=0){ x++; y++; } return (*x-*y); }