dポイントプレゼントキャンペーン実施中!

どうしても、--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);
}

A 回答 (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さんぐらいの明確な質問があると回答しやすいのですが・・・。
###############################################
    • good
    • 0

> 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言語の基礎を学ぶ方が良いのではないかな。
    • good
    • 0

>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ビットシフト(ここでビットがあるかどうか調べる)
    • good
    • 0

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ですよね?

この回答への補足

int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?)
print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。

補足日時:2005/12/25 11:41
    • good
    • 0

最上位のビットからビットの位置に合わせて右シフトして1か0を判定して文字'1'か'0'を標準出力に出力する

    • good
    • 0

#######################################


No2さんのsizeofを使わない理由が参考になりました。
どうして、こんな回りくどい方法を・・・
と思ってました。
おもしろい発見をしました。
#######################################

えーっと。本題に入りますが・・・。
なにがわからないのか明確にしたほうがいいですよぉー。

例えば、
3項演算子の挙動は知ってますか?
シフト演算子の挙動は知ってますか?
C言語の式の評価値は非ゼロを真と見なすことを
知ってますか?
~0Uなどの補数演算子の~は理解しますか?
&がビットごとの論理積であることを理解しており、
その挙動については大丈夫ですか?


「--unsigned型のビット内容表示--の所が意味が分かりません」
とありますが。

意味がわからないものが本質的にどれであるかを
よく考えて、明確に質問しないと期待通りの
回答を得ることは難しいです。

「意味がわからないものが本質的にどれであるかを
よく考えて、明確に質問する」
能力がないのであれば、基礎からやり直したほうが
よいでしょう。


以上。

この回答への補足

int_bits()の関数は、結局、何ビットあるか数えているということですか?(大きさを調べるということですか?)
print_bitsの関数で、for (i=int_bits() -1; i>=0; i--)のどうしてi=int_bits() -1;で-1するか分かりません。また説明してください。宜しくお願いします。

補足日時:2005/12/25 11:40
    • good
    • 0

 #1です。



 先ほど、sizeofを使わない理由を置いておいてしまったが、投稿直後に思い出した事がある。それは、「世の中にはcharが8ビットじゃないマシンもある」という事だ。

 とある国のコンピュータで、charが9ビット、short、int、longが全て36ビットというマシンがある。sizeof(unsigned int)×8ではこのマシンには対応できないね。

 そういう意味なのかも知れない。
    • good
    • 0

 解説しづらいなぁ。



 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するか分かりません。また説明してください。宜しくお願いします。 

補足日時:2005/12/25 09:53
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!