- ベストアンサー
困っています
どうしても、--unsigned型のビット内容表示--の所が意味が分かりません。分かりやすく教えてください。宜しくお願いします。 /* 0~UINT_MAXを2進・8進・16進で表示 */ #include <stdio.h> #include <limits.h> /*--- 整数xのセットされたビット数を返す ---*/ int count_bits(unsigned x) { int count =0; while (x) { if (x & 1u) count++; x>>=1; } return (count); } /*---- unsigned型のビット数を返す ----*/ int int_bits(void) { return (count_bits(~0U)); } /*---- unsigned型のビットを内容を表示 ---*/ void print_bits(unsigned x) { int i; for (i=int_bits() -1; i>=0; i--) putchar(((x>>i) & 1U) ? '1' : '0'); } int main(void) { unsigned i; for (i=0; i<UINT_MAX; i++) { print_bits(i); printf(" %6o %5u %4X\n", i, i, i); } return(0); }
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
############################################### No5さんへ、 >putchar(((x>>i) & 1U) ? '1' : '0'); どう考えても、 putchar((x>>i) & 1U); でいいと思うのだが? 間違っている?僕。 http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html を見てください。 putchar( にint型の1を与えると、SOHを出力するという意味になりませんか? putchar( にint型の0を与えると、NULLを出力するという意味になりませんか? 文字の1,0をpuchar(に与えるためには、 0x31 や 0x30 を与える必要がありますね。 文字定数 '1'は0x31と同じ意味です。 文字定数 '0'は0x30と同じ意味です。 なので、こうなります。 putchar(((x>>i) & 1U) ? '1' : '0'); ############################################### #####################################333 質問者さんへ >int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?) その通りですが。 もう一度、聞きますが・・。 シフト演算子の挙動は知ってますか? &がビットごとの論理積であることを理解しており、 その挙動については大丈夫ですか? それがわかってれば、わかるはずですが・・・。 >print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。 0000------0000001とビットごとの論理積をとって、上位ビットから(左側のビット)pucharで出力したいから。 int_bits() -1の-1が必要なのは、 Nビットある情報についてN-1ビット目から0ビット目まで処理したいからです。 例えば、 3ビットある情報は、 0ビット目、1ビット目、2ビット目の3ビットだとします。 int_bits()自体が3を返すなら、 int_bits()-1をループカウンターの初期値とすれば 2,1,0という変化で、ループ処理できます。 2ビット分シフトすると、0ビット目が一番右に来ます。そこで 0000------0000001とビットごとの論理積をとって、結果が1か0かを取得します。 1ビット分シフトすると、1ビット目が一番右に来ます。そこで 0000------0000001とビットごとの論理積をとって、結果が1か0かを取得します。 0ビット分シフトすると、2ビット目が一番右に来ます。そこで 0000------0000001とビットごとの論理積をとって、結果が1か0かを取得します。 もう一度聞きますが。 3項演算子の挙動は知ってますか? シフト演算子の挙動は知ってますか? C言語の式の評価値は非ゼロを真と見なすことを 知ってますか? ~0Uなどの補数演算子の~は理解しますか? &がビットごとの論理積であることを理解しており、 その挙動については大丈夫ですか? No5さんぐらいの明確な質問があると回答しやすいのですが・・・。 ###############################################
その他の回答 (7)
- anmochi
- ベストアンサー率65% (1332/2045)
> print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。 では、このforが何回ループするか、その間のiの値は何かを考えてみようか。ここではunsigned intは16ビットとする。 for (i=int_bits() -1; i>=0; i--) すなわち for (i=16 -1; i>=0; i--) すなわち for (i=15; i>=0; i--) iの値は、15から0まで変化する。16回ループする訳だ。次に、ループ内の(x>>i)を考える。 i=15の時(x>>i)はxを15回ビットシフトしたもの、つまり最上位ビットが最下位ビットの位置に来る i=14の時(x>>i)はxを14回ビットシフトしたもの、上から2ビット目が最下位ビットの位置に来る ・・・ i=1の時(x>>i)はxを1回ビットシフトしたもの、下から2ビット目が最下位ビットの位置に来る i=0の時(x>>i)はxを0回ビットシフトした、つまりビットシフトを行わないので、最下位ビットが最下位ビットの位置 以上から、iの値をシフトするビット数として使うので同じint_bits回ループするのでも for (i = 0; i < int_bits(); i++) ではいけないし for (i = int_bits(); i > 0; i--) でもいけないのが分かってもらえるかと思う。この辺が「このおっさん何を言いよるんやろ」となってしまうなら、今までの回答者が言う通りもう少しC言語の基礎を学ぶ方が良いのではないかな。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>int_bits()の関数は、結局、何ビットあるか数えているということですか? unsignedのビット数を数えています。 >print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません あとのシフトする数に使っているからですね。 例えば5ビットのデータで 5ビット右シフトしたらなくなっちゃいますよね 10000 5ビットのデータビットサイズは、5 01000 1ビット右(無符号で)シフト 00100 … 00001 4ビットシフト(ここでビットがあるかどうか調べる)
- nk2
- ベストアンサー率23% (6/26)
putchar(((x>>i) & 1U) ? '1' : '0'); どう考えても、 putchar((x>>i) & 1U); でいいと思うのだが? 間違っている?僕。 unsigned intは通常32bitsです。 int_bits()が32返すとすると、 x = 1111111111111111111111111111101 i = 1 のとき、 x >> i より x = 0111111111111111111111111111110 になります。 1Uは0000000000000000000000000000001 を示していますので、 0111111111111111111111111111110 & 0000000000000000000000000000001 は0ですよね?
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
最上位のビットからビットの位置に合わせて右シフトして1か0を判定して文字'1'か'0'を標準出力に出力する
- lawson
- ベストアンサー率44% (29/65)
####################################### No2さんのsizeofを使わない理由が参考になりました。 どうして、こんな回りくどい方法を・・・ と思ってました。 おもしろい発見をしました。 ####################################### えーっと。本題に入りますが・・・。 なにがわからないのか明確にしたほうがいいですよぉー。 例えば、 3項演算子の挙動は知ってますか? シフト演算子の挙動は知ってますか? C言語の式の評価値は非ゼロを真と見なすことを 知ってますか? ~0Uなどの補数演算子の~は理解しますか? &がビットごとの論理積であることを理解しており、 その挙動については大丈夫ですか? 「--unsigned型のビット内容表示--の所が意味が分かりません」 とありますが。 意味がわからないものが本質的にどれであるかを よく考えて、明確に質問しないと期待通りの 回答を得ることは難しいです。 「意味がわからないものが本質的にどれであるかを よく考えて、明確に質問する」 能力がないのであれば、基礎からやり直したほうが よいでしょう。 以上。
補足
int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?) print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。
- anmochi
- ベストアンサー率65% (1332/2045)
#1です。 先ほど、sizeofを使わない理由を置いておいてしまったが、投稿直後に思い出した事がある。それは、「世の中にはcharが8ビットじゃないマシンもある」という事だ。 とある国のコンピュータで、charが9ビット、short、int、longが全て36ビットというマシンがある。sizeof(unsigned int)×8ではこのマシンには対応できないね。 そういう意味なのかも知れない。
- anmochi
- ベストアンサー率65% (1332/2045)
解説しづらいなぁ。 count_bits()は、「unsigned int型の、(引数で指定された)とある数値で1になっているビットの数」を返す。これは良いかな? int_bits()は、「unsigned int型で0の反転」すなわち「unsigned int型で全て1になっているもの」を引数にcount_bits()を呼び出す。結果として「unsigned int型のbit数」を返すわけだ。 「え? そんな事しなくてもsizeofを使えば良いんじゃないの?」と思うかも知れないが、思うかもしれないが・・・・う~ん、私もそう思う。sizeofはコンパイル時にサイズを「定数として」コードに埋め込むが、上記のint_bitsだってコンパイル時に大きさを決定するしねぇ・・・・。 まぁ、とりあえず置いとこう。 それを踏まえて、 void print_bits(unsigned x) /* 引数で指定された、とある値 */ { int i; for (i=int_bits() -1; i>=0; i--) /* 正確にunsigned intのビット数だけループ */ putchar(((x>>i) & 1U) ? '1' : '0'); /* xの、ループ内の指定ビットが立っているなら1を、立っていなければ0を画面に出力 */ } 後はmain()でこいつを0からUINT_MAXまで繰り返している訳だ。 これで分かってもらえたかどうか不安なので、また質問を投げていただければ・・・・。
補足
int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?) print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。
補足
int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?) print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。