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型ビット構成の表示されるので、自分の考え方が間違えている。なのですが、どう間違えているかがわかりません。
多少説明文の省略しているためわかりにくいかもしれませんが、間違えを指摘していただけないでしょうか?
No.1ベストアンサー
- 回答日時:
count_bits の処理で, なんで x=10 なの?
関数間の呼出関係を絵で描いてみてごらん.
この回答への補足
図書いて位置から考えなおして見ました。
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までの表示を行っているんでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C言語 3 2022/11/09 13:27
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# このプログラミングの問題を教えて欲しいです。 キーボードから整数kを入力し、kが配列aの中に何個存在 2 2022/12/19 22:50
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
2の補数を計算するプログラム
-
C++で表を作成したいのです ...
-
ヌメロンのプログラム
-
c言語プログラミングについて f...
-
迷路を脱出する経路探索プログ...
-
再起呼び出しの回数をカウント...
-
OpenCVによる4値化について
-
PIC16F88マイコンのC言語プログ...
-
C++ bmp 透過処理
-
C言語の問題
-
カードシャッフルのブログラム...
-
乱数で交互に偶数、奇数が、、、。
-
C言語で%を使わない余りの出し方
-
関数とビット列
-
異なるn個の整数からr個の整数...
-
放射状ブラー C言語で書いたの...
-
画像の拡大・縮小
-
C言語 格子点が多角形の中にあ...
-
16bitで乱数を生成する方法
-
プログラミングに関して
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
おすすめ情報