サンプルプログラムの解釈についてアドバイス欲しいです(初心者です)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ちびちび

サンプルプログラムの解釈についてアドバイス欲しいです(初心者です)

#1

投稿記事 by ちびちび » 14年前

入力文字を’文字’型0~9として受け取り、数値0~9に変換するプログラムです。
サンプルプログラムに自分でコメント付けました。全然合ってないと思うのですが
どれ位理解出来ているのか、どなたか見て頂けないでしょうか?
よろしくおねがいします><

コード:

#include <stdio.h>
int get_line(char line[]);            // getcharから入力した文字列を格納する関数
int char_to_int(char c);	        // 文字型を数値型に変換する関数

int n=0;                // グローバル変数
int main()
{
  char line[80];			// 入力文字列を格納する配列の宣言
  printf("文字を1つ入力してください(エンター入力で受け取ります\n");
  get_line(line);			// char型line配列の先頭アドレスを渡し、get_line呼び出し。毎回1がreturn?
  n = char_to_int(line[0]);		// Line[0]の実体(1)を渡してchar_to_int呼び出しnに代入。int型になったcがnに格納される

  printf("数値では[%d]\n",n);	// 変換結果n(int型)の出力
  return 0;
}

int get_line(char line[])		// getcharから入力した文字列を格納する関数
{
  int c, i = 0;			// get_line内のみ有効なローカル変数 ※iは0と1にしか変化しない?

  while (((c = getchar()) != '\n') && (i < 79)) 	// getchar入力においてエンターが押されるまでの間かつ、iが79より小さい間?
  line[i++] = c; 			// Line[i]に入力値cが代入される(この行が終わったらiが++変化)
  line[i] = '\0';			// i=1になり、Line[1]に\0が代入される

  return i;		            // iを返す。メインでは帰ってきたint型の1を受け取る所が無い&しかも関数処理が終了すると
  			           // iは初期化されるから、iはいつも0,1にしかならない?
}

int char_to_int(char c)	           // 間数内ローカル変数
{
  return c - '0';		          // cから¥0をとり、cを返す=get_lineによって文字列となったcから\0を取る=int型にして、返すということ
}


box
記事: 2002
登録日時: 14年前

Re: サンプルプログラムの解釈についてアドバイス欲しいです(初心者です)

#2

投稿記事 by box » 14年前

誰が書いたのかはわかりませんが、そのサンプルプログラムそのものに
いろいろと突っ込みたい箇所があることはさておき…。

コード:

int n=0;                // グローバル変数
こういう、当たり前のコメントはちょっといただけないです。
nがグローバル変数なのは見りゃわかるわけでありまして、
「何をするための」変数であるかを書いておくのが適切なコメントというものでありましょう。

【参考】いただけないコメントの例

