標準入力・条件分岐

はじめに

前回は環境導入、Hello-World!、変数等を勉強しました。わからないところがあったら、先輩に聞いたり、自分で資料を読み直したりしてみてください。

演算

さて、変数によって値を保存できることがわかったのはよかったのですが、今のままだと絶対に計算プログラムは作ることが出来ません。なぜなら、計算の方法を知らないからです。当たり前ですね。では実際に計算を行う簡単なプログラムを見てみましょう。

#include <stdio.h>

int main(void){
  int x = 2; // これはint x; x= 2;を一行にまとめたものです。
  int y = 3;
  int ans = x + y;
  printf("x+yは%dです",ans);
  return 0;
}

このプログラムを実行してみてください。「x+yは5です」と表示されたのではないのでしょうか。

int ans = x + y;の部分は、コメントにもあるようにint ans;ans = x + y;をまとめたものです。ここで大切になるのはans = x + y;の部分になります。前回学んだ通り=は左側の変数に右側の値を代入するものです。右側にx+yのようながある場合、左側の変数には式の評価結果が代入されます。少し難しいですが、例を見て理解してください。式の評価は数学の式と同じように行われます。少しだけいつも使う記号とは違いますが。

int x = 0;
int y = 2;
int z = 3;
x + y; // この式はx + yを意味するので、0 + 2で評価結果は2
x + z; // この式はx + zを意味するので、0 + 3で評価結果は3
z * y; // この式はz × yを意味するので、2 × 3で評価結果は6

+*といった演算の内容を指示する記号を演算子といいます。演算子には優先順位というものがあり、優先度の高い演算子から先に処理されていきます。実は=も演算子なのです。=は代入演算子といいます。代入演算子の優先度は+*といった計算に使われる演算子の優先度よりも高く設定されています。そのため、ans = x + y;という式はまずansx+yを代入しよう、という風に解釈されます。その後x+y+の演算が行われ、最終的にx+yの値である5がansに代入されるわけです。

演算子について

演算子について

このあたりは正直難しいので、正確に理解出来なくても構いません。ここの練習問題やサンプルプログラムなどを見て、「こうすればこうなるんだな」というのを感覚で憶えてもらえばそれで問題ないです。

演算子の種類

計算でよく使う演算子をまとめておきます。

その他の演算子等に関してはこちらのサイトがよくまとまっています。もしわからなくなったらプログラミングが詳しそうな先輩に質問してください。

練習問題

  1. 変数を2つ用意し、それぞれ3と2を代入しなさい。3の代入された変数から2の代入された変数を-を用いて引いた結果を他の変数に代入して表示しなさい。
  2. 変数を3つ使い、120と20について、それぞれ足し算の結果、引き算の結果、掛け算の結果、割り算の結果を表示しなさい。

まとめ

今まではずっと整数の計算をしてきました。ですが、少数が必要になる時もありますよね。少数を1扱うことになると、int型では表現出来ません。その場合、別の型を使う必要があります。

float,double

少数を扱う変数を使う場合、その変数の型はfloat型またはdouble型にする必要があります。float型とdouble型の違いは、その変数の表現できる値の大きさの範囲です2

型名 範囲
float \[\pm 10^{-38}~10^{38}\]
double \[\pm 10^{-308}~10^{308}\]
#include <stdio.h>

int main(void){
  float x = 3.5;
  float y = 2.4;
  float ans = x + y;
  printf("x+yは%fです",ans);
  return 0;
}

変数の型とその値が変わったこと以外は特に変化がないように見えます。ただ、%dだった部分が%fに変わっています。これは与えられた値を整数で表示するか、少数で表示するかの違いです。値をどのようなフォーマットで表示したいかによって、この文字列は3変更する必要があります。

#include <stdio.h>

int main(void){
  float x = 3.5;
  float y = 2.4;
  float ans = x + y;
  printf("x+yは%fです\n",ans);
  printf("x+yは%dです",ans);
  return 0;
}

上のプログラムを実行してみてください。一行目は正常に表示されますが、二行目はおかしな値になるのではないのでしょうか4。 このように、そのプログラム上で変数をどのようなフォーマットで表示したいかをちゃんと考える必要があります。フォーマットの表を次に示しておきます5

表示したい変数の種類 フォーマット指定子
整数(int) %d
少数(double,float) %f
文字6 %c
文字列 %s
#include <stdio.h>
// フォーマット指定子を使う例
int main(void){
  int a = 0;
  float b = 0.3;
  printf("a=%d,b=%f",a,b);
}
// => a=0,b=0.3

ちなみに7行目にある\nは改行を意味します。printfの中の文字列にこれを入れると、表示されたときにその\nのある場所で改行されます。

printf("a\n\nb"); 
// a
// 
// b

練習問題

  1. 4.3と2.6を足し合わせて表示するプログラムを作成してください。

まとめ

標準入力

