• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:明解C言語 入門編 P219 について)

C言語で数字の出現回数をカウントするプログラムの理解について

このQ&Aのポイント
  • C言語で実装されたプログラムについての質問です。
  • プログラムでは、入力された文字列に含まれる数字の出現回数をカウントする処理が行われています。
  • 関数内で行われている処理の一部が理解できず、具体的な動作や意図について知りたいです。

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

  • ベストアンサー
  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.1

unsigned i = 0; while(str[i]) { // str に '\0' が現れるまで繰り返し if(str[i] >= '0' && str[i] <= '9') cnt[str[i] - '0']++; // !!!! ココです !!!! i++; str[]に"3.14159"が入っていたとき、 str[0] == '3'であるから、if文の条件を満たします。 str[0] - '0'は、'3' - '0'ですから、3という数値です。 たいていの文字コードでは'0', '1, '2', ..., '9'の順に番号が振ってあるはずですから、 '0'を基準としていくつ離れているか('3' - '0'の式の部分)が、その数字に相当します。 cnt[3]++;は、配列の要素cnt[3]の値を1だけ増やします。 これで、"3.14159"の先頭文字である'3'の個数が1個増えたことになります。 i++;によって、次の文字'.'を対象とします。 これは、数字ではありませんので、if文をスルーします。 i++;によって、次の文字'1'を対象とします。 ここの処理は、先ほどの'3'の場合と同じです。cnt[1]を1増やします。 以下同様です。

jussmen_1979
質問者

お礼

丁寧なご回答有難うございました。 おかげさまで理解することが出来ました。

その他の回答 (3)

回答No.4

数字の文字コードは連続していると仮定(念のため) > /* ループ1回目 */ > cnt[0] = str[0] - 0; /* 3 - 0 で cnt[0] には 3 が入る。 */ > cnt[0++]; str[0]は'3'で、str[i]-'0'='3'-'0'=3です。この値がcntの添え字になります。 なので、cnt[3]++;が実行されます。++の位置も違いますね。 > /* ループ2回目 */ > cnt[1] = str[1] - 1; /* "." - 1 となる。 数字ではないので減算できずエラーになるのでは? */ > cnt[1++]; その前のif文で'.'は排除されています。 > /* ループ3回目 */ > cnt[2] = str[2] - 2; /* 1 - 2 なので、なぜか負の数になってしまう。。 */ > cnt[2++]; str[2]-'0'ですよね。なんで-2になってるんですか? '2'-'0'=2なので、cnt[2]++;が実行されます。

jussmen_1979
質問者

お礼

ご回答有難うございました。おかげさまで理解が進みました。 ベストアンサーにすることができず恐縮ですが、皆様の 回答を読むことで理解度が高まり、感謝しております。

noname#208507
noname#208507
回答No.3

文字データは特定の数値で符号化されています. ひとまず,ASCIIコード表と照らし合わせるのが分かりやすいでしょう. 1) - '0' が何を行っているのか  '0'はASCIIコードで48(十六進数で0x30)です.  '3'は同じく51(十六進数で0x33)です.  よって '3'-'0' は 51-48 を意味し,結果は数値の 3 です. 2) ++ はどの値を増加  上の例('3'-'0')なら,'3'の度数(cnt[3])を増やします. /* ループ1回目 */ cnt[3]++; /* '3'-'0' = 51-48 = 3 より */ /* ループ2回目 */ /*  if(str[i] >= '0' && str[i] <= '9') は  if(str[i] >= 48 && str[i] <= 57) であり,  '.' == 46 なので 偽となる */ /* ループ3回目 */ cnt[1]++; /* '1'-'0' = 49-48 = 1 より */ 以下同様.

jussmen_1979
質問者

お礼

ご回答有難うございました。おかげさまで理解が進みました。 ベストアンサーにすることができず恐縮ですが、皆様の 回答を読むことで理解度が高まり、感謝しております。

  • f272
  • ベストアンサー率46% (8526/18249)
回答No.2

if(str[i] >= '0' && str[i] <= '9') cnt[str[i] - '0']++; // !!!! ココです !!!! これを if(str[i] >= '0' && str[i] <= '9'){ printf("%d回目,str[i]=%d,str[i]-'0'=%d,before:cnt[%d]=%d",i,str[i],str[i]-'0',str[i]-'0',cnt[str[i] - '0']); cnt[str[i] - '0']++; // !!!! ココです !!!! printf(",after:cnt[%d]=%d\n",str[i]-'0',cnt[str[i] - '0']); } これに書き直して実行ささせてみなさい。

jussmen_1979
質問者

お礼

ご回答有難うございました。おかげさまで理解が進みました。 ベストアンサーにすることができず恐縮ですが、皆様の 回答を読むことで理解度が高まり、感謝しております。

関連するQ&A

専門家に質問してみよう