C#入門編

C#入門編(3)演算子と式 ~BMI計算をした結果をHTMLで出力~

今回は、BMIを計算してその結果をHTMLで出力する演習を行います。

演習を通して以下について学ぶことができます。

学べること

  • プログラムの構成要素(文、式、演算子など)
  • 演算子の種類

プロ太
プロ太
データに対して様々な計算を行うためには、演算子を使います。

Youtubeの動画でも解説しているので、こちらもぜひ御覧ください。

演習1:BMI計算した結果をHTML出力

前回は変数と型について学び、HTMLへ入力値を埋め込みました。今回は、前回までの復習をしつつ、データに対する計算を行ってみましょう。

演習プログラムとポイント

今回は、ユーザが入力した身長、体重を元にBMIを計算をした結果をHTMLとして出力するプログラムを作成してみましょう。

身長と体重からBMIを計算するために、演算子を使います。

あと、これまで何気なくプログラムを書いていましたが、あらためてプログラムの構成要素についても学んでいきましょう。

以下は、ユーザから入力された身長と体重を元にBMIを計算し、その結果をHTMLで出力するプログラムです。

BMIの計算は「体重(kg) ÷ (身長(m) × 身長(m))」です。

Console.Write("身長を入力してください:");
double height = Convert.ToDouble(Console.ReadLine());
Console.Write("体重を入力してください:");
double weight = Convert.ToDouble(Console.ReadLine());
double bmi = weight / (height * height); //★(a)
          
Console.WriteLine("<html><body>");
Console.WriteLine("<table border=\"2\">"); //★(b)
Console.WriteLine($"<tr><td>身長</td><td>{height}</td></tr>");
Console.WriteLine($"<tr><td>体重</td><td>{weight}</td></tr>");
Console.WriteLine($"<tr><td>BMI</td><td>{bmi}</td></tr>");
Console.WriteLine("</table>");
Console.WriteLine("</body></html>");

このプログラムの大部分は、前回までに学んできた以下の知識があれば、理解できるかとお思います。

  • 変数、型、型変換
  • 文字列補完 ($””の記法)

今回はHTMLのTableタグを使って表形式で結果を出力しています。

プログラムの(a)の箇所ではBMIを計算するために算術演算子を使っています。これを例にとり、演算子やプログラムの構成要素(式、文)ついて説明します。

また、(b)では文字列で特別な文字(“)を扱うために、エスケープシーケンスという仕組みを使っています。こちらについても説明していきます。

ポイント1:プログラムの構成要素(演算子、式、文)

プログラムの(a)の(height * height)の部分で、*は数値の掛け算を行う演算子(オペレータ)です。

そして、演算の対象となる要素をオペランドといいます。この例では*演算子の左右のheight変数ですね。

そして、演算子とオペランドを合わせて式と呼びます。

演算子と式(その1)

計算結果の式は、別の演算子のオペランドにすることができます。/は数値の除算となります。以下のように、「weight」と「height*heightの計算結果」が/演算子のオペランドですね。

演算子と式(その2)

実は、これまで変数への代入で使っていた「=」も代入演算子なのです。なので、以下のようになります。

演算子と式(その3)

そして、式や演算子を組み合わせることで文を作ります。文はセミコロンで終わります。

今回、(a)の部分を例にとって説明しましたが、演習プログラムの他のコードも全て同じように文、式、演算子と分解していくことができます。

プロ太
プロ太
小さいなものを少しずつ組み合わせ大きくし、プログラムを構成しているのですね。

ポイント2:エスケープシーケンス

プログラムの(b)では、テーブルの枠線の幅を変更するために「<table border="2">」というダブルクォーテーション「"」が含まれる文字列を出力しようとしています。

ところが、ダブルクォーテーション「"」は、C#において、"XXXX"と文字列を表現する特殊な記号であるため、そのまま表記することができません。

このように、そのまま表記できない文字はエスケープシーケンスという表記で記述します。ダブルクォーテーションは「\"」と表記します。

こちらにエスケープシーケンスの一覧があるので、参考にしてください。

プロ太
プロ太
改行コードを書くときもエスケープシーケンスを使います。

実行結果

プログラムを実行すると、以下のようになります。

演習1ぷろの実行結果


身長を入力してください:1.75
体重を入力してください:65.0
<html><body>
<table border=”2″>
<tr><td>身長</td><td>1.75</td></tr>
<tr><td>体重</td><td>65</td></tr>
<tr><td>BMI</td><td>21.224489795918366</td></tr>
</table>
</body></html>

身長は1.75m(単位はcmではなくmで入力することに注意してください)、体重は65kgと入力しています。BMIは21.224489795918366と出力されていますね。

出力されたHTMLをブラウザで表示すると、以下のようになります。

HTMLで結果を表示

