C言語の最近のブログ記事
猫でもわかるC言語プログラミング
の第6章 関数 練習問題2より
--初項a,公差bの等差数列の第n項までの和を求める関数を作ってください。
--ただし、ここでは初項も等差も int 型とします。エラーチェックはしなくてもよいです。
===================以下解答===============================
/*tousasuretu.c*/
#include
int suretu(int,int,int);
int main()
{
  int a,b,n,souwa;
  printf("初項 a 公差 b における等差数列の\n");
  printf(" n 項までの和を求め、表示します\n\n");
  printf("初項 a を入力してください --- ");
  scanf("%d",&a);
  printf("\n公差 b を入力してください --- ");
  scanf("%d",&b);
  
  printf("\n第n項までの総和を求めます。nの値を入力してください --- ");
  scanf("%d",&n);
  souwa=suretu(a,b,n);
  printf("総和は%dです",souwa);
  return 0;
}
int suretu(int a,int b,int n)
{
  int souwa=0,i;
  for (i = 1; n >= i; i++){
   souwa += a + (i-1) * b;
   printf("%d\n",souwa);
   }
   return souwa;
  
}
今のところ一番完璧に近い。
しかし動作が完璧だからといって、ちゃんとしたコードが
書けているといったわけではないのが悲しい。
いいソースを読む旅にでも出ようかな・・・。
=============================================================
#include <stdio.h>
int main ()
{
int tensu=0,ninzu =0,goukei=0;
double avr;
  for (;tensu!=-1;){
    printf("%d人目の点数を入力してください\n",ninzu+1);
    printf("-1で終了します==== ");
    scanf("%d",&tensu);
    while(tensu>100 || tensu<-1){
      printf("もう一度点数を入力してください\n");
      printf("数値は0から100までの整数に限ります\n");
      printf("-1で終了します==== ");
      scanf("%d",&tensu);
    }
    
    if(tensu!=-1){
      goukei+=tensu;
      ++ninzu;
    }
    else {}
  }
if(ninzu>0){
  avr=(double)goukei/ninzu;
  printf("%d人の平均点は%4.1f点です\n",ninzu,avr);
}
else{}
printf("終了します\n");
return 0;
}
相変わらず初心者としてプログラムの勉強してみる。
仕様としては
□点数(tensu)の入力を求める。
□-1が入力されたら終了。
□100点超、0点未満( 100 < tensu < 0 )ならもう一度入力を求める。
□最後に合計点を人数で割る。
□平均点を小数点以下1桁で表示する。
==========================================================
#include <stdio.h>
int main (){
int tensu=0;
double avlg;
int gokei=0;
int ninzu=0;
// printf("%d点ですね\n",tensu);
for(tensu=0;tensu!=(-1);++ninzu){
printf("点数を入力して下さい -1 で終了-- ");
scanf("%d",&tensu);
for(;tensu>100||tensu<-1;){
printf("点数をちゃんと入力して下さい -1 で終了-- ");
scanf("%d",&tensu);
}
if(tensu!=(-1)){
gokei += tensu;
}
else if(tensu==(-1)){
printf("以上ですね\n\n");
break;
}
}
if (ninzu!=0) {
avlg=(double)gokei/ninzu;
printf("%d人の平均点は%4.1f点です\n",ninzu,avlg);
// printf("%d,%d,%f\n",tensu,ninzu,avlg);
}else
printf("終了します\n");return 0;
}
==========================================================
これよりもっと簡単にシンプルにできるのでは?と思い試行錯誤を繰り返すも、
ループ地獄にはまりとまどう。forとかwhileとかあまり使いたくなく、
使っても一回だけでやりたいのだが。
プログラミングなんてものをしてみると、アルゴリズムという言葉に出くわす。
アルゴリズムとはある事象にたいしての問題解決手順とでもいったらいいのだろうか?
で、そんなアルゴリズムって言葉を聞くと、思い出すクイズがある。
それは "象を冷蔵庫に収納する。これを3動作でしろ" ってやつ。
これが意地悪いクイズで、問題を初めて聞いたときには
象を入れるってどんだけ大きい冷蔵庫だよ!とか、
バラバラにしていいの?とか、
血は一滴もながしてはならない(ヴェニスの商人)とか頭に浮かんだ。
しかし答えを聞いてみればあっけないもので、
1.冷蔵庫のドアを開ける。
2.象を冷蔵庫に入れる。
3.冷蔵庫のドアを閉める。
というなんだかなあな答えなのだ。
しかしこういう考えが必要なのか、とも思わされた。
一般常識というか既成概念、これが境界条件を作り出してしまう。
本当なら、それは後付けでいいのかもしれない。
これならできるが、これだとできない。
その試行錯誤の上で境界条件は付与されるべきものであり、
いきなり無理と決めつけてしまうのは思考の幅を狭めてしまうだけなのだ。
さてさて、
C言語でのプログラミングをはじめてちょこちょこと本を読んだ。
その中にCプログラミング診断室―さらに美しく健康的なプログラムのためにという本があった。
いろんなコードをどこまで可読的に優れたものにするか、よりカスタマイズしやすいものにしていくか、というのがこのテーマである。
内容はいまの僕には高度なものであった。なんせ出てくる言葉がすべて未知のものなんだから。
しかし、その中でも印象に残った言葉があった。
それは "他人にコードをみてもらえ" ということである。
作者がいうには、恥ずかしがってコードを見せない人(たいていは初心者、中級者)は進歩しない。いろんな人にみてもらって、その人ならどうするかを聞け、ということなのである。
これにならって僕はコードを書いた分とりあえず、アップしておこうと決めた。
もしご意見、ご批判いただけるならばありがたくいただきます。
それにしてもコードをみられるというのは恥ずかしいこと、という気持ちは理解できる。今の僕ぐらいの単純な、些細なコードならばそれほどでもないが、一所懸命に書いたものをさらすのは恥ずかしいし、怖いだろう。
なんだか自分の脳みそをみられているみたいな気持ちになるのではないか、と思う。
それを全否定されて、とても短いエレガントなコードに書き換えられちまった日にゃ、
枕はしとどに濡れまするな。
プログラマー(コードを書いて実際に『お金』をもらう人)というのは僕の周りには一人、二人しかいないし、その二人も僕の想像するようなプログラマーの思考法は持っていないような気がする。本物のプログラマーがどういう思考法をもっているか気になる。
僕の親父はときたま優れたことを発明する。
トイレで大をするときの話なのだが、彼はまず洋式便器の中の、ちょうど便が落ちそうな土手にトイレットペーパーを手の平大にしておいておくそうな。
そうしておくことで、粘着度の高い便がでても便器にこびりつかない、といっていた。
こういう危機回避能力というのは実はプログラマーに向いているのでは、と思ったり思わなかったり。
本日もまた、猫でもわかるC言語プログラミングを参考にして、というかそこにのっている問題をといてみた。
数値の書式?をあわせるのに大変に手間取ってしまた。
"%f" だの "%d" だのたいへんややこしい。しかしこれくらいふつうに扱えないと困ってしまうわけだ。
なんとなくこうしてこうして、という制御だとか分岐には気づくみたい。でもそれを文法にするのに手間なわけです。
今回のはBMI値の測定、というお題でした。ちょっと長すぎるか?とも思います。もしだれかプログラミングに
詳しい方がいたら、一言いただきたいものです。
===================
#include <stdio.h>int main()
{
float cm;
float kg;
float meter;
int bmi;printf("あなたのBMI値を測定します。\n");
printf("身長を cm で入力してください。0で終了---- ");
scanf("%f",&cm);if(cm==0){
printf("終了します\n");
return 0;
}
else if(cm < 0){
printf("きちんと入力してください。\n");
for(;cm<0;){
printf("身長を cm で入力してください。0で終了---- ");
scanf("%f",&cm);
}
if(cm==0){
printf("終了します\n");
return 0;
}
}
printf("体重を kg で入力してください。0で終了---- ");
scanf("%f",&kg);if(kg==0){
printf("終了します\n");
return 0;
}
else if(kg < 0){
printf("きちんと入力してください。\n");
for(;kg<0;){
printf("体重を kg で入力してください。0で終了---- ");
scanf("%f",&kg);
}if(cm==0){
printf("終了します\n");
return 0;
}
}meter = cm/100;
bmi = (kg / ( meter * meter));printf ("あなたのBMI値は%dです\n",bmi);
if(bmi>=25)
printf("肥満に注意しましょう");//printf("%f,%f,%d,%f",cm,kg,bmi,meter);
return 0;
}
===================
最近C言語なるものをはじめている。
なにを今さらだけどいまやらないと、
いつまでもしないからしょうがない。
参考にしているのは猫でもわかるC言語プログラミングという2~3年前の本。
で、本日はこんな感じのソースを書いてみた。
==============================
/*Question.c*/
#include
int main ()
{
int or;
int answer;
printf("これからクイズをはじめます\n");
printf("参加しますか? 1:YES\t0:NO------\t");
printf("1か0を入力してください\n");
scanf("%d",&or);
if (or==1){
printf("参加ありがとうございます\n\n");
}
else if (or==0){
printf("カナシス\(´・ω:;.:... \n");
return 0;
}
else {}
while (or!=1){
printf("参加しますか? 1:YES\t0:NO------\t");
scanf("%d",&or);
if (or==1){
printf("参加ありがとうございます\n\n");
}
else if (or==0){
printf("カナシス\(´・ω:;.:... \n");
return 0;
}
else {}
}
printf("第一問\n");
printf("音楽バンド、RCサクセションの\n");
printf("ボーカルの名前は?\n\n");
printf("1:甲本ヒロト\n");
printf("2:忌野清志郎\n");
printf("3:スガシカオ\n");
printf("4:桂歌丸\n");
printf("解答は?------");
scanf("%d",&answer);
if (answer==2){
printf("正解です\n");
}
else {
printf("不正解です\n");
}
return 0;
}
==================================
という感じである。
疑問点はたくさんある。
まず、変数の宣言後の初期値である。
============================
int or;
int answer;
printf("これからクイズをはじめます\n");
printf("参加しますか? 1:YES\t0:NO------\t");
printf("1か0を入力してください\n");
scanf("%d",&or);
============================
とint型の変数 "or" と "answew" を宣言したのだが、
初期値は当然 0 になると思っていた。
が、実は違うのだった。
============================
int or;
int answer;
//int point=0;
printf("%d",or); /*付け足し*/
printf("%d",answer); /*付け足し*/
printf("これからクイズをはじめます\n");
printf("参加しますか? 1:YES\t0:NO\n");
printf("1か0を入力してください----------");
scanf("%d",&or);
===========================
とすると、最初に表示されるのは、
===========================
1
256
これからクイズをはじめます
参加しますか? 1:YES
0:NO
1か0を入力してください----------
===========================
となった。これがよくわからない。
"or" が1~255までの幅を持ち、
"answer" が256~511 までの幅を持つということなのだろうか?
確認するために "kakunin" を新しく宣言してみることにした。
============================
int or;
int answer;
int kakunin;
//int point=0;
printf("%d",or);
printf("%d",answer);
printf("%d",kakunin);
printf("これからクイズをはじめます\n");
printf("参加しますか? 1:YES\t0:NO\n");
printf("1か0を入力してください----------");
scanf("%d",&or);
===========================
すると表示結果は
===========================
1
256
0
これからクイズをはじめます
参加しますか? 1:YES
0:NO
1か0を入力してください----------
===========================
となり、なんだか一周したみたいだ。
同じように "saikakunin" も定義して、表示してみる。
===========================
1
256
0
1
これからクイズをはじめます
参加しますか? 1:YES
0:NO
1か0を入力してください----------
============================
なるほどまた1が表示された。
そうすると新たな疑問が。
"or" はまだ1なのだろうか?
============================
int or;
int answer;
int kakunin;
int saikakunin;
//int point=0;
printf("%d\n",or);
printf("%d\n",answer);
printf("%d\n",kakunin);
printf("%d\n",saikakunin);
printf("%d\n",or);
=============================
としてみると、
=============================
1
256
0
1
1
=============================
となった。なんだかよくわからないがそういうことなんだろう。
最初にこの現象に気づかずに"or"が"0"だと思いこんでいた。
=============================
if (or==1){
printf("参加ありがとうございます\n\n");
}
else if (or==0){
printf("カナシス\(´・ω:;.:... \n");
return 0;
}
else {}
while (or!=1){
printf("参加しますか? 1:YES\t0:NO------\t");
scanf("%d",&or);
if (or==1){
printf("参加ありがとうございます\n\n");
}
else if (or==0){
printf("カナシス\(´・ω:;.:... \n");
return 0;
}
else {}
=============================
これ、"or" が "0" ならうまい具合にループされると思ったのだが、
いきなり初期値に "1" が入っていたので、
最初の質問がすべてYESの回答で動作してしまっていた。
どうしてそうなるのか未だによくわかってないが、
初期値はちゃんと設定した方がよさそうだ。まあ当たり前か。