今までのプログラムでは、計算したい値をプログラム中に入力していました。しかし計算機を作ると、数字をあとから指定したいですよね。

プログラムを使う人(ここからはユーザーといいます)に、計算に利用する値を入力してもらいたい場合、標準入力を使います。

scanf関数

ユーザーに数字を入力してもらうプログラムは以下のようになります。

#include <stdio.h>

int main(void){
  int a;
  printf("aの値を入力してください:");
  scanf("%d",&a);
  printf("aは%dです\n",a);
  return 0;
}

実際にこのプログラムを実行してみてください。aの値を入力してください、という文字が表示されて画面が止まります。そこで、好きな数字を半角で入力してください。

たとえば3を入力すると、「aは3です」という表示がされます。4であれば「aは4です」と言った風に、自分の入力した値がaに代入されていることがわかります。

scanf関数は、ユーザーからの入力を受けつけて、入力された値を指定した変数に代入する関数です。

scanf("欲しい変数のフォーマット指定子",&変数名)

下はscanfを使った例です。

int a;
scanf("%d",&a);
float b;
scanf("%f",&b);
double d;
scanf("%lf",&d);

「どうして変数名の前に&をつけるの?」という疑問を持った方がいるでしょう。現状私がここまで教えてきた知識だけでは&7が必要な理由を適切に説明することはできません。ポインタという項目を学習する際に、詳しく解説しますので、ここではとりあえず覚えてください。

練習問題

  1. ユーザーに整数を入力してもらい、その数字の3倍を表示するプログラムを書いてみましょう。
#include <stdio.h>

int main(void){
  int num;
  // ここにユーザーからの入力を受け付ける処理を書く
  // ここにその数字を三倍した値を書くプログラムを書く
  return 0;
}

まとめ

条件分岐

さて、これでユーザーからの数字を受け入れるプログラムを書くことが出来ました。これで計算機に近いことはできそうです。例えば2つの数字を入力してもらい、その足し合わせた結果を求めるプログラムはこんなふうになります。

#include <stdio.h>

int main(void){
  int a,b;
  printf("一つ目の数字を入力して下さい:");
  scanf("%d",&a);
  printf("二つ目の数字を入力して下さい:");
  scanf("%d",&b);
  printf("二つの数字の足し合わせた結果は%dとなります。\n",a+b);
  return 0;
}

上のプログラムは理解出来ているでしょうか?もしよくわからないところがあったら、今までのテキストを読み直したり練習問題をやってみたりしてください。

では、入力された2つの値を引いた結果を求めるプログラムを書くにはどのようにしたらよいでしょうか。上のプログラムを数文字変えるだけですみますね。

#include <stdio.h>

int main(void){
  int a,b;
  printf("一つ目の数字を入力して下さい:");
  scanf("%d",&a);
  printf("二つ目の数字を入力して下さい:");
  scanf("%d",&b);
  printf("aからbを引いた結果は%dとなります。\n",a-b);
  return 0;
}

簡単ですね。さて、ここで「1つのプログラム上で、足し算と引き算どちらもできるようにしたい」と思いませんか?最初に足し算と引き算、どちらを行うかを選べるとより計算機に近づくと思いませんか?

このようにある要素(今回の場合はユーザーの選択)によって処理を分岐するために必要なのが、条件分岐となります。

条件分岐は、プログラムを書く上で本当に大切な要素です。これがないと、プログラムを書くことは出来ません。今までよりすこしだけ難しくなりますが、頑張ってついてきてください。

if文

まずみなさんには、if文というものを学んでもらいます。if文は、与えられた条件によって処理を分岐することが出来ます。

if(条件式) 処理

与えられた条件式の値が真であれば、その後に書かれた処理を実行します。偽であれば実行しません。

ここで、真は0でない数字、偽は0を指します。

これだけ言われてもよくわからないでしょうから、例を見てみましょう。

#include <stdio.h>
int main(void){
  if(1) printf("1は真なのでこれは表示される\n");
  if(-1) printf("-1も真なので、コレも表示される\n");
  if(0) printf("0は偽なので、これは表示されない。\n");
  if(6-5){
    printf("6-5は1なので真である。よってこれは表示される\n");
    printf("こんな風にifのあとを{}で囲むと、複数の処理をかくことができる\n");
  }
}

大体わかったでしょうか?このif文を使えば、いろいろなことができるようになりそうですね!では例えば、ユーザーから入力された数字が42ではない時だけ、メッセージを表示する様なプログラムをつくってみましょう。

#include <stdio.h>

int main(void){
  int a;
  scanf("%d",&a);
  if(a - 42){
    printf("世界の答えではない\n");
  }
  return 0;
}

プログラムの意味は理解してもらえたでしょうか8?流れは簡単です。aにscanfで値を代入します。その値が42だったときはifの中の式の値が0になるためなにも行われず、42ではなかった場合、if文の中の値が0以外になるため真となり、文字が表示されるようになっています。

