C言語で2進数を10進数に変換するプログラムの解説

このQ&Aのポイント
  • C言語で2進数を10進数に変換するプログラムの解説をします。
  • C言語のプログラムにおいて、val = binary[pos] - '0';という部分について説明します。
  • この行は2進数の桁の値を取得するための操作です。2進数の各桁の値は文字列で表されており、'0'を引くことで対応する数値を得ることができます。
回答を見る
  • ベストアンサー

解説お願いします

C言語の本を読んでいたのですが、わからないことがありました。 //2進数を10進数に変換するプログラム #include <stdio.h> #include <string.h> int main() { char binary[32]; /* 2進数 */ int weight; /* 2進数の桁の重み */ int pos; /* binary[]の桁の位置 */ int val; /* binary[]の桁の位置の値 */ int sum; /* 集計された値(変換後の10進数) */ /* キーボードから2進数を入力する */ printf("変換前の2進数 = "); gets(binary); /* 2進数を10進数に変換する */ sum = 0; weight = 1; for (pos = strlen(binary) - 1; pos >= 0; pos--) { val = binary[pos] - '0'; printf("桁の重み%d × 桁の数値%d = %d\n", weight, val, weight * val); sum += weight * val; weight *= 2; } /* 変換後の10進数を画面に表示する */ printf("変換後の10進数 = %d\n", sum); return 0; } このプログラムにおいて、val = binary[pos] - '0';という部分がよくわかりません。 -'0'って書き方がよくわかんないです。 この行は一体なにをしているんでしょうか・・ 解説お願いします。

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

  • ベストアンサー
回答No.2

こう言う場合は、一旦、問題になってる場所をコメントアウトしてみれば良いです。 ちなみに、今問題になってるのは「0って何だ?」って事なんでそこに注目してみます。 元のプログラムを実行して0を入力すると、例えばこう言う結果が返ってきますね。 /* ここから結果 */ 変換前の2進数 = 0 桁の重み1 × 桁の数値0 = 0 変換後の10進数 = 0 /* ここまで */ 2進数の0は10進数の0ですね。当たり前なんでこれは正しい結果です。 さて、じゃあ問題の箇所を次のようにコメントアウトしてみましょう。 /* こう言う風にコメントアウトしてみる */ val = binary[pos]; /* - '0'; */ /* セミコロンを付け忘れないように! */ こうするとbinary[pos]ってのが剥き出しでvalに代入されますね。 これでさっきやったようにコンパイルして実行、そして0を入力してみます。 そうするとどうなるでしょうか。 /* ここから結果 */ 変換前の2進数 = 0 桁の重み1 × 桁の数値48 = 48 変換後の10進数 = 48 /* ここまで */ コナン君なら 「あれれれぇ、おかしいな、0を入力したのに48が返ってきたよ?」 とか言うでしょうね(笑)。 さて、一体何が起こってるのでしょうか。 まず、このプログラムで特徴的なのは入力でgets関数を使ってる辺りですね。 ・C言語関数辞典(gets) http://www.c-tipsref.com/reference/stdio/gets.html んで解説読んで欲しいんですが、実際はC言語には(他の言語で言う)「文字列」って物は厳密には無いんですが、次のように書いてあります。 "gets 関数は標準入力 (standard input) から 1 行分※ 文字列を読み取り,s が指す配列に格納します." つまり、このプログラムで「入力」してるのは、上のサイトの説明を借りると、「数値」を入力してるんじゃなくって「文字列」を入力してるわけです。 コードのこの部分ですよね。 gets(binary); もう一度言いますが、仮にここで「0」と入力しても、要するに「整数型」の0が入力されるわけじゃなくって「文字としての」0が入力されてる、って事です。ここまで良いでしょうか? 問題は、文字としての0と数値としての0が一致してれば良いんですが、さにあらず、文字の基本にASCIIコード表なるものがあって、実は「文字の数値」と、メモリに置かれる実際の数値は次のような対応になってるんです。 ・ASCIIコード表 http://e-words.jp/p/r-ascii.html 文字の0 -> 数値の48 文字の1 -> 数値の49 文字の2 -> 数値の50 文字の3 -> 数値の51 文字の4 -> 数値の52 文字の5 -> 数値の53 文字の6 -> 数値の54 文字の7 -> 数値の55 文字の8 -> 数値の56 文字の9 -> 数値の57 お分かりでしょうか?48って数値はさっき出てきましたね。 つまり、コンピュータでは極論、最期は全部数値になるんですが、「文字」と「文字としての数字(整数)」にはズレがある…要するに「48ズレがある」って事なんです。 従って、単純には、C言語上で「文字の数値」を単なる数値に変換するには48引けば良いわけですね。例えばこのプログラム上では次のように書ける。 /* 文字数値から整数への変換 */ val = binary[pos] - 48; そしてもっと端的にはASCIIでは文字'0'は48と定義されてるので、「次の数式も」意味的には上の数式と同値になるわけです。 /* もっとカッコイイ書き方? */ val = binary[pos] - '0'; まとめます。 gets関数は入力を文字として捉える入力関数で、そのままではASCIIコードに従った数値としてメモリへ格納されます。計算/出力する際に、その「文字としての」数値を単純な一桁の整数に変換しないといけません。 ASCIIコードに従う限り、一桁の数値は全て48、ないしは文字'0'を引くと単純な一桁の整数と一致し、これはよく使われる「文字数値 -> 数値」の変換となっています。

