こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

unsigned型のビット構成を表示するプログラムが理解できません。

unsigned型ビット構成の表示プログラム

#include<stdio.h>

int count_bits(unsigned x)
{
int count=0;
while(x){
if(x&1U)count++;
x>>=1;
}
return(count);
}

int int_bits(void)
{
return(count_bits(~0U));
}

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 nx;

printf("非負の整数を入植してください。:");
scanf("%u",&nx);

print_bits(nx);
putchar('\n');

return(0);
}

このプログラムで10を入力したら、00000000000000000000000000000001010と表示され。
18だと00000000000000000000000000000010010と表示される原理が理解できません。

自分なりにプログラムを追ってこういう考えてます。

まず、10を入力したらcount_bitsの関数の処理からスタート。

while(x){
if(x&1U)count++;
x>>=1;

if(x&1U)の処理を行い。x=10はbit単位表示で、1010として考え。一番右側の101「0」とunsigned型の1との論理比較を行う。0と1なので偽で何もせずにif文を抜けて、x>>=1;を行いx=0101となり。while(x)から再びif(x&1U)行う。x=0101の一番右側のunsigned型の1との論理比較を行い0と1なので真なのでcount++を行いcount=1としてif文を抜け、x>>=1;を行いX=0010になり。三度目のif(x&1U)の処理を行う。0010の一番左側のunsigned型の1との論理比較を行い0と1なので偽でif文を終了。x>>=1;を行い0001となり、再びif(x&1U)行う。
00
01の一番左側のunsigned型の1との論理比較を行い0と1なので真なのでcount++を行いcount=2となり、x>>=1;を行い0000なのでwhile(x)を抜けて返り値2をint_bitsへ返して関数は終了

int_bitsではunsinged型の2が戻り値としてprint_bitsへ返し、int_bitsの関数は終了。

print_bitsの処理が始まり。for(i=int_bits()-1;i>=0;i--)の処理がスタート。
i=int_bits()-1の処理でiは2-1でi=1からスタート。
putchar(((x>>i)&1U)?'1':'0');の処理。
(x>>i)でx=10,i=1なので1010>>1だから0101。
0101の一番右側の1とunsigned型の1と論理比較を行う
真なのでputcharは'1'を一度表示。
for文に戻りiをデクリメントとしてi=0なのi>=0から
一度、putchar(((x>>i)&1U)?'1':'0');処理。
(x>>i)は0101>>0の0右シフト行い0101。
unsignedと1を0101の一番右側の1と論理比較を行う
真なのでputcharは'1'を一度表示。
for文に戻りiをデクリメントとしてi=-1なのでi>=0からfor文を終了してprint_bitsの処理を終了。mainの関数処理に戻り。putchar('\n');を出力して関数処理は終了。表示として「11」が表示される。18も同様に考えているので、「11」が表示されてしまうのでは?という考えに陥ってます。実際は、両方とも正しくunsigned型ビット構成の表示されるので、自分の考え方が間違えている。なのですが、どう間違えているかがわかりません。
多少説明文の省略しているためわかりにくいかもしれませんが、間違えを指摘していただけないでしょうか?

投稿日時 - 2009-01-18 19:23:52

QNo.4640850

困ってます

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

count_bits の処理で, なんで x=10 なの?
関数間の呼出関係を絵で描いてみてごらん.

投稿日時 - 2009-01-18 19:58:26

補足

図書いて位置から考えなおして見ました。
count_bits(unsigned x)に受け渡されているのはcount_bits(~0U)から~0Uで

int count_bits(unsigned x)
{
int count=0;
while(x){
if(x&1U)count++;
x>>=1;
}
return(count);
}

ここの処理は

int count=0;
while(~0U){
if(~0U&1U)count++;
x>>=1;
}

私の処理系ではcount=32となって、int int_bits(void)で、32をint_bits()に返す。
右シフトを31から0までの表示を行っているんでしょうか?

投稿日時 - 2009-01-18 20:49:25

ANo.1

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

そうです.
int_bits() で int のビット数を調べて, そのあとで上位から順に各ビットが 0 か 1 かを表示しているだけです.

投稿日時 - 2009-01-19 02:14:14

あなたにオススメの質問