コード:

    i++;    // iに1を足す(見りゃわかるって)
    for (i = 0; i < 10; i++) {    // 10回繰り返す(だから、見りゃわかるって)
    return n;    // nを呼び出し元に返す(だ~か~ら~、見りゃわかるって)

コード:

  get_line(line);			// char型line配列の先頭アドレスを渡し、get_line呼び出し。毎回1がreturn?
毎回1が返ってくる、なんてことはないです。
get_line()の戻り値を何かの変数に格納して、値を確かめてみてください。

コード:

  n = char_to_int(line[0]);		// Line[0]の実体(1)を渡してchar_to_int呼び出しnに代入。int型になったcがnに格納される
line[0]の実体(1)、というのは意味がわかりません。

コード:

  int c, i = 0;			// get_line内のみ有効なローカル変数 ※iは0と1にしか変化しない?
先に書きましたとおり、iが0と1にしかならない、というのは誤りです。なぜなら、

コード:

  while (((c = getchar()) != '\n') && (i < 79)) 	// getchar入力においてエンターが押されるまでの間かつ、iが79より小さい間?
ここで、ご自分で理由を書かれているではないですか。iが79より小さい間、って。
78までの値を持つ可能性があるってことですよね?

コード:

  line[i] = '\0';			// i=1になり、Line[1]に\0が代入される
この文は、while文によるループの外である、ということは理解されてますか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

ちびちび

Re: サンプルプログラムの解釈についてアドバイス欲しいです(初心者です)

#3

投稿記事 by ちびちび » 14年前

ご指摘頂きどうもありがとうございます!
恐縮なのですが、正しい意味(各処理の説明)を教えていただけないでしょうか?;

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: サンプルプログラムの解釈についてアドバイス欲しいです(初心者です)

#4

投稿記事 by bitter_fox » 14年前

ちびちび さんが書きました:ご指摘頂きどうもありがとうございます!
恐縮なのですが、正しい意味(各処理の説明)を教えていただけないでしょうか?;
この様な感じでしょうか。(ソースコードを全面的に書き換えたいところではありますが・・・)

コード:


#include <stdio.h>

int get_line(char line[]);            //  一行分の入力を受け取る
int char_to_int(char c);              // 文字('0'~'9')を数値に変換する関数 // 修正

int n=0;

int main()
{
	char line[80];

	printf("文字を1つ入力してください(エンター入力で受け取ります\n");
	get_line(line);               // lineに一行分の入力を受け取る
	n = char_to_int(line[0]);     // line[0]を整数値に変換

	printf("数値では[%d]\n",n);   // 変換結果n(int型)の出力

	return 0;
}

//
// 一行分の入力を受け取る
// 引数 : char line[] => 一行分の入力を受け取るバッファ(80以上の要素を持たなくてはいけない) // 修正:[]の位置
// 戻り値 : int => 読み込んだ文字数
////////////////////////////////////////////////////////////////////////////////
int get_line(char line[])
{
	int c, i = 0;                 // cは文字バッファ、iはカウンタ(=入力を受けた文字数)

	while (((c = getchar()) != '\n') && (i < 79))     // 入力を受け、それがエンターか読み込んだ文字数が79より小さい間
	{
		line[i++] = c;            // line[i]にc(=入力された文字)を移して文字数を1増やす
	}
	line[i] = '\0';               // 読み込んだ文字列の末尾に'\0'を付与

	return i;                     // 読み込んだ文字数(=i)を返す
}

//
// 文字型('0'~'9')を整数値に変換(エラーチェックは行わない)
// 引数 : char c => 変換される文字
// 戻り値 : int => 変換後の数値
////////////////////////////////////////////////////////////////////////////////
int char_to_int(char c)
{
	return c - '0';                 // 文字コード上で'0'~'9'が一列に並んでいるのは規格で保証されているので'0'を引くことによって差分(=0~9)を求める // 修正 : 保障
                                    // http://www.kijineko.co.jp/tech/superstitions/A-to-Z-is-sequence.html
}

line[i++] = cのインデント位置が誤解の招く位置にあったので{}で囲み強調しました。
どの文が制御構文の影響を受けるのかをしっかり確認してください。
line[i++] = cがwhileの影響を受けることが理解できたらiの取りうる値も自ずと分かるはずです。

それから、c - '0'も良く出てくるテクニックなのでしっかりと理解してください。
http://homepage3.nifty.com/mmgames/c_gu ... 01.html#S4
http://www.kijineko.co.jp/tech/supersti ... uence.html

あと、'0'と'\0'の区別もしっかりしましょう。
http://www.ne.jp/asahi/hishidama/home/t ... 7%E5%88%97
http://www.c-tipsref.com/words/null_character.html

[hr][補足]
c - '0'については次のような関係が成り立ちます(ASCII文字コードの場合)

コード:

 ------------------------------------------- 
| c |'0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|
|   | 48| 49| 50| 51| 52| 53| 54| 55| 56| 57|
 ------------------------------------------- 

 ------------------------- 
| ASCII文字コードに基づく |
 ----------------------------------- 
| c - '0' | '0' - '0' | 48 - 48 | 0 |
|         | '1' - '0' | 49 - 48 | 1 |
|         | '2' - '0' | 50 - 48 | 2 |
|         | '3' - '0' | 51 - 48 | 3 |
|         | '4' - '0' | 52 - 48 | 4 |
|         | '5' - '0' | 53 - 48 | 5 |
|         | '6' - '0' | 54 - 48 | 6 |
|         | '7' - '0' | 55 - 48 | 7 |
|         | '8' - '0' | 56 - 48 | 8 |
|         | '9' - '0' | 57 - 48 | 9 |
 ----------------------------------- 
[修正]コメントを修正

閉鎖

“C言語何でも質問掲示板” へ戻る