しかし、これってちょっと困りますよね。入力された値が42のときだけ、何かを表示するというプログラムを書けません。そんなときに利用するのが、==演算子です。

#include <stdio.h>

int main(void){
  int a;
  scanf("%d",&a);
  if(a == 42){
    printf("世界の答えだ\n");
  }
  return 0;
}

==演算子を使うと、左の値(左辺値とも言います)と右の値(右辺値)が等しいときは式の値は1、そうでないときは0となります。aが42であれば、a == 42は1となるのでprintfが実行されますし、aが42でなければ0となるのでprintfは実行されません。

==演算子は代入演算子(=)と非常に間違えやすいので注意してください9

==等値演算子と言われるものです。等値演算子には2つの種類があります。

演算記号 意味
== 左辺値と右辺値が等しければ1になる
!= 左辺値と右辺値が等しくなければ1になる

では早速、サンプルのプログラムを見てみましょう。

#include <stdio.h>

int main(void){
  int a;
  printf("3の倍数かどうかを判定するプログラムです\n");
  printf("3の倍数であれば「3の倍数です」と表示します。\n");
  scanf("%d",&a);
  if(a % 3 == 0){
    printf("%dは3の倍数です\n",a);
  }
  return 0;
}

==の演算子としての優先度は%*+-/などより高く設定されていますから、上のa % 3 == 0は、a % 3の結果が0と等しいか、という意味になります。3の倍数であれば3で割ったあまりは0になるため、上のプログラムが成立します。

else,else if

さきほどのサンプルプログラムを発展させて、「3の倍数であるときは『3の倍数です』と表示させ、そうでないときは『3の倍数ではありません』と表示する」プログラムを作ってみましょう。こういったプログラムを書くときに必要なのがelse文です。

if(条件式) 条件式が真だったときの処理;
else 条件式が偽のときの処理;

else文はif文と合わせて使います。if文の条件式が偽だったときにその後の処理文が実行されるようになっています。

else文の中でさらに条件式を指定したい場合は、else if文を使います。

if(条件式A) 条件式Aが真だったときの処理; 
else if(条件式B) 条件式Aが偽かつ条件式Bが真だったときの処理;

こちらもちょっとわかりづらいですから、サンプルを見てみましょう。

#include <stdio.h>

int main(void){
  if(0){
    printf("ここは条件式が偽なので実行されない。\n");
  } else {
    printf("条件式が偽なのでここは実行される\n");
  }
  if(1){
    printf("条件式が真なのでここは実行される\n");
  } else {
    printf("条件式が真なのでここは実行されない\n");
  }
  if(0){
    printf("ここは条件式が偽なので実行されない。\n");
  } else if(3*4 == 12){
    printf("一つ目の条件式が偽、かつ二つ目の条件式が真なのでここは実行される\n");
  }

  if(0){
    printf("ここは条件式が偽なので実行されない。\n");
  } else if(3*4 != 12){
    printf("二つ目の条件式が偽なので実行されない。\n");
  } else {
    printf("一つ目と二つ目の条件式がどちらも偽なので実行される.\n")
  }
  return 0;
}

大体理解できたでしょうか?このelse文を使えば、こんな風にプログラムを書けます。

#include <stdio.h>

int main(void){
  int a;
  printf("3の倍数かどうかを判定するプログラムです\n");
  printf("3の倍数であれば「3の倍数です」と表示し、そうでなければ「3の倍数ではありません」と表示します。\n");
  scanf("%d",&a);
  if(a % 3 == 0){
    printf("%dは3の倍数です\n",a);
  } else {
    printf("%dは3の倍数ではありません。",a);
  }
  return 0;
}

このような条件分岐は、プログラムを書く上でとても大切になります。頑張って覚えましょう。

練習問題

  1. 上の足し算と引き算のプログラムを利用して、足し算と引き算好きな方を計算できるようなプログラムを書いてみましょう。

ヒント: 足し算・引き算に使う変数とは別に、ユーザーからの入力を受け付ける変数を用意します。scanf関数を使って入力してもらった数字をそこに代入し、その値が1であったら足し算を、2であったら引き算を行うようなプログラムを書いてみましょう。

まとめ


  1. 数学的に言えば実数を

  2. 環境によっては下の表と違う範囲であるときがあります。型の範囲に依存するプログラムを記述したい場合はプログラミングができそうな先輩に聞いてみてください

  3. 正確にはフォーマット指定子といいます

  4. 環境によって実際に表示される文字列は違います

  5. 文字と文字列に関してはこの講座では扱いません。

  6. 文字・文字列についてはこの講座では扱いません

  7. アンパサンドと読みます

  8. このテキストの意味を知りたかったら、暇なときに42という言葉をGoogle検索してみてください

  9. プログラムが上手く動かないということがあったら、まず代入演算子と==演算子を間違えていないかを確認するべきと言われるほどです