講座全体の概要
プログラミング基礎講座の第4回の後半です。講座全体の概要は以下の記事ゼロから始めるプログラミング基礎講座 第1回【講座の概要・目的】をご覧ください。
前半の内容
変数宣言の構文は以下の通りでしたね。
アクセス修飾子 型 変数名[= 初期値]
※「 [ ] 」はその部分が省略可能であることを表す。
前半では上の構文の「アクセス修飾子」について学習しました。今回は「型」について学習します。
前回作成したプログラムのソースコードを再掲しておきます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
namespace BasicCourse4_1.Pages
{
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public int 親のパブリック変数;
private int 親のプライベート変数;
//private int 子の変数を受け取る変数 = 子の変数;
public const string COURSE_NAME = "ゼロから始めるプログラミング基礎講座";
public string Title;
public int CourseNumber;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
int 子の変数;
親のパブリック変数 = 1;
親のプライベート変数 = 1;
子の変数 = 1;
CourseNumber = 4;
Title = COURSE_NAME + " 第" + CourseNumber + "回【変数・定数を理解する】";
//COURSE_NAME = "オブジェクト指向プログラミング講座";
//CourseNumber = "4";
}
}
}
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<h1>@Model.Title の実行結果</h1>
<p>@Model.親のパブリック変数</p>
@*<p>@Model.親のプライベート変数</p>*@
@*<p>@Model.子の変数</p>*@
</div>
型とは
プログラミングにおける「型」とはデータの種類を表します。上記のプログラムでは「int」と「string」という型を指定しています。この2つを含めた、基本的な型を以下に示しますが、よく使うものだけに限定して紹介します。
整数型:
- int
- 値の範囲:-2,147,483,648 ~ 2,147,483,647
- 初期値:0
- 備考:最もよく使う整数型である。
- long
- 値の範囲:-9,223,372,036,854,775,808 から 9,223,372,036,854,775,807
- 初期値:0
- 備考:intでは桁数が不足する場合に使用する。
浮動小数点型:
- decimal
- 値の最大桁数:28~29桁
- 初期値:0
- 備考:小数点を含む数値は基本的にdecimal型を使用する。他にfloatとdoubleという型があるが、最大桁数が小さいため特殊な用途以外には使わない。decimal型の数値は「123m」の様に最後にmを付けて表現する。
論理型:
- bool
- 値の種類:true または false
- 初期値:false
- 備考:ブールまたはブーリアンと呼ぶ。何らかの条件(「aがbより大きい」、「aとbが同じ」等)を満たすかどうかを表す場合に使用される。満たす場合はtrue、満たさない場合はfalseとなる。日本語ではtrueのことを「真」、falseのことを「偽」と言う。
文字列型:
- string
- 値の種類:0個以上のUnicode文字
- 初期値:なし(null)
- 備考:1文字を表す型にcharがあるが、stringは文字列(複数の文字の並び)を表す。通常は1文字であってもstringを使う。意識してcharを使うことはほぼない。文字列の値は「”あいうえお”」の様に、ダブルクォーテーションで括って記述する。また、初期値はnullという状態で、これは「何もない」ということを表す。nullのままで参照するとエラーの原因となるため、必ず値を代入してから使用するように注意が必要。なお、nullとは異なり、空文字列(0文字の文字列)という特殊な値があり、「string.Empty」または「””」と記述する。
変数の宣言時にこれらの型を指定することにより、その後に行える処理が変わってきます。例えば整数型のintや浮動小数点型のdecimal等は四則演算等の数学的な計算が行えます。文字列型のstringでは文字列を結合したり、特定の文字を別の文字に置換したりできます。論理型のboolについては第6回講座の条件分岐で説明します。
※ここで挙げた型はC#の仕様に基づいて記述しています。他の言語では名称や値の範囲、初期値が異なる場合があります。
動的型付けと静的型付け
変数の宣言で指定した型と代入する値の型が一致していない場合はエラーとなります。下の部分のコメントを解除してみてください。
//CourseNumber = "4";
int型の変数に文字列を代入しようとしているため、エラーとなるはずです。
C#では宣言時に型を決定する(静的型付け)ため、プログラムを実行する前からVisual Studio が型に合った処理が行われているかチェックしてくれます。逆に、宣言時に型を決定しない(動的型付け)言語もあり、この場合はプログラムを実行してはじめてエラーがわかります。
- 代表的な静的型付け言語
- C#
- Java
- Go
- C++
- C
- 代表的な動的型付け言語
- JavaScript
- Python
- Ruby
- PHP
静的型付けと動的型付けですが一概にどちらがいいとは言えません。ただし、動的型付けは型を指定しないからといって、型の概念が無いわけではありませんので注意が必要です。
変数a= 1;
変数a += "回目"
動的型付け言語で上記の様なプログラムがあった場合、変数aに数値の1を代入した時点で、変数aはintであると決定されます。次に文字列を結合しようとしていますが、int型に対して文字列の結合は行えないためエラーとなります。動的型付けとは、あくまで型をあらかじめ決めなくて良いだけで、型がないわけではありません。
傾向として、大規模システムのプログラミングには静的型付け言語が好まれ、比較的小規模で実行時のエラーがある程度許容されるようなシステムのプログラミングには動的型付け言語が好まれると思います。
ちなみに、私個人的には静的型付けの方が好きです。変数宣言時のコード記述は動的型付けの方が少なくて済みますが、C#等は型を指定することにより、その後のコード記述で自動補完が適切に働くようになるため、結果的に楽に書けますしエラーも少ないです。一般的にはコード記述量が少ないことが動的型付けのメリットとされていますが、Visual Studio と C# の組み合わせであれば、動的型付け言語よりも圧倒的に楽にコードが書けます。その上で、一般的に言われている静的型付けのメリットはそのままあります。一般的に言われているメリット・デメリットはインターネットにたくさん情報がありますのでここでは語りませんが、興味がある方は調べてみてください。
型による処理の違い
型の概念的な説明はここまでとして、ここからは具体的に、型の違いがどうプログラムに影響するかを体感してもらいます。BasicCourse4_1のプログラムを実行してみてください。
変数Titleが”ゼロから始めるプログラミング基礎講座 第4回【変数・定数を理解する】”となっていることが確認できると思います。では、この文字列を編集しているヶ所を確認しましょう。
public const string COURSE_NAME = "ゼロから始めるプログラミング基礎講座";
public string Title;
public int CourseNumber;
public void OnGet()
{
CourseNumber = 4;
Title = COURSE_NAME + " 第" + CourseNumber + "回【変数・定数を理解する】";
}
関連する部分だけ抜粋したものが上のコードです。Titleというstring型の変数にいくつかの文字列を結合して代入しています。string型の値は「 + 」を使うことで文字列を結合できます。int型では足し算、string型では文字列結合が行われるように型に応じて処理が変わります。
ここで、疑問に感じることはなかったでしょうか?
CourseNumberの型に注目してください。int型ですよね。文字列の結合の中に数値が混ざっていますが、実行結果は意図した通り”4″という数字(文字)が結合されています。
これは
+ CourseNumber
の左辺部分の
COURSE_NAME + " 第"
が文字列であるため、CourseNumberの数値「4」が自動的に数字「”4″」に変換されたのです。
この様に、文字列の処理を行っていることが推測される場合は、数値から数字への変換は自動で行われます。逆に、数字から数値への変換は明示する必要があります。int型に変換するには、「int.Parse(変換したい数字)」の様にすれば可能です。以下に例を示します。
string number1 = "4";
string number2 = "3";
string text1 = number1 + " + " + number2 + " = " + (number1 + number2);
string text2 = number1 + " + " + number2 + " = " + (int.Parse(number1) + int.Parse(number2));
これをデバッグ等で実行してtext1、text2の結果を見て、違いを確認してください。数値への変換を明示する必要性がわかると思います。
また、number1、number2に数字以外の文字を代入した場合や、number1、number2の型をintにして初期値に数値を代入した場合も確認してみてください。これで型による処理の違いや、数字を自動的に数値に変換できない理由が理解できると思います。(エラーが発生するケースもあるはずです。エラーメッセージを確認して理由を考えましょう。)
以上が型についての説明でした。
定数について
最後に定数というものを説明して終わりにします。変数と同じようにデータを格納しておくものですが、変数とは少し異なります。今回のプログラムでは以下の部分が定数です。
public const string COURSE_NAME = "ゼロから始めるプログラミング基礎講座";
変数宣言の構文と似ていますが、型の前に「const」を記述することで、定数となります。定数は必ず初期値を代入する必要があり、この後に値を変更することはできません。
同じ文字列や、数値に意味がある場合、例えば3.14という数値が円周率を意味するのであれば、以下の様に定数を定義して使用するべきです。
public const decimal 円周率 = 3.14m;
これにより、円周率を使う数式の中で、3.14を直接記述するよりも処理の意図がわかりやすくなります。また、円周率を間違えて記述するリスクを減らせ、複数ヶ所で円周率を使用していても、定数定義の1ヶ所を修正すれば桁数変更等が容易に可能です。
この様に、値に変化のないものでも、処理の記述部分に直接値を記述せず定数を定義して、その用途や意味をわかりやすくすることが推奨されます。
今回の講座は以上です。お疲れさまでした。
この記事へのコメントはありません。