C#での演算処理

演算

第一日目では、Console.WriteLine()およびWrite()を用いて、様々なものを表示してみました。ここで更に、C#を用いた計算について学んでいくことにしましょう。

プログラミングでは、こういった計算のことを、演算と呼びます。ここでは簡単な演算のプログラムをみてみることにしましょう。

サンプロプログラム

プロジェクト:Sample201/ファイル名Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sample201
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("{0} + {1} = {2}", 5, 2, 5 + 2);  //  足し算
            Console.WriteLine("{0} - {1} = {2}", 5, 2, 5 - 2);  //  引き算
            Console.WriteLine("{0} * {1} = {2}", 5, 2, 5 * 2);  //  掛け算
            Console.WriteLine("{0} * {1} = {2} 余り {3}", 5, 2, 5 * 2, 5 % 2);//  割り算と剰余  
        }
    }
}
実行結果
5 + 2 = 7
5 - 2 = 3
5 * 2 = 10
5 / 2 = 2 余り 1

実行結果からもわかるとおり、このプログラムを実行すると、様々な計算結果が出てきます。

演算子

このように、C#で様々な演算を行う記号のことを演算子(えんざんし)と呼びます。足し算の+や、引き算の-はわかるものの、その他の記号は何でしょう?C#で使用する演算子は以下の表2-1のようなものがあります。

表2-1:C#の計算で用いられる主な演算子
演算子 読み方 意味 使用例
+ プラス 足し算を行う演算子 5 + 5
- マイナス 引き算を行う演算子 7 - 3
* アスタリスク 掛け算を行う演算子 7 * 3
/ スラッシュ 割り算を行う演算子 7 / 3
% パーセント 剰余(じょうよ)演算子。割り算の余り 7 % 3

この表からわかるとおり、*が掛算、/が割り算を表す記号であることがわかると思います。また、%の記号は、かなりC#のプログラミングでは使用頻度が高いので、覚えておきましょう。

パラメータの表示

このプログラムの中で、数値および、その計算結果といった、パラメータをConsole.WriteLine()の中で表示する場面があります。

Console.WriteLine
Console.WriteLine("{0} + {1} = {2}", 5, 2, 5 + 2); // 足し算

""l;で囲まれた範囲内に書かれている{}の中に書いてある番号が、後で,で区切られたパラメータを表示するための番号を示しています。

後に続くパラメータの値が、5,2,5+2の場合は、それぞれに該当する番号は、0,1,2であり、{}内に同じ番号で記述されているパラメータの番号の位置に表示されます。(図2-1.)

図2-1.Console.WriteLineとパラメータの位置関係

Console.WriteLineとパラメータの位置関係

変数

C#と変数

C#を用いれば、様々な演算ができることはすでにわかりました。しかし、これでは、決められた値の計算しかできません。実際は、色々な数値を用いて計算することが想定されるため、これでは不便です。このように、値が定まった数のことを、定数と言いますが、それに対し、C#には、値を常に変えることができる数が存在するのです。これを、変数と言います。

サンプルプログラム

まずは、以下のサンプルを実行してみてください。

プロジェクト:Sample202/ファイル名Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sample202
{
    class Program
    {
        static void Main(string[] args)
        {
            int a;           // 変数の宣言
            int b = 3;      //  初期化と代入を同時に行う。
            int add,sub;    //  複数の変数を同時に宣言
            double avg;     //  int以外の変数を宣言
            a = 6;  //  代入(最初に値を入れるので、”初期化”と言う。
            add = a + b;            //  a,bの和を求める。
            sub = a - b;            //  a,bの差を求める。
            avg = (a + b) / 2.0;    //  a,bの平均値を求める。
            Console.WriteLine("{0} + {1} = {2}", a , b ,add);
            Console.WriteLine("{0} - {1} = {2}", a, b, sub);
            Console.WriteLine("{0}と{1}の平均値{2}",a,b,avg);
        }
    }
}
実行結果
6 + 3 = 9
6 - 3 = 3
6と3の平均値 4.5

