質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

7945閲覧

ビット演算を用いた10進数~2進数への変換がうまくいきません

masuter0413

総合スコア50

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/05/30 11:19

高校3年生です。c言語を学んでいます。疑問点があったので質問させていただきます。

現在、実現したい仕様は以下の通りです。
コマンドライン引数から整数を受け取り、ビット演算を用いてその値を2進数として標準出力する。
<実行例(完成したとき)>

c

1./test3 2 Usage: program <Length(byte)> <Integer number> 3./test3 1 43 4 00101011 5./test3 2 53018 6 11001111 00011010 7./test3 4 987654321 8 00111010 11011110 01101000 10110001

<補足>
コマンドラインから出力する長さと2進数出力する整数をうけとる。
出力する長さは1~4byteとする。
出力する長さと2進数出力する整数は、sscanfを用いて変数に代入する。
各bitごとの値を格納する配列bitのサイズは出力する長さから計算し、calloc()を用いて動的確保を行う。

<自分実現できていること>
10進数の値を2進数に変換する関数の作成

c

1void cv2bin(unsigned char n){ 2 int i; 3 for(i=DIGITS-1;i>=0;i--){ 4 printf("%d",(n>>i)&1); 5 } 6 printf("\n"); 7} 8int main(int argc,char*argv[]){ 9 10if(argc!=3){ 11printf("Usage: program <Length(byte)> <Integer number>\n"); 12exit(1); 13} 14 15unsigned char n; 16cv2bin(n);//2進数に変換 17 18return 0; 19} 20

<疑問点>
関数cv2binはきちんとビット演算を用いているといえるでしょうか?
コマンドライン引数からの2つの値を'unsigned n'にsscanfを用いて代入するにはどうすればよいでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

関数cv2binはきちんとビット演算を用いているといえるでしょうか?

はい、いえます。ビット右シフト演算>>、ビット積演算&が使われています。

コマンドライン引数からの2つの値を'unsigned n'にsscanfを用いて代入するにはどうすればよいでしょうか?

プログラム起動時のコマンドライン引数は、main関数のパラメータargv配列を介してアクセスできます。またこのとき、コマンドライン引数の個数はargcで確認できますから、必ず2個以上(もしくはきっかり2個)の引数が指定されたかをチェックしてください。エラーチェックを怠ると、誤ったコマンドライン引数指定でクラッシュする不親切なプログラムになってしまいます。

sscanf書式文字列(%+文字のこと)でunsigned char型を扱うには、%hhuを指定します。ただし、この書式指定は「C99」仕様をサポートするCコンパイラでないと使えません。(お使いのコンパイラ次第です)

C

1unsigned char n1, n2; 2sscanf(argv[1], "%hhu", &n1); 3sscanf(argv[2], "%hhu", &n2);

コンパイラの対応状況がわからなければ、unsigned int型と書式文字列%uならばあらゆるC言語コンパイラで動作します。

C

1unsigned int n1, n2; 2sscanf(argv[1], "%u", &n1); 3sscanf(argv[2], "%u", &n2);

投稿2018/05/30 12:26

編集2018/05/30 12:28
yohhoy

総合スコア6189

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

cv2bin()

数値(unsinged char)から、bitになっている様ですが、もう少し、効率よくしても良いのでは?

for(i=DIGITS-1;i>=0;i--){

printf("%d",(n>>i)&1);

}

C

1char bitString[9]: 2for (i = 0; i < DIGITS; i++) { 3 bitString[i] = n >> ((DIGITS - i) & 1) ? '1' : '0'; 4} 5bitString[8] = '\0'; 6printf("%s\n", bitString); 7 8 9```とか。(もっと、簡単な方法あるかも) 10 11> cv2bin(n);//2進数に変換 12 13--> cv2bin((unsinged char)atoi(argv[2])); 14手抜きです。 本当は、数字かとどうか、unsigned char の範囲か確認すべきです。 15あっと、 sscanf()だったら、関数の仕様を確認して、 16```C 17int inputNum; 18sscanf(argv[2], "%d", &inputNum); 19cv2bin((unsinged char)inputNum); 20

こちらにしても、エラーチェックは省いています。

投稿2018/05/30 11:54

編集2018/05/30 12:28
pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

関数cv2binはきちんとビット演算を用いているといえるでしょうか?

これでちゃんとうごくんじゃないでしょうか

コマンドライン引数からの2つの値を'unsigned n'にsscanfを用いて代入するにはどうすればよいでしょうか?

いったん int の変数にいれといて、そこから代入すればいいかと


しかし、各変数をわざわざunsigned char を使うこともないかと思われます
ふつーに int あるいは unsigned int を使ったほうがいいんじゃないかと。
PCでコードを組むぶんには、int は4バイトですぜ

投稿2018/05/30 11:50

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問