例題

ほないきまっか。先にちゃんと写して実行しといてや。できへんかったらどっかおかしいねん。

#include <stdio.h>
#include <math.h>
#include <ctype.h>

#define PAI 3.141592654
#define RADIUS 5.5

int main(void){
  const double pi = PAI;
  double x,y,z;
  char c;
  x = RADIUS;
  y = x * 2 * pi;
  z = pow(x,2) * pi;

  printf("半径:%f\n",x);
  printf("円周:%f\n",y);
  printf("面積:%f\n",z);

  do{
    printf("何か(半角英数)一文字入力。\n数字で終わりまっせ。\n");
    scanf("%c",&c);
  }while(!(isdigit(c)));

  return (0);
}

実行できましたやろか?ん、予想と違った?大丈夫、説明に入りまっせ。

#define?

defineってなんやの?これはな、includeと同じプリプロセッサ命令や。#で始まってはるやろ?マクロ定義っちゅうてプログラム中のPAIを全部3.141592654に変えてしまうんや。半角スペースで区切るからスペースは入れられへん。あと、これでいうたらPAIの部分を「大文字」で書く習慣があるさかい守ったってえ。みんなで気を付けよな。

「便利そうやけどなんに使ったらええねん!」って?後から変えるかも知れへんとこをdefineで定義しておけば一箇所変えるだけで簡単や。有意義につこてや。

今回はPAIをわざわざpiに入れてもうたけど、piの宣言なくしてpiを全部PAIに換えてみると意味がちょっとわかってもらえるやろか?そう、今回はわざわざpiを作らなあかんかったんや。実はなんかへんなことに気付いてはるやろ?

const double pi = PAI;?

な、constが使いたかったんや。ほやでわざわざpi作ったん。これはな、宣言した時から決もうてしまうってことや。piになんか入れよ思うてももう無理や。なんぞ代入しようもんならコンパイラにえらい怒られまんねん。

これは換えへんぞっ!ていう時にconst使うとこの先安心やな。

doubleを忘れた?まぁ、しゃあないな、これは実数や。小数点が入ってもええで。intよりりっぱやけどええ加減なとこがあるねん。四捨五入とかしようと思うと壁にぶち当たりますのや。あと、条件判断(そのうちやりまっせ)でdouble型を参照するとえらいめにおうてまうから頭の片隅に入れといてや。

今回はちゃんとcをcharにしてますやろ?intでエラー出るかもしれんからな。でもisdigit()の引数は本とはintやねん・・・。この辺の問題はまだうやむやにしといてんか?

pow(x,2)、isdigit(c)?

これらは簡単や、リファレンスを参考にしてもらえんやろか?

do{}while(!(isdigit(c)));?

while()の()内がゼロで無ければ{}内を繰り返すってことや。これを例にあげたサイトはそうはないやろ。でもな、便利なんや。普通のwhileやと

  printf("何か(半角英数)一文字入力。\n数字で終わります。\n");
  scanf("%c",&c);
  while(!(isdigit(c))){
    printf("何か(半角英数)一文字入力。\n数字で終わります。\n");
    scanf("%c",&c);
  }

と同じモンを二回書かなあかん。ちょっとひねくれて

  while(1){
    printf("何か(半角英数)一文字入力。\n数字で終わります。\n");
    scanf("%c",&c);
    if(isdigit(c))break;
  }

でもええ。ただ、一番スマートなのはどぅでっしゃろ?やっぱドゥでっしゃろ?最初の一回がミソなんや。そう、do{}while();はとりあえず{}内を一度実行してから()内を評価すんのや。うまいこと使いわけてな。ちなみに、if(){}は()内がゼロ以外なら{}内を実行せぇって命令。「あ、{}がない」だって?一行ならいりまへんのや。

「forでもええやないかっ!」って?ふぉ、forを知っとるのはすごい!でもな、ええけどこの場合は何回繰り返すかわからへん。おとなしくwhile使っとき。ちなみにkimiが書くなら

  for(c='a';!(isdigit(c));){
    printf("何か(半角英数)一文字入力。\n数字で終わります。\n");
    scanf("%c",&c);
  }

やな。え、意外とスマートだ?でもわかりにくいよな。見た目は良おても、forは回数指定ととらえられるから一瞬kimiは回数を探してしまう。頼むでまどわさんといてぇな。

for(a=1;a<10;a++){}構文解説。最初だけa=1を実行。ほんで、「{}内、a++、a<10の評価」を繰り返す。a<10が成り立たへんくなったらそこで即終わり。

あとな、大事なこと言わなあかんねん。do{}while();は;がいるんや、気つけてぇな。ほなLesson3終わるか。・・・ん、納得いかん事がある?じゃぁもう一項目いっとくか!

実行するとなんやおかしいで?

じゃ、ちょっと実行してみよか・・・

半径:5.500000
円周:34.557519
面積:95.033178
何か(半角英数)一文字入力。
数字で終わります。
p
何か(半角英数)一文字入力。
数字で終わります。
何か(半角英数)一文字入力。
数字で終わります。
6

なんやこれっ!二回でとるやないかっ!!おれは確かに一文字しか入れとらんっ!!!

それはどうかな?なら

  do{
    printf("何か(半角英数)一文字入力。\n数字で終わりまっせ。\n");
    scanf("%c",&c);
    if(c == '\n')printf("変ってわいのことか?\n");
  }while(!(isdigit(c)));

と代えてもう一回してぇな。ちなみにif文の(c == '¥n')は(cが¥nって文字なら)ってこと。(c == '8')だと(cが8って文字なら)ってこと。''は一文字を文字として扱う時に使いまんねん。(c == 8)とは意味が違うから間違えたらあかん。==は比較する演算子で同じって意味、!=なら違うって意味やねん。

話が少しずれたけどどうなりはった?¥nなんて文字入れてへんのに泥沼にはいりこんでしもたか?

君は確かに入れてはりまんのやっ!Enter押しておまっしゃろ?それが改行文字っていって¥nなんや。そう、プログラムは改行も文字として扱うってことが言いたかったんや、かんにんしてぇな。

abcと入力したら4回繰り返しますやろ?scanfは入力した文字を毎回一個ずつ取り出してちゃんと仕事してまんのや。見かけ上解決する方法は

  do{
    if(c != '\n')printf("一文字入力。\n数字で終わりまっせ。\n");
    scanf("%c",&c);
  }while(!(isdigit(c)));

これで上手くいくと思うんや、試してみてな。他にも

  do{
    printf("一文字入力。\n数字で終わりまっせ。\n");
    scanf("%1s",&c);
  }while(!(isdigit(c)));

って方法もあるんや。これは文字列として1文字読み込むってことなん。文字列の終わりは¥0に変えられるから大丈夫なんや。「え、¥nが一文字なら¥0も一文字やあらへんのか?」って・・・scanf()となんぞや?入力した文字を読み込むんや。¥0は入力してないでっしゃろ?ま、良くわからんことはやめといたほうがええよ。そのうちわかるようになるでっしゃろ。

 

ほなLesson3を終わりましょか。ん、何最後に一つだけ質問?なんで関西弁なのかって?・・・なんとなくさ。