プログラムの中にabaddsubavgといった文字列が出ていますが、これが変数です。int aとある部分を、変数の宣言と言います。そのあと、a=6のようにすると、値が入ります。これを代入と言います。(図2-2)特に、変数を宣言したときに、最初に行う代入のことを、初期化と言います。

代入

数値が代入された変数は、その数値として扱う事が出来ます。例えば、a=6とすれば、aは別の値が代入されるまで、"6"として扱う事が出来ます。変数は原則的に何度も値を変えるとが可能です。つまり、変数は値を変えることが出来るのです。

変数の初期化と代入
int a; ← 変数の初期化(aという変数を使えるようにする)
a = 6; ← 代入。(変数に値を入れる)

図2-2.変数の宣言と代入のイメージ

変数の宣言と代入のイメージ

演算の優先順位

プログラム中に、()(括弧)がありますが、これは、計算の優先順位を変更するものです。通常、

括弧が無い場合の計算
1 + 2 * 3 → 結果は7

とすると、最初に掛け算の演算である「2*3」が実行され、その結果の6に1が加算されます。したがって、結果は7になります。しかし、

括弧を用いた計算
(1 + 2) * 3 → 結果は9

とすると、()内の計算を先に行い、その結果である、3と次の3が掛けられることになります。このように、C#にも、数学と同じような演算子の優先順位があります。C#には様々な演算があるため、ここでは全てを説明するのは省略しますが、加減乗除といった基本的な数値計算に関しては、数学と同じルールに従うと思ってほぼ間違いありません。(図2-3)

図2-3.()を使用した場合と、使用しない場合の演算の処理

C#での()が無い演算と、ある演算

データ型