きちんと表形式で結果が表示されていますね。

講義1:演算子の種類

C#には算術演算子、ブール論理演算子など多くの演算子が用意されています。

演算子は、オペランドの数によって以下の3種類に分けられます。

  • 単項演算子
  • 2項演算子
  • 3項演算子

主な演算子の一覧を以下に載せます。

主な演算子の一覧

それぞれの演算子について、具体例も示しながら説明していきます。

算術演算子

算術演算子は、数値型(整数型、浮動小数点数型)に対して、四則演算などの数値計算を行う演算子です。

今回の演習プログラムでも、浮動小数点数の乗算、除算ができましたね。

以下に算術演算子の例をいくつか示します。

int a = 2;
int b = 3;
Console.WriteLine(a + b);//結果は5
Console.WriteLine(a - b);//結果は-1
Console.WriteLine(a * b);//結果は6
Console.WriteLine(a / b);//結果は0
Console.WriteLine(a % b);//結果は2

int c = 5;
int d = 5;
Console.WriteLine(-c);//結果は-5
Console.WriteLine(++c);//結果は6 (←前置記法だと1増えた後)
Console.WriteLine(c);//結果は6 (←結果として1増える)
Console.WriteLine(d++);//結果は5 (←後置記法だと1増える前)
Console.WriteLine(d);//結果は6 (←結果として1増える)

文字列連結演算子

文字列連結演算子は文字列同士を連結して新しい文字列を作る演算子です。前回の演習でも使いましたね。

以下は文字列連結演算子の使用例です。

string s1 = "abc";
string s2 = "def";
            
Console.WriteLine(s1 + s2);//結果はabcdef

ブール論理演算子

ブール論理演算は真偽値型(ブール型)の、論理計算を行い、何らかの条件が成立するかどうかを判定するために使います。

ブール論理演算子は、次回に話をする制御文(if文、for文など)と一緒に使うことが多いため、具体的にどのような場面で使うものかは、そちらで説明します。

ここでは、それぞれの演算子について、一通り簡単に紹介します。

  • 論理否定演算子(!):TrueはFalse、FalseはTrueと、真偽を反転させます。
  • 論理和(|)、短絡論理和(||):左右のオペランドのどちらかが真ならば、真となります。
  • 論理積(&)、短絡論理積(&&):左右のオペランドの両方が真ならば、真となります。
  • 排他的論理和(^):左右のオペランドが異なる真偽値ならば、真となります。

それぞれのオペランドの組み合わせと演算結果をまとめると以下のようになります。

論理否定演算子
論理和、論理積、排他的論理和

以下にプログラム例をいくつか載せます。

bool a = true;
bool b = false;

Console.WriteLine(!a);//結果はFalse
Console.WriteLine(!b);//結果はTrue
Console.WriteLine(a & b);//結果はFalse
Console.WriteLine(a | b);//結果はTrue
Console.WriteLine(a ^ b);//結果はTrue
Console.WriteLine(a && b);//結果はFalse
Console.WriteLine(a || b);//結果はTrue
Console.WriteLine(a || !(a && !b));//結果はTrue

論理和と短略論理和、論理積と短絡論理積の結果は全く同じですね。何が違うのでしょうか?

実は、短略論理和/短絡論理積は、途中で計算結果(真か偽か?)が確定した段階で、残りの部分の計算は行わないのです。これを短絡評価(ショートサーキット評価)といいます。

例えば、上述した論理演算子の例における最後の式「a || !(a && !b)」は複雑な式になっていますが、aがTrue(真)とわかれば、「!(a && !b)」の真偽にかかわらず式全体としては真になるとわかるため、「!(a && !b)」については計算する必要がなく、省略できるのです。

基本的には、短略評価の方が処理効率で優れるため、短略論理和・論理積(&&と||)を用いればよいです。

プロ太
プロ太
私がプログラムを書くときには、基本的に短絡評価しか使いません。

ただ、短絡評価ではない方(|と&)が使われているプログラムを読むこともあるため、計算の仕方が異なる点は知っておくと良いです。

いろいろでてきてややこしいですが、とりえあず「Not(!)、Or(||)、And(&&)」の3つを覚えていれば大丈夫です。if文とあわせて実際の使い方を学んでいきましょう。

等値演算子

等値演算子は、2つのオペランドが等しいときに真となり、非等値演算子は等しくないときに真となります。以下に例を示します。

int x = 1;
int y = 1;
int z = 2;

Console.WriteLine(x == y);//結果はTrue
Console.WriteLine(x == z);//結果はFalse
Console.WriteLine(x != y);//結果はFalse
Console.WriteLine(x != z);//結果はTrue

string s1 = "abc";
string s2 = "abc";
string s3 = "def";