saiumalsei
質問者

お礼

詳しい解説ありがとうございます 文字コードが関係していたのでしたか 勉強になりました

その他の回答 (1)

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.1

>このプログラムにおいて、val = binary[pos] - '0';という部分がよくわかりません。 文字コードに依存する話なのでASCIIの文字コード表など参照して欲しいのですがASCII文字コードだと 文字 文字コード '0' 0x30 '1' 0x31 '2' 0x32 '3' 0x33 ... '9' 0x39 binary[pos]の値が'0'だと '0' - '0' → 0x30 - 0x30 → 0 binary[pos]の値が'1'だと '1' - '0' → 0x31 - 0x30 → 1 というように数字の文字を数値に変換できます。

関連するQ&A

  • この数列プログラムの解説お願いします c言語です

    初項が2です。 #include<stdio.h> int main(void){ int a, n, k, sum = 0; printf("Type k\n"); scanf("%d",&k); a = 2; for(n = 2; n <= k+1; n++){ sum += a; printf("a = %d, sum = %d\n",a, sum); a += (n-1)*(n-1); } return 0; } for文の()内の意味とかよくわかんないです

  • ループ

    #include<stdio.h> int main(void) { int i=1,sum=0; int num=1; while(num>0) { printf("整数を入力してください。(マイナスの値で終了)\n"); scanf("%d",&num); printf("%dが入力されました。(%d番目の繰り返しです)\n",num,i); sum+=i; printf("1から%dまでをたすと%dです。\n",i,sum); i++; } printf("繰り返しが終わりました。\n"); printf("加算値は%dです。\n",sum); printf("%d回繰り返しました。\n",i); return 0; } このプログラムで101以上の数値は加算しないようにするにはどうすればいいですか。

  • C言語の配列について

    配列を20 定義し値を入力して合計値を出したいのですがどうすればよいのでしょうか 下のソースでエラーはおこりませんでした 何がちがうのでしょうか #include <stdio.h> int main() { int a[20]={}; int i, sum; printf("整数を入力してください:"); scanf("%d",&a); printf("\n"); for (i = 0; i < 10; i++) { sum += a[i]; } printf("sum= %d\n", sum); return 0; }

  • 解説お願いします。

    0から9までの数字を入力しあたりかはずれかを表示するプログラム。 #include<stdio.h> #include<time.h> #include<stdlib.h> int main(void){ int r,a; printf("0から9までの数字を入力してください。\n"); scanf("%d",&a); srandom(time(NULL)); r = random()%10; printf("%d \n",r); if(a==r){ printf("アタリ\n");} else{ printf("ハズレ\n");} return 0; } 例えば%10は何のためにあるのかとか・・

  • コマンドライン引数を使って2進数を10進数に変換させたい

    2進数を入力し10進数に変換するプログラムを作成したのですが、うまく動作しないので質問させてください。 コマンドライン引数を使って実行したいのですが2進数も入力出来ず困っています。作成したコードの何処に問題があるのかも解らずにいます。 宜しくお願いします。 作成環境は「Windows XP」「Visual Studio .net 2003」 <作成したコードです> *********************************************************** // binary.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 #include "stdafx.h" #include <stdlib.h> int _tmain(int argc, _TCHAR* argv[]) { if( argc < 8 ){ printf("2進数を入力してください。\n"); exit(1); } //空白文字のチェック// int i=0,n=0; char decimal[ 128 ], binary[ 128 ]; for( i=0; i<argc; i++ ){ if( binary[ i ] != ' ' ){ decimal[ n ] = binary[ i ]; n++; } } //'\0'を代入(文字列の終端)// decimal[ n ]='\0'; //「0」と「1」のループ// for( i=0; i<argc; i++ ){ if(( decimal[ n ] == '0' ) || ( decimal[ n ] == '1' )){ }else{ printf("エラー\n 「0」と「1」以外の文字が入力されております\n"); } } //桁数のループ// int m = 0; for( i=0; i<'\0'; i++ ){ m = m +1 ; } //桁数の判断/// if( m == 8 ){ }else{ printf("エラー\n2進数(0,1)を8桁、入力して下さい。\n"); } //add・初期化// int add = 0; //decimal[0]~decimal[7]の判断// if( decimal[ 0 ] == '1' ){ add += 128; } if( decimal[ 1 ] == '1' ){ add += 64; } if( decimal[ 2 ] == '1' ){ add += 32; } if( decimal[ 3 ] == '1' ){ add += 16; } if( decimal[ 4 ] == '1' ){ add += 8; } if( decimal[ 5 ] == '1' ){ add += 4; } if( decimal[ 6 ] == '1' ){ add += 2; } if( decimal[ 7 ] == '1' ){ add += 1; } //2進数を10進数に変換した値の出力// printf("2進数を10進数に変換した値は %d \n",add); return 0; }

  • for文を別のint内で定義し、初めのint文内で呼び出す??? 何という名のプログラム名?ですか???

    毎度毎度忙しい中失礼します。現在<私のプログラム>を基に<参照プログラム>のようにプログラムを作り変えようとしていますが、正直お手上げ状態です。 どうしても<参照プログラム>に基づいてプログラムを組まなければならないのです。 どこがお手上げ状態かといえば、<参照プログラム>を参考にすると、int multInts(int x, int y)内の条件の組み方が<私のプログラム>内でどのようにして組めばいいのかが全くもって分かりません。かなり考えても分からないレベルです・・・私にとっては。 int multInts(int x, int y)の定義の仕方を真似て<私のプログラム>でも真似てみるのですが・・・出来ないのです。何をどう直せば良いのでしょうか???初期化でtra=0;とすると、表示は"0"になったりするし・・・。簡単かと思われるかもしれませんが・・・私にとってはかなり難しいのです。 ”丸投げ”みたいな感じで恥ずかしいのですが、どうかアドバイスだけでも下さい。お願いします。 出力結果 1.5桁数字入力:"12345"と入力 (これは出来ます) 2.偶数桁のみ抽出して2倍にする→"14385" (最不明部: <参照プログラム>内のmultInts内の条件を<私のプログラム>内でどのようにして組むのかが分かりません) 3.各桁の数値を足し合わせる→1+4+3+8+5=21(不明部: 2.が出来ないので出来ません) 4.その数値が”妥当”か”不当”かをDOS?画面に表示(不明部:2.と3.が出来ないので出来ません) <私のプログラム> #include <stdio.h> #include <stdlib.h> #include <math.h> int main() { int num,tra; int inpt=5; int inptnum; int sum=0; //#define 0 printf("5桁入力; "); scanf("%d", &num); if (num==0){ printf("その値は0です。 \n"); } else{ for(inpt ; inpt >=1 ; inpt--) { if(inpt%2 == 0) { inptnum = pow(10,inpt-1); tra = (num/inptnum)%10; //printf("%d",tra*2); tra=(tra*2)/10+(tra*2)%10; printf("%d",tra); } else{ inptnum = pow(10,inpt-1); tra = (num/inptnum)%10; printf("%d",tra); } sum += tra; } printf("\n %d\n",sum); sum= sum%10; if(sum==0) { printf("妥当な数値です。\n"); } else { printf("不当な数値です。\n"); } } system("pause"); return 0; } <参照プログラム> #include <stdio.h> #include <stdlib.h> int main(){ int multInts(int x, int y); int num1,num2,answer; printf("間にスペース設けて2つの値入力: "); scanf("%d%d", &num1, &num2); answer = multInts( num1, num2); printf("%d * %d=%d\n", num1, num2, answer); system("pause"); return 0; } int multInts(int x, int y) { int result = 0; int i; for (i=1 ;i<=y ;i++) { result=result + x; } return result; }

  • 下記のプログラムを実行したところ、不正な処理をしたので強制終了しましたとでました。何故でしょうか?

    #include <stdio.h> #include <stdlib.h> #include <float.h> int main( void ) { int val; int sum = 0; int max = -DBL_MAX; int cnt; char FileName[FILENAME_MAX]; FILE *fp; printf("入力ファイル名>>>"); scanf("%s", FileName ); if( (fp = fopen( FileName, "r" )) == NULL ) { printf("ファイルが見つかりません------%s\n",FileName ); exit( EXIT_FAILURE ); } for(cnt=0; ;cnt++) { fscanf(fp,"%d",&val); /*合計を求める*/ if(val == 0) { break; } sum += val; /*最大値を求める*/ if( max < val) { max = val; } } if( cnt > 0) { printf("平均は%g,最大値は%dです\n",(double)sum / cnt, max); } fclose( fp ); return EXIT_SUCCESS; } コンパイルはできるのですが実行すると このプログラムは不正な処理をしたので強制終了しますとでました 入力ファイル名>>>ってのも表示されません やはりこれは僕のパソコンがおかしいのでしょうか? 何か原因があるのなら教えてください

  • 各桁の和を返す関数

    一つの正整数を引数として受け取り、 その整数の各桁の和を返す関数を作成する。 この関数を用い、いくつかの正整数を入力して その整数の各桁の和を表示する。 入力の終わりは、0または負のデータが現れたことで 判定する。 というC言語の問題なんですが、 整数の各桁の和を返す関数がうまくできません・・。 123が15となってしまいます・・。 とりあえず最初の部分を作ってみました。 初心者なのでミス多いかもしれませんが どなたか教えていただけませんか? #include<stdio.h> #include<conio.h> int sum(int n) n=(n/10)+(n%10); return n; } main() { int n,sum2; scanf("%d",&n); sum2=sum(n); printf("%d",sum2); }

  • C言語!プログラム書いたのですがエラーです!

    課題内容 キーボードから数字を入力してその値までの合計を表示する。 さらに入力した値が偶数なら0から入力した値までのすべての偶数の和を 入力した値が奇数なら1から入力した値までのすべての奇数の和を表示するプログラム。 #include<stdio.h> int main(void) { int i, n, sum; sum=0; scanf("%d",&n); printf("入力値:%d\n", n); if(n%2 = 0) { for(i=0;i<=n;i+=2) { sum=sum+i; } printf("合計値:%d\n",sum); } else { for(i=1;i<=n;i+=2) { sum=sum+i; } printf("合計値:%d\n",sum); } return(0); } これでコンパイルすると10行目に左辺値が必要とでます。 どうすればよいでしょうか? 教えてください。よろしくお願いします。

  • 文字列をint型へ変換するには?

    c言語初心者です。 こちらのプログラムだとうまく表示されません何故でしょう? わかる方是非教えていただきたいと思います。 #include<stdio.h> #include <stdlib.h> int main() { int  num ;     char sum1[4]; printf("数字 str1 =>"); scanf("%d",&num); num= atoi(sum11); printf("sum1= [%d]\n",num); } コマンドに数字を入力したあとintに変換してnumに表示させたいのですが、、、、

専門家に質問してみよう