では、初期化の際に変数の先頭についている、intや、doubleといった文字列は何でしょうか?このような文字列のことを、データ型と言い、その変数がどのような値を扱うのかを示しています。 例えば、intは、整数型のデータ型を表し、"int a"とすると、"aは整数の値が入る変数である。"ことを意味します。なお、データ型には以下のようなものがあります。(表2-3

表2-3:C#で用いられるデータ型
データ型 説明 ビット 範囲
byte符号なし整数80 ~ 255
sbyte符号付き整数8-128 ~ 127
int符号付き整数32-2,147,483,648 ~ 2,147,483,647
uint符号なし整数320 ~ 4294967295
short符号付き整数16-32,768 ~ 32,767
ushort符号なし整数160 ~ 65535
long符号付き整数64-922337203685477508 ~ 922337203685477507
ulong符号なし整数640 ~ 18446744073709551615
float単精度浮動小数点型32-3.402823e38 ~ 3.402823e38
double倍精度浮動小数点型64-1.79769313486232e308 ~ 1.79769313486232e308
char単一 Unicode 文字16テキストで使用される Unicode 記号
bool論理ブール型8true または false
object他のすべての型の基本型
string文字列
decimal29 の有効桁数で 10 進数を表現
できる正確な小数または整数型
128±1.0?×?10e ? 28 ~ ±7.9?×?10e28

初期化

再び変数の話に戻りましょう。変数は、宣言時に値を代入(初期化)することが出来ます。記述方法は以下のとおりです。

変数の宣言と初期化を同時に行う
int a = 6;← 変数の宣言と同時に値を代入(初期化)

また、以下のように、,(コンマ)で区切ることにより同時に複数の変数を宣言したり、初期化することも可能です。

複数の変数を同時に宣言
int a,b;← 変数a,bを宣言
int a=1,b=2;← 変数a,bを初期化
int a,b=1;← 変数a,bを宣言、bのみを初期化

変数の命名規則

C#の変数の命名規則

変数の名前は、基本的にプログラマーが自由につけることが許されています。通常、アルファベット一文字か、その組み合わせといったものが使われる場合がほとんどです。しかし、何でも良いというわけではなく、以下のようなルールがあります。

キーワード

なお、予約語とは言語の仕様で使い方が決められている単語のことで、C#のキーワードは以下のとおりです。(表2-4)

表2-4:C#のキーワード
abstractasbasebool
breakbytecasecatch
charcheckedclassconst
continuedecimaldefaultdelegate
dodoubleelseenum
eventexplicitexternfalse
finallyfixedfloatFor
foreachgotoifimplicit
[in]in (ジェネリック修飾子)intinterface
[in]in (ジェネリック修飾子)intinterface
internalislocklong
namespacenewnullobject
operator[out]out (ジェネリック修飾子)override
paramsprivateprotectedpublic
readonlyrefreturnsbyte
sealedshortsizeofstackalloc
staticStringstructswitch
thisthrowtruetry
typeofuintulongunchecked
unsafeushortusingvirtual
voidvolatilewhile

さらに、C#には、コンテクストキーワードというものがあります。(表2-5.)これらはコード内で特定の意味を与えることができます。キーワードと違い、変数名として利用することは可能ですが、誤解を避けるためにできれば避けた方が良いでしょう。

表2-5:C#のコンテクストキーワード
addaliasascending
asyncawaitdescending
dynamicFromget
globalgroupinto
joinletorderby
partial (型)partial (メソッド)remove
SelectSetvalue
varwhere (ジェネリック型制約)where (クエリ句)
yield

代入演算子

代入と演算

すでに述べたとおり、変数に値を入れることを代入と言いました。代入とは例えば以下のように記述します。

代入処理
a = 1;← 変数aに1を代入
a = b;← 変数aに変数bの値を代入
d = 4.0;← 変数dに4.0を代入

ここで気をつけたいのが、代入で使用する=(イコール)記号の意味です。数学で、=記号は、左辺と右辺の値が等しい、という場合に用いられる記号です。しかし、Javaで代入に用いる=は、少し意味が違います。

代入におけるイコールは、右辺の値を左辺の変数に代入するという意味になるのです。そのため、例えば

自身を用いた計算結果を代入する
a = a + 1;← ① aに、a+1の値を代入する。
b = b * 5;← ② bに、b*5の値を代入する。

といった記述方法も可能になります。例えば、①ですが、仮に最初の段階でaに4が入っていたとすると、そこに1を足した5がaに代入されます。についても同様で、bに2が入っていたら、2に5をかけた値、つまり10がbに入ります。

プロジェクト:Sample203/ファイル名Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sample203
{
    class Program
    {
        static void Main(string[] args)
        {
            // 使用する変数の定義
            int a1=2,b1=2,c1=2,d1=2;    // 変数の宣言(1)
            int a2=2,b2=2,c2=2,d2=2;    // 変数の宣言(2)
            //  普通の演算による計算と代入
            a1 = a1 + 1;
            b1 = b1 - 1;
            c1 = c1 * 2;
            d1 = d1 / 2;
            //  代入演算による計算
            a2 += 1;
            b2 -= 1;
            c2 *= 2;
            d2 /= 2;
            Console.WriteLine("a1={0} b1={1} c1={2} d1={3}", a1, b1, c1, d1);
            Console.WriteLine("a2={0} b2={1} c2={2} d2={3}", a2, b2, c2, d2);
        }
    }
}
実行結果
a1=3 b1=1 c1=4 d1=1
a2=3 b2=1 c2=4 d2=1

代入演算子

実行結果を見れば判る通り、a1とa2~d1とd2の組み合わせはそれぞれ、記述の仕方が違うだけで、結果が同じであることが判ります。このように、代入演算を用いれば、短い記述で同様の結果を得ることが出来ることがわかります。

なお、Javaにおける主な代入演算は、以下のとおりです。(表2-6.)

表2-6:C#の主な代入演算子
演算子 使用例 意味
+= a+=1; a=a+1;
-= a-=1; a=a-1;
*= a*=2; a=a*2;
/= a/=2; a=a/2;
%= a%=2; a=a%2;

キャストとデータの型変換

サンプルプログラム

次に、型の異なる変数に値を代入するケースを見てみましょう。例えば、整数型の変数の値を実数型の変数に代入するような処理です。以下のサンプルを見てみましょう。

プロジェクト:Sample204/ファイル名Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sample204
{
    class Program
    {
        static void Main(string[] args)
        {
            int a;
            double b,c,d;
            a = (int)1.23;  //  キャストで代入
            b = 1.23;
            c = 10;         //  キャストなしで代入
            d = (double)c;  //  キャストありで代入
            Console.WriteLine("a={0} b={1} c={2} d={3}",a,b,c,d);
        }
    }
}
実行結果
a=1 b=1.23 c=10 d=10

キャスト

このプログラムでは、8行目でdouble型からint型の変換と、11行目でint型から変換からdouble型への変換を行っています。実行結果から見てわかるとおり、前者の場合、小数点以下の数値が切り捨てられ、後者の場合は、整数に変換されていることがわかります。

8行目と、11行目では、変換する値への型変換がおこなわれています。頭に(int)や(double)などと、変換したい値の型を先頭につけることを、キャストと言います。

キャスト
a = (int)1.23;
d = (double)c;

aはint型の変換なので、double型の変数を代入する際、先頭に(int)とつけ、e2は(double)なので、先頭に(int)とつけることにより、型の変換を行います。このとき、キャストを省略するとエラーになります。また、この処理の結果、小数点以下の内容は省略されます。

また、11行目では整数型を実数型に変換する型変換が行われていますが、同じ変換でも、整数から実数への変換の場合、キャストは省略してもエラーになりません

文字列の変数

サンプルプログラム

数値などのほかに、C#では文字列を変数として扱うことができます。文字列の変数を宣言するには、stringを使います。厳密に言うと、これはintdoubleなどといったデータ型ではありませんが、データ型と同じように扱うことができます。まずは、以下のサンプルを実行してみてください。

プロジェクト:Sample205/ファイル名Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sample205
{
    class Program
    {
        static void Main(string[] args)
        {
            string str1, str2;
            Console.Write("str1=");
            str1 = Console.ReadLine();  //  1つ目の文字列を入力
            Console.Write("str2=");
            str2 = Console.ReadLine();  //  2つ目の文字列を入力
            Console.WriteLine("str1 + str2 = {0}", str1 + str2);
        }
    }
}

実行結果
str1=Hello  ← キーボードから文字列を入力
str1=Hello  ← キーボードから文字列を入力
str1 + str2 = HelloWorld

実行結果を見てもわかるとおり、実行すると「str1=」と表示され、コンソールから文字列の入力待ち状態になります。ここで文字列を入力してEnterボタンを押すと、再び「str2=」と表示され、再び文字列の入力待ち状態になります。ここで再び、二つ目の文字列を入力し、Enterボタンを押します。

すると、18行目の処理で、+演算子により、文字列の変数同士が結合され出力されます。このように、+演算子を用いれば、文字列を結合することができます。

文字列の入力

なお、文字列の結合はすでに説明したとおり、コンソールからの文字列の入力は、Console.ReadLine()で行うことができます。それを、文字列変数に入力することができます。(15,17行目)

コンソールから入力された文字列を、文字列型変数に代入
str1 = Console.ReadLine();← ① コンソールから文字列を入力し、文字列変数str1に代入。
str2 = Console.ReadLine();← ② コンソールから文字列を入力し、文字列変数str2に代入。

定数

サンプルプログラム

変数は、自由に値を変えることが可能です。しかし、何らかの理由で、定数など、値を変えたいようなことがあります。その時便利なのが、constキーワードです。以下のプログラムを実行してみてください。

プロジェクト:Sample206/ファイル名Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sample206
{
    class Program
    {
        static void Main(string[] args)
        {
            const int NUMBER = 100;
            const string STRING = "Hoge";
            Console.WriteLine(NUMBER);
            Console.WriteLine(STRING);
            //  constがついた変数は値を変えられない
            //NUMBER = 100;
            //STRING = "fuga";
        }
    }
}
実行結果
100
Hoge

constキーワード

プログラムの13行目および、14行目で、それぞれint型、String型の変数を定義し、初期値を設定しています。15、16行目でその結果を表示していますが、ここまでは、今まで学習してきた変数と変わりません。

しかし、18行目および19行目のコメントをとってみてください。エラーが発生します。つまり、constがついた変数は、一度定義したら、二度と値を変更することが出来ないのです。そのため、constは、円周率のような、値を変えられたら困るような値に使用するのが一般的です。

練習問題 : 問題2.