Console.WriteLine(s1 == s2);//結果はTrue
Console.WriteLine(s1 == s3);//結果はFalse
Console.WriteLine(s1 != s2);//結果はFalse
Console.WriteLine(s1 != s3);//結果はTrue

等値演算子は、比較対象が「値型」の場合と「参照型」の場合とで動作が異なります。

値型については、データの中身そのものが等しいかどうかを判定します。これは直感的ですね。

しかし、参照型の場合には、データの中身ではなく参照先が等しいかどうかで判定します。(ただし、文字列型についてはデータの中身が等しいかで判定してくれるようになっています。)

等値演算子を参照型へ適用したときの具体的な動作や注意点などは、オブジェクト指向やクラスの話をするときに詳しく紹介します。

比較演算子

比較演算子は、オペランドの大小を比較して、その結果の真偽を返します。

以下にいくつか例を示します。

int x = 1;
int y = 1;
int z = 2;

Console.WriteLine(x >= y);//結果はTrue
Console.WriteLine(x > y);//結果はFalse
Console.WriteLine(x < z);//結果はTrue
Console.WriteLine(x <= z);//結果はTrue

数学の不等式でも出てくる記号なので、こちらも直感的にわかりやすいかと思います。

プロ太
プロ太
論理演算子、等値演算子、比較演算子を組み合わせることで、様々な条件が記述できるようになります。

三項条件演算子

三項条件演算子は3つのオペランドをとり、第1項の論理式を評価した結果が真であるなら第2項を、偽であるならば第3項を返します。

以下が例です。

int x = 1;
int y = 2;
            
int z = x > y ? x : y;
Console.WriteLine(z);//結果は2
プロ太
プロ太
次回説明する制御構文(if文)と似たような処理を行えます。

代入演算子、複合代入演算子

代入演算子は、変数への代入を行います。これまでにも何度も使っていますね。

複合代入演算子は、代入と同時に別の演算(算術演算等)を行います。以下が例です。

int x = 1;
x -= 2; // 「x = x - 2;」と同じ意味
Console.WriteLine(x);//結果は-1

C#の演算子は他にも多くあります。一覧については、Microsoft公式ドキュメントも参考にしてください。

プロ太
プロ太
これで一通り主な演算子を紹介しました。

まずは、今回紹介したような主だったものを覚えておけばよいかと思います。

C#の言語仕様はけっこう膨大ですが、頻繁に使うものは限られますので、まずはそこを重点的に覚えればOKです。

プログラムの構成要素は全て、文、式、演算子…などと細かく分解できます。

これまでの演習プログラムで、「Console.WriteLine(“XXX”);」という命令文がよくでてきました。

この式についても、「.」はメンバーアクセス演算子、「()」は呼び出し演算子、といった演算子で構成されています。

このような演算子については、オブジェクト指向やクラスの説明をするときに説明します。

講義2:演算子の優先順位

これまでみてきたように、演算子は組み合わせて使うことができます。

演算子を組み合わせて使ったときに、どの演算子から適用されるかは優先順位が決まっています。

例えば、「x + y * z」という式があったら、+演算子よりも*演算子の方が高い優先度なので、「y * z」から先に計算されます。これは数学における式と同じルールですね。

以下がC#の全ての演算子の優先順をC#公式リファレンスからの引用します。
(今回記事で紹介した演算子以外のものも含め、C#の全て演算子が載っています。)

C#の演算子の優先順位一覧

優先順位を変えたい場合はカッコ()を使います。

演習プログラムで、「weigh /(height*height)」という計算がありましたが、これは height * heightを先に計算したいので、カッコをつけています。

まとめ

今回は、データに対して様々な計算を行うことができる演算子の使い方について学びました。

これで、ユーザから受け取ったデータに対して様々な計算を行い、その結果をHTMLコードとして出力することができるようになりました。

算術演算子については比較的わかりやすかったと思うのですが、論理演算子や等値・比較演算子については、真偽値を返すだけで、このままでは何に使うのかがよくわからないですね。

次回は、選択(条件分岐)を行う制御構文(if文、switch文)について紹介します。そこで、論理演算子等を具体的にどう活用していくのかも説明していきます。

プロ太
プロ太
引続き、C#やプログラミングの考え方を一緒に学んでいきましょう!

ABOUT ME
プロ太
プログラミングを勉強している人へ情報を発信していきます! ・情報工学分野で博士(工学)の学位取得 ・言語:C# 、Java、C/C++、Python、JavaScript/TypeScript等 ・仕事は主に上流工程(WF開発・Agile開発、OSS開発経験あり) ・趣味で開発:3Dゲーム、Webアプリ、言語処理系等

ご依頼・ご相談について

プログラミング学習のご相談、お仕事のご依頼については、
こちらのお問い合わせページをご確認ください。