C# 初級講座 |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
2022/3/29
この記事が対象とする製品・バージョン
![]() |
Visual Studio 2022 | ◎ | 対象です。 |
![]() |
Visual Studio 2019 | ◎ | 対象です。 |
![]() |
Visual Studio 2017 | ◎ | 対象です。 |
![]() |
Visual Studio 2015 | ◎ | 対象です。 |
![]() |
Visual Studio 2013 | △ | 対象外ですが参考にはなります。 |
![]() |
Visual Studio 2012 | △ | 対象外ですが参考にはなります。 |
![]() |
Visual Studio 2010 | △ | 対象外ですが参考にはなります。 |
![]() |
Visual Studio 2008 | △ | 対象外ですが参考にはなります。 |
![]() |
Visual Studio 2005 | △ | 対象外ですが参考にはなります。 |
![]() |
Visual Studio.NET 2003 | △ | 対象外ですが参考にはなります。 |
![]() |
Visual Studio.NET (2002) | △ | 対象外ですが参考にはなります。 |
Visual Studio Code | △ | 対象外ですが参考にはなります。 |
目次
今回は数値を題材に、変数について色々見てみます。
下記の設定で新規プロジェクトを作成してください。
プロジェクトテンプレート | コンソール アプリ |
---|---|
プロジェクト名 | NumberLesson |
ソリューション名 | NumberLesson |
フレームワーク | .NET 6.0 |
そして、次の通りプログラムをして実行してください。
int x = 2;
int y = x + 3;
Console.WriteLine(y);
コンソールに「5」と表示されれば成功です。
何が起こっているか見てみましょう。
C#では数値にもいくつか種類があります。このプログラムで扱っている数値は整数型で、int (読み方:int=イント)で宣言できます。
数値型の変数 x には初期値として2を代入しています。
もう1つの数値型の変数 y には、初期値として x に 3 をプラスしたものを代入しています。結果として、y は 5 になります。
そして、Console.WriteLine で変数 y を表示しているので、結果として 5 が表示されます。
このように数値型はだいたい人間の感覚と同じようにたし算したり引き算したり計算できます。
= の意味はよく考えると数学で習うものとは違います。 = は代入を行う演算子です。
そのため y = x + 3 の意味は x に 3を足したものを y に代入するという意味になります。
中学校で習う数学の場合は y = x + 3 は方程式ですので、 C# とは異なります。
y を使わないで x だけで考えると、この違いがもっとよくわかります。
int x = 2;
x = x + 3;
Console.WriteLine(x);
このプログラムでは、最初 x の値は 2 です。次の行で x に 3 をプラスしたものを x に代入するので x は 5 になります。
この x = x + 3 が中学校で習う方程式だとしたら、おかしな意味になってしまいますよね。
ところで、今回勉強のためにあえて変数を使っていますが、最初に登場したプログラムは変数 x を使わないで、次のように書いても同じ意味です。
int y = 2 + 3;
Console.WriteLine(y);
いっそのこと、変数 y も省いて次のように書くこともできます。
Console.WriteLine(2 + 3);
もちろん、2 + 3 などと回りくどい書き方をせず 5 と書くこともできます。
整数型を含めて、C# の数値型には下記のものがあります。
型 | 読み方(一例) | 日本語 | 値の範囲 | 備考 |
---|---|---|---|---|
byte | バイト | バイト型 | 0 ~ 255 の整数 | 初心者向けではありません。 |
decimal | デシマル | 十進型 | 29桁程度の整数・小数 | |
double | ダブル | 倍精度浮動小数点型 | 309桁程度の整数・小数 | 初心者向けではありません。 |
float | フロート | 単精度浮動小数点型 | 39桁程度の整数・小数 | 初心者向けではありません。 |
int | イント | 整数型 | -2147483648 ~ 2147483647 の整数 | |
long | ロング | 長整数型 | -9223372036854775808 ~ 9223372036854775807 の整数 | |
nint | エヌイント | 環境によって異なります。 | 初心者向けではありません。 | |
nuint | エヌユーイント | 環境によって異なります。 | 初心者向けではありません。 | |
sbyte | エスバイト | 符号付きバイト型 | -128 ~ 127 の整数 | まず使いません。 |
short | ショート | 短整数型 | -32768 ~ 32767 の整数 | まず使いません。 |
uint | ユーイント | 符号なし整数型 | 0 ~ 4294967295 の整数 | まず使いません。 |
ulong | ユーロング | 符号なし長整数型 | 0 ~ 18446744073709551615 の整数 | まず使いません。 |
ushort | ユーショート | 符号なし短整数型 | 0 ~ 65535 の整数 | まず使いません。 |
これが C# の数値型のすべてです。備考欄に「初心者向けではありません。」と書いてあるものはちょっと使い方に癖があるので必要なければ手を出さない方が無難です。C#ではなく、フレームワークの機能にも目を向けるとこの表の他にも複素数(Complex)や無限桁数の整数(BigInteger)などもあります。
表を見るとわかるようにC#の数値型の主な違いは桁数です。たとえば、1000という値を使用したいのであれば byte型 では不十分です。
それからもう1つ小数を表現できるかどうかの違いがあります。初めに出てきた整数型(int)には小数を格納することはできません。
数値型にこんなに種類がある根本的な理由の1つはコンピューターは内部ではすべてのデータを 0 と 1 の集まり、つまり二進法で扱っているのに対し、人間は十進法で1,2,3,4…と数えるので、この違いをどう解決するかというアプローチが異なるからです。もう1つの大きな理由は、どうやって効率的に計算するかという観点です。特にコンピューターは割り算が苦手です。
効率性を無視すれば decimal だけを使えばほとんど困ることはありません。decimal は整数も小数も表現できるうえ、桁数も 29桁と大きいからです。しかし、1と3とか小さな値しか扱わないのに29桁分の記憶域(メモリ)を使うのはちょっともったいない気もします。計算を実行する場合は、小数点の位置をそろえて整数として計算してから必要であれば小数に戻します。こうすると内部的には整数の計算だけでほとんど済むのですが効率が悪いです。
一方、double や float は小数の計算効率を重視しています。小数の計算は速いです。ただ、特有の誤差が生じるので、良く知らないままに、金額の計算などに使っていると少しずつ誤差が出てしまうかもしれません。(だから、私は初心者向けではありませんと書きました。)
このように、各数値型それぞれで何らかの意図があり、歴史もあります。
こんなことをいちいち覚えるのは大変なので、初心者の方は次のように3つの型だけ使い分けてください。
整数 | int |
---|---|
21億以上の整数 | long |
小数が必要な場合 | decimal |
表に書いてある最大値と最小値を暗記しなくても、フレームワークの機能で取得できます。
intやlongなどの各型の名前を使ってフレームワークの機能を呼び出せるようになっており、フレームワークの MaxValue プロパティ(読み方:MaxValue=マックスバリュー)で最大値を MinValue プロパティ(読み方:MinValue=ミンバリュー)で最小値を取得できます。
int intMax = int.MaxValue;
int intMin = int.MinValue;
Console.WriteLine($"intの最大値:{intMax}");
Console.WriteLine($"intの最小値:{intMin}");
long longMax = long.MaxValue;
long longMin = long.MinValue;
Console.WriteLine($"longの最大値:{longMax}");
Console.WriteLine($"longの最小値:{longMin}");
decimal decimalMax = decimal.MaxValue;
decimal decimalMin = decimal.MinValue;
Console.WriteLine($"decimalの最大値:{decimalMax}");
Console.WriteLine($"decimalの最小値:{decimalMin}");
たし算などを行って最大値を超えると、一周回って最小値になります。最大値 に 1をたすと最小値と同じです。
int intMax = int.MaxValue;
intMax = intMax + 1; //int.MinValueと同じです。
なにかをカウントアップするプログラムを作る時は注意してください!カウントがどんどんアップしていくと、最小値になってしまうということです。
最小値についても同じで、最小値を下回ると最大値になります。
プロジェクトのプロパティでビルドの詳細欄にある「算術オーバーフローのチェック」をチェックすると、最大値を上回るか、最小値を下回る場合にエラーが発生するようになります。
これがチェックされていると、C#はオーバーフローが発生する可能性がある計算を実行するたびに、計算結果が最大値・最小値をオーバーしていないか確認するので、少しだけ実行が遅くなります。この遅さはまったく大したものではないので、通常は気にしなくても大丈夫です。円周率を何日もかけて計算するような速度至上主義のプログラムを作るような場合だけ気にすれば良いレベルだと思います。
数値の計算に使用できる演算子は次の通りです。このような演算子を算術演算子と呼びます。
この表の読み方は私はこう読んでいるというものを書きましたが、一般的にどう呼ばれているのかあまり自信はないです。
演算子 | 読み方(一例) | 意味 |
---|---|---|
++ | プラスプラス | 1 プラスします。 |
-- | マイナスマイナス | 1 マイナスします。 |
+ | プラス | たし算します。 |
- | マイナス | ひき算します。 または 符号を反転させます。 |
* | かける | かけ算します。 |
/ | わる | わり算します。 |
% | パーセント | わり算のあまりを求めます。 |
= | イコール | 計算と代入の両方を行います。 |
同じ記号が使い方によって意味が変わる場合もあります。
+ や - など見れば使い方の想像が付くものもあると思います。
++ と -- は1プラスするか1マイナスするので、1つの変数だけで使用できます。これらはインクリメント演算子またはデクリメント演算子とも呼びます。
たとえば、次のように記述できます。
int x = 3;
x++; // x は 4 になります。
x++; // x は 5 になります。
x--; // x は 4 になります。
Console.WriteLine(x);
++ と -- は使い方をミスるプログラマーもいますし、少しわかりにくいので私はあまり使わない方が良いと思っています。でも、どんな使い方ができるか説明はしておきましょう。そうじゃないと他人が書いたプログラムの意味がわからないので。
まず、次のような使い方できます。この実行結果はちょっと以外に思われるかもしれません。(ここがわかりにくいポイントです)
int x = 3;
Console.WriteLine(x++); // 3 と表示されます。
Console.WriteLine(x); // 4 と表示されます。
x++ という記述は、 x が後ろについていることがなんとなくイメージしているのですが、 x を使用した後に 1 プラスするという意味です。
そのため、最初の Console.WriteLine は 1プラスを実行する前に値を表示します。
++ を前に書くことができて、そうすると、 x を 1プラスした後に値が使用されるので結果が変わります。
int x = 3;
Console.WriteLine(++x); // 4 と表示されます。
Console.WriteLine(x); // 4 と表示されます。
この性質をすごく上手に活かしたプログラムができる場合もあるのですが、たいていはわかりにくいように私は思います。
みなさんもこの説明を見てあまり良い気分はしなかったのではないでしょうか?
x に 1プラスしたいのなら次のように書いた方が私はわかりやすいと思います。これならいつプラス1されているかとても明確です。
int x = 3;
x = x + 1;
Console.WriteLine(x); // 4 と表示されます。
すぐ後で説明しますが, x = x + 1 のことを x += 1 と書くこともできます。
小学校でも習うたし算・ひき算・かけ算・わり算はだいたい直感的に使えます。
ただ、パソコンのキーボードにはかけ算の記号「×」とわり算の記号「÷」がないので、代わりに * と / を使います。
int x = 10;
Console.WriteLine(x + 4); // 14
Console.WriteLine(x - 4); // 6
Console.WriteLine(x * 4); // 40
Console.WriteLine(x / 4); // 2
注目すべきはわり算です。整数しか表現できない型(int, longなど)同士でわり算を行うと、あまりは切り捨てられ答えは整数部分だけが返されます。
この例でもあ 10 ÷ 4 = 2.5 ですが、小数部分は切り捨てられて 2 が表示されます。
% 演算子はわり算のあまりだけを返すので、あまり部分が必要な組み合わせましょう。
int x = 14;
Console.WriteLine(x / 3); // 14÷3 からあまりを除いて 4
Console.WriteLine(x % 3); // 14÷3 のあまりの 2
int ではなく decimal の場合、小数も表現できるので、結果が変わります。
decimal x = 10;
Console.WriteLine(x + 4); // 14
Console.WriteLine(x - 4); // 6
Console.WriteLine(x * 4); // 40
Console.WriteLine(x / 4); // 2.5
これ、結構忘れやすいので、覚えておいてください。わり算の答えが小数の時、整数型同士の演算ならば小数部は切り捨てられ、小数が表現できる型ならば小数部が保持されるということです。
割り切れない場合は、桁数が無限というわけではないので、限界の桁数まで答えを計算します。
decimal x = 14;
Console.WriteLine(x / 3); // 4.6666666666666666666666666667
Console.WriteLine(x % 3); // 14÷3 のあまりの 2
ひき算の - 記号は単一の値の前に付けるとプラスマイナスを逆転させる効果があります。
この使い方は直感的でわかりやすいので一度知っておけば困ることはないでしょう。
long value1 = 123;
long value2 = -value1; //123を反転して -123にします。
long value3 = -value2; //-123を反転して 123 にします。
Console.WriteLine($"value2 = {value2}"); //-123
Console.WriteLine($"value3 = {value3}"); //123
各演算子と = を組み合わせて、演算と代入を同時に行うことができます。
たとえば、x = x + 3 という式は、x に 3を加えたものを x に代入する意味であるということは既に説明しましたが、これを x += 3 と書くこともできます。この2つは同じ意味です。
decimal x = 5;
x = x + 3;
Console.WriteLine(x); // 8
decimal y = 5;
y += 3;
Console.WriteLine(y); // 8
- や * などほかの演算子と組み合わせることもできます。
int x = 10;
x += 4;
Console.WriteLine(x); // 14
x -= 5;
Console.WriteLine(x); // 9
x *= 2;
Console.WriteLine(x); // 18
x /= 3;
Console.WriteLine(x); // 6
x %= 4;
Console.WriteLine(x); // 2
1つの式で複数の演算子を使った場合、左から順番に計算されるわけではありません。演算子ごとに優先度が決まっており、優先度が高い演算子から計算されます。
たし算やひき算よりかけ算やわり算が優先されるルールになっており、学校で習う算数や数学のルールと同じです。
下記のプログラムでは、かけ算が先に計算されるので、 結果は6になります。
long value = 2 + 2 * 2;
Console.WriteLine(value); // 6
でも、学校の算数・数学には出てこない演算子もあるので、時には混乱してしまうこともあります。
( ) を使うと、その部分の優先度を上げることができるので、実際のプログラムでは ( ) を記述することが多いです。たとえば ( ) があってもなくても結果が変わらなくても、わかりやすさを優先するために ( ) を付けることが推奨されています。
このようになります。どうでしょうか。最初のプログラムよりわかりやすく感じませんか?
long value = 2 + (2 * 2);
Console.WriteLine(value); // 6
次のプログラムは今回説明した演算子だけでを使っていますが、何が起こるのかちょっとわかりにくいです。
long value = 13;
value = -value + 20 % 5;
Console.WriteLine(value);
これは意地悪な例で、こんなプログラムを実戦では目にすることはない思いますが、これも ( ) を使って書き直してみましょう。
long value = 13;
value = (-value) + (20 % 5);
Console.WriteLine(value);
こうすると、20 % 5 が 20÷5 のあまりで 0 になるから、結局 -value つまり、 -13 が答えであるということがわかりやすくなります。
あなたが頭の回転が速い人ならかっこを書かなくても何の問題もないかもしれませんが、それでも ( ) を付けるようにしましょう。あなたが書いたプログラムを他の人が見てもわかりやすくするためです。
累乗や絶対値・標準偏差など対応するC#の演算子がない計算でも、フレームワークの機能で簡単にできるものがあります。
特にフレームワークの Math クラス (読み方:Math=マス)には数学でよくでてくる計算機能があります。
一例を紹介します。
int x1 = Math.Abs(-123); //123。絶対値。
double x3 = Math.Floor(6.78); //6。切り捨て。
double x4 = Math.Floor(-6.78); //-7。(低い方に寄る)。
double x5 = Math.Ceiling(3.45); //4。切り上げ。
double x6 = Math.Ceiling(-3.45); //-3。(高い方に寄る)
double x7 = Math.Pow(2, 3); //2の3乗 = 8。
double x9 = Math.Sqrt(2); //1.41421356...。平方根。
この他にもMath クラスにはSinなどの三角関数や立方根・対数・逆数などいろいろな計算機能があります。
Math クラス (System) | Microsoft Learn
次の回では、簡単な計算機プログラムを作ってみます。