Microsoftが開発を続け、広く一般的に利用されているC#というプログラミング言語の基本的な使い方を、チュートリアル形式で学ぶことが出来る記事になります。C#はシステム開発の現場でも広く用いられる言語ですので、覚えておくに越したことはありません。
この記事ではプログラミング未経験者がC#の基本を学ぶために必要なC#の歴史から基本的な構文までを一気に書いてみました。システム開発企業における新人研修の最初の1週間くらいの内容に相当するかと思います。ボリューミーですが、ぜひともチャレンジしてみてください。
第1章 C#の基礎知識
C#というプログラミング言語を学んでいきますが、まずは C# の基礎知識的な部分を解説します。C# は未経験者・初心者が一番初めに学ぶのにオススメできるプログラミング言語だと考えていますが、それらは、言語の特徴や歴史、できることなど様々な要因からいえることです。まずは C# の基礎的な知識として以下のトピックを理解していきましょう。
- C#はどんな言語か
- C#が歩んできた歴史
- C#でできること
- C#を学ぶべき理由
C#はどんな言語か
C# はプログラミングに関する環境がきれいに整備されているプログラミング言語だと考えています。誰もが知っている巨大IT企業の Microsoftが主要な言語として開発を行っているため、日々進化を続けているプログラミング言語になります。そのため機能が豊富に用意されており、初級者から上級者に至る多様なニーズに答える力を有しています。
C#は開発から20年以上がたった今でも、現役で進化を続けている稀有なプログラミング言語でもあります。また、Microsoftはより広く様々な人が C# というプログラミング言語を使えるように方針を決めているため、Windowsに特化したものだけでなくなってきているのも特徴の一つです。
こうしたMicrosoftの意向により、年々、C# の活躍の場が広がってきていると感じています。C# は世界的にも大きな発展を遂げたプログラミング言語であるC 言語の直径子孫であり、世界最大規模で使用されているJavaというプログラミング言語の特徴も兼ね備えています。
そして何よりも初心者にもおすすめできる理由は、開発するための環境をかんたんに用意することができるという理由もあります。Microsoft が提供している C# の開発環境に Visual Studio というものがあり、このアプリケーションをインストールするだけで C# を開発する基礎的な環境が整います。この Visual Studio はこれまでに多くのプログラマーが利用しており、長年の実績に支えられている優秀な開発環境です。
ここまで説明してきたことをまとめると、C# は Microsoft が主要なプログラミング言語として開発を行っている、様々な機能を有しているプログラミング言語であります。そうした背景があるため、筆者は個人的に未経験者にとって取り組みやすいプログラミング言語であるとしています。
C#の歴史
C# というプログラミング言語について解説してきました。次は C# というプログラミング言語がどのように発展してきたのかをみていきます。すこし専門的な話が混じっているので、今は詳しく知る必要はないのかもしれません。理解がすすんだ時に改めて戻ってきてもよい内容になります。
C系言語の直径の子孫となるプログラミング言語になります。C言語が一般的だった時代に「オブジェクト指向」の概念が組み込まれて、C++ というプログラミング言語が発明され、技術的に大きな進化を遂げました。その一方でC++は技術者自身が様々な処理をする必要がありました。特にメモリ管理がエンジニアを悩ませる種となっていったのです。そのころ、オブジェクト指向の思想のもとでサン・マイクロシステムズという企業がJavaという言語を開発しました。
C++でエンジニアにとって頭の痛かったメモリ管理の問題を自動で行ってくれる「ガーベジコレクション」が組み込まれていました。この言語は今でも人気の言語の一つで、聞いたことのある人もいるかもしれません。C++からJavaへと発展を遂げる一方で、アンダース・ヘルスバーグという技術者が C# という言語を開発しました。このC# は Windows の共通フレームワークである .Net Framework と親和性が高いので C#をコンパイルし、実行することができます。
この C# は「オブジェクト指向」を継承し、Javaに組み込まれていたガーベジコレクション機能も搭載していました。これまでに開発されてきた様々なプログラミング言語から良い部分を取り込んでいくことで、使いやすいプログラミング言語へと進化してきているのです。C# は Microsoft が開発した .Net Framework との親和性が高いため、 Windowsの世界的な普及と共に広がっていきました。
最近になって Microsoft はより広く一般的に利用されることを想定しており、「.Net Core」というフレームワークも誕生させています。このフレームワークは .Net FrameworkをWindows環境以外で動作させるようにリリースされたものです。
このフレームワークの普及により、WindowsだけでなくLinuxやmacOSでもアプリケーションの開発ができるようになりました。この大きな第一歩は開発から20年以上が経過した C# がより進化した瞬間とも言えるでしょう。Windows上で成熟を重ねてきたC#は、さらなる活躍の機会の待っているプログラミング言語の一角ともいえます。
このような歴史から、 C#を学んでおくことは、今後のプログラマーとして歩む道程の第一歩として最適であることが分かります。何よりもMicrosoftが開発を強力にサポートしているからです。また .Net Coreの誕生により、環境に依存しない自由なプログラミング言語へと進化を遂げています。C#で基礎を固めておくことで、その他の様々なプログラミング言語の学習にも役立つことになるでしょう。
C#でできること
ここではC# を使って出来ることを紹介していきたいと思います。C# はこれまでにも書いてきている通り、年々活躍の場を広げていると感じています。より様々な分野に対して応用できるようになりました。興味のある分野があるかもしれませんし、それがきっかけで C# を学び始めるのも十分な動機だと思います。
まず初めにあげておきたいのが、WindowsForm アプリや WPF といったフレームワークを使用した、デスクトップアプリが容易に構築できるのが C# の特徴です。デスクトップアプリはサーバーといったものが必要にはならず、パソコンだけで動くのでサッと作れる手軽さがあります。もちろん商用で使うような複雑なアプリケーションも構築できます。アプリ開発の最初のステップとしてオススメですね。
またASP.NETという Microsoft がサポートしているシステムを利用することでMVCや MVVM といったパターンを利用したWebアプリの構築も行うことができます。将来的にWebアプリケーションの開発などに携わってみたいという人にとっても、C# を学ぶことは有意義な時間になるはずです。過去の案件ではWebアプリケーションの開発経験もあります。
それ以外にもスマートフォン向けのアプリケーションも開発することができます。これまではJavaかSwiftと開発の相場が決まっていましたが、それを切り崩しにかかっているのが C# をベースとした、 Xamrine というフレームワークです。いつのまにはか C# は AndroidやiOSによらないスマホアプリの開発ができるようになりました。さらには C# を使ってゲームの開発も行うことができるようになっています。 Unityというゲームエンジンが C# をサポートしているため、 C# を学んでいくことで将来的にゲームを開発するなんてこともできるかもしれません。
こうやって見ていっても C# は万能なプログラミング言語であることがわかります。プログラミングを使ってやりたいことを実現するための第一歩になりそうだという感じがしてきませんか?
C#を学ぶべき理由
私がC#を一番初めに学ぶべきプログラミング言語だと考えているのは、 C# が初心者にとって扱いやすい言語であり、かつ将来的な需要が十分に見込まれる言語だと思っているからです。 C# は開発から20年以上経っているので、プログラミング言語の中では、古株と呼んでも過言ではありませんが、これまでの成長の過程において、ほかのプログラミング言語のいいところをたくさん取り込んできた経緯がありますし、日々アップデートを重ねている印象もあります。
様々なプログラミング言語から良い部分を組み込んでいるということは、プログラミング言語として洗練され、とても扱いやすいということでもあります。「扱いやすい」というのはプログラミング学習において重要な要因だと考えているため、C#は最適な学習対象といえるでしょう。
Microsoftが開発し続けているプログラミング言語である以上、世界中で標準的に使用されるプログラミング言語であることが裏付けされていますし、前項にもでも書いている通り、Webアプリケーションからゲーム、スマートフォンアプリなど応用範囲が極めて広いことも魅力です。「扱いやすいプログラミング言語であること」そして、「今後も安定的な需要が見込まれるプログラミング言語」という2つの要素から、 C# は未経験者にとって学んでおいて損のない経験になると思っています。
第2章 プログラミングの準備
それでは本格的にプログラミングに取り組んでいきますが、そのためには「開発環境」というものが必要となります。これまでにも登場していますが、 C# では Visual Studio と呼ばれる開発環境が良く使われています。まずは Visual Studio をダウンロードするところから始めましょう。
学習の進め方
本書では「コンソールアプリケーション」と呼ばれる、最もシンプルで簡単に作れるアプリケーションを作りながら C# の基本的な文法をハンズオンで取り組んでいきます。そのため、できれば一緒にアプリケーションを作りながら学んでいくことをオススメします。
Visual Studioのダウンロード方法
本書では Microsoft が開発を行っているアプリケーションの開発環境である Visual Studio というアプリケーションを使用して学習を進めていきます。まずはプログラミング学習を進めるための準備として Visual Studio をインストールしていきましょう。以下のURLからダウンロードができます。
色々な種類がありますが、選択するべきはVisual Studio Community(コミュニティー)という無料バージョンです。無償版ですが機能は十分すぎるほどなので、気にせずにインストールをしていきましょう。
インストールする際に気を付けなければならないのが、以下の画面のように「ワークロード」という画面が出てくるときに選ぶべきものです。本書では「.NET デスクトップ開発」にチェックを入れてインストールボタンを押下してもらえればOKです。
Visual Studio をインストールすることで色々なことができるようになります。最初は時間が掛かってしまいますが、本書を手に取ってプログラミングを学ぼうとしている気持ちを忘れずにしばし待機しておきましょう。
インストール方法に不安のある人はネットで「Visual Studio インストール」と検索すれば、丁寧な解説でインストール方法を紹介しているブログなどをたくさん見つけられるので参考にするとよいでしょう。プログラミングを学ぶと「分からないこと」を探すことは日常ですので、「検索して参考にする」に少しでも慣れておくことをオススメします。
コンソールアプリケーションの作成方法
先ほども少しだけ触れましたが、本書では Visual Studio で作成できる「コンソールアプリケーション」を作成しながら C# の学びを進めていきます。ここでは、そのために必要な「コンソールアプリケーション」の作り方を解説していきます。
まずはこれから作成していくアプリケーションをまとめるフォルダを作成しておきます。デスクトップで右クリックをして、「新規作成」から「フォルダ」を選択してください。
作成するフォルダの名前は特に指定はありませんが、プログラミングだとわかりやすい名前だと良いんじゃないかと思います。ここでは「cs-basic」としてフォルダを作成しています。ほかにも「App」や「dev」といった名前を付けても良いかもしれません。
基本的にここで作成したフォルダ内に作成していくアプリケーションを置いていきます。最終的にはフォルダごと他の場所に移動して問題ありません。いまはソースコードの置き場所をわかりやすくするためにデスクトップに配置しています。
それでは、ここからアプリケーションを作成していきます。 Visual Studio を使いながら進めていきますので、ダウンロードがまだの人は先ほどのページに戻って、ダウンロードを行ってください。まずは Visual Studio を立ち上げましょう。立ち上げると以下のような画面になると思います。
右下の「新しいプロジェクトの作成」を選択してください。
すると以下のような画面になります。
上にある「テンプレートの検索」という項目に「コンソール アプリ」と打ち込みましょう。すると検索結果が以下のように表示されます。
この様々な中から「コンソール アプリ」の題で「Windows、Linux、macOS 上の .Net Core で実行できるコマンドラインアプリケーションを作成するためのプロジェクト」と書かれたものを選択して、右下にある「次へ」をクリックしてください。
すると「新しいプロジェクトを構成します」という画面になります。
ここでは、プロジェクト名に「App01」と入力し、場所の項目は横の「…」を押下して、先ほどデスクトップに作成したフォルダを選択します。ソリューション名はプロジェクト名を入力すると一緒に変わりますので変更はしなくて大丈夫です。
ここまで出来たら画面の右下にある「次へ」を押下しましょう。「追加情報」の画面が現れますが、ここは特に変更する必要はありません。そのまま右下にある「作成」をクリックして先に進みます。
少し時間がかかりますがコンソールアプリが問題なく作成されると以下のような画面に切り替わります。これが開発環境と呼ばれる Visual Studio の基本的な画面です。
Visual Studio をダウンロードしたばかりですと、背景色が白色になっているかもしれませんが、筆者の環境は黒背景に変更して使用しています。色を変更したい方は、上のメニューバーにある「ツール」から「テーマ」、「濃色」を選択してみてください。ほかにもいろいろなテーマが容易されているので、好みに応じて変更してみるのも良いと思います。
また Visual Studio で使われるフォントを変更したい場合は、上のメニューバーの「ツール」から「オプション」を選択してください。
すると以下の画面が表示されますので、「環境」を開いて「フォントおよび色」を選択してみましょう。フォントという項目がありますので、好きなフォントに変更することが可能となります。筆者は Consolas というフォントを好んで使っていますので、よかったら使ってみてください。インターネットで「プログラミング フォント」などのキーワードで検索してみるのも楽しいと思います。
閑話休題。本題に戻りますが、アプリケーションを作成するとフォルダ内にアプリケーション一式が作成されているのがわかると思います。先ほどのフォルダを確認してみると 「App01」というフォルダが作成されています。
これは先ほどのアプリケーションの作成画面でプロジェクト名を App01 と入力しているからになります。アプリケーションは「プロジェクト」単位でまとまっており、プロジェクトの情報を管理しているのが「ソリューション」と呼ばれるものです。
App01 フォルダを開いてみると下のほうに App01.sin というファイルがあると思います。これが「ソリューションファイル」と呼ばれるもので、プロジェクトの構成を管理するファイルです。
一度、Visual Studio を右上の×ボタンで閉じてみて、この App01.sin と書かれたファイルをダブルクリックしてみてください。Visual Studio が自動で起動され、アプリケーションが立ち上がると思います。Visual Studio を閉じて、改めて再開したい場合は、このようにソリューションファイルから行うことができるので覚えておいてください。
アプリケーションを起動する方法
App01 が作成できたので、早速、作成したアプリケーションを起動してみましょう。Visual Studio で作成されたデフォルト状態でも、アプリケーションとしては意味のあるものになります。Visual Studio が起動して App01 が開かれている状態で上にある「▶ App01」のボタンを押してみましょう。
しばらく待つと、以下のような黒い画面が自動的に起動すると思います。
これが「コンソールアプリケーション」になります。黒い画面を「コンソール」と呼んでいて、コンソールを使ったアプリケーションなので「コンソールアプリケーション」なのです。画面の上のほうに「Hello, World!」と書かれていますが、これだけでも十分なアプリケーションです。何かキーをたたくと画面が終了します。
以上、アプリケーションを作成して、実際に起動してみるまでを解説しました。これだけでも十分に大変だったかもしれませんが、プログラマーの多くは誰しも、この「Hello, World!」アプリケーションからスタートしています。ここがプログラミングを学ぶスタートラインと言えるでしょう。
第3章 コンソールアプリの基本
コンソールアプリの準備
第2章ではコンソールアプリケーションを作成して、これから始まるプログラミング学習の準備を行ってきました。ここからがプログラミング学習のスタートということになります。まず初めはコンソールアプリケーションを使って、コンソールに文字を出力することから始めていきます。
早速ですが前章の復習として、プロジェクト名を「App02」としたコンソールアプリケーションを作成してみましょう。うまく作成できるとフォルダ内に App02 の新規フォルダが作成され、中にアプリケーションに必要なファイル一式が用意されます。
うまく作成できたでしょうか。Visual Studio を開いてみると以下のような記載がされています。まずはこれをいろいろと使ってコンソールで遊んでみましょう。
コンソールに文字を出力する
作成した App02 は以下のようになっていると思います。これはVisual Studio がデフォルトで用意してくれた、いわばテンプレートのようなものです。以下のソースコードは、実行してみるとわかる通り、コンソールに「Hello World!」と表示されるアプリケーションでした。
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
すでにお気づきかもしれませんが、C# ではConsoleWriteLite() と記載の括弧内に記述されている内容を、コンソールに表示することができます。このサンプルでいうと “Hello World!” の部分が該当します。では上記を変更して Good Morning, World! と画面に表示されるようにしてみてください。変更出来たら実行して、ちゃんと意図したとおりに表示されているか確認してみましょう。
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Good Morning, World!");
上記のように変更できたでしょうか? コンソールに文字を表示するには Console.WriteLine() と記述して、括弧内にダブルクォーテーションを書き、出力したい文字をダブルクォーテーション内に記述するだけです。あとはアプリケーションがうまくやってくれます。
さてもう一つコンソールに文字を出力する方法があります。それは Cosole.Write() というものです。Console.WriteLine() との違いは、出力後に改行されるかどうかという点にあります。Write() のほうは単純に出力されるだけで、WriteLine() は出力後に改行されます。App03を作成して、以下のコードを書いてみましょう。
Console.Write("Hello");
Console.Write(",");
Console.Write(" ");
Console.Write("World");
Console.Write("!");
もともとあった記述はすべて削除して、上記のソースコードに書き換えてもらえれば大丈夫です。実行をしてみるとConsole.WriteLine() を使った時と同じような出力内容になると思います。Write() の場合は改行されないので、同じ行内に文字を続けて記述することができるようになるのです。
コンソールから文字を受け取る
前項ではコンソールに対して文字を出力する方法を学習しました。ここでは、その逆の「コンソールから文字を受け取る方法」を解説していきます。早速ですが新規のアプリケーションを作成していきます。プロジェクト名を「App04」にして始めていきましょう。
string input = Console.ReadLine();
Console.WriteLine(input);
少し見慣れない記号 string がありますが、これについては次章で取り組んでいくので気にしないようにしてください。文字を受け取るには Console.ReadLine() を使用します。最後の ; を忘れないようにしてください。
Console.WriteLine は「コンソールの一行に対して文字を出力する」でしたが、Console.ReadLine は「コンソールの一行の文字を読み込む」に該当します。コンソールアプリを実行して、適当に文字を入力してエンターキーを押してみてください。次の行に入力した文字がオウム返しのように出力されるはずです。
コンソールアプリの基本としてはここまでで十分になります。文字の出力方法と読込方法について学んできました。次章からは、ここで紹介した2つの武器を使って C# プログラミングを進めていきます。
練習問題
余裕のある人はいくつか自分でアプリケーションを作成してみましょう。
- コンソールから入力値を受け取って、コンソールに「入力値:」の後に入力した文字を続けて一行に出力させましょう
- 「なにか入力してエンターキーを押してください。」「あなたの入力値は「×××」です」と簡単なやり取りをするアプリケーションを作成してみましょう
第4章 変数の基礎
この章ではプログラミングにおいて重要な「変数」というテーマに触れていきます。
変数の基本的な概念
変数という言葉を聞いたことのある人は多いと思いますが、それがどんな内容だったか覚えているでしょうか?変数は数学を勉強する際によく出てくる単語だったと記憶している人も多いことでしょう。例を挙げると以下のように使われることが多かったと思います。
3 + x = 10
x = 7
上記にあげた x がまさに変数ですよね。変数は「変わる数」と書いています。つまり「分からない数」と言っても良いかもしれません。これは数学のサンプルですが、式に対して「わからない数」の代わりに x という文字を使って一時的な「代わり」をしてもらっていました。
それに対してプログラミングの世界では「変数」は、一時的に「値を格納(代入)する箱」のようなイメージにとらえておくと分かりやすいと思います。一時的に何かしらの値を格納しておいて、必要になったら中身を取り出して使うイメージです。変数を使ったプログラミングをしてみましょう。新規のアプリケーションを作成して App05 として以下を記述してみましょう。
string greeting = "Hello, World!";
Console.WriteLine(greeting);
実行してみると、コンソール画面上に Hello, World! と表示されたと思います。あれ?と気が付いた人はさすがですね。これまでは Console.WriteLine(“Hello, World”!); と直接的に書いていましたが、今回のサンプルでは Console.WriteLine(greeting); としてますが、コンソール画面に表示される文字は同じでした。
先ほど変数は「値をいれるような箱のようなもの」と解説しましたが、まさにその例といえると思います。変数 greeting に対して “Hello, World!” という値を一時的に格納しているのです。最初の行では greeting という名前の箱に “Hello, World!” という値を格納しなさい、という命令をしているのです。
プログラミングでのイコール記号
変数を語るうえで外せない話題についてもう一つ触れておきます。それは「イコール」の意味についてです。未経験者に対してプログラミングの新人研修を行っているときに、よく勘違いする人がいるので覚えておいてほしい内容です。
イコール記号(=)は数学においてたくさん触れてきたと思います。たとえば以下のような数式を考えてみます。
x + 10 = 15
上記の内容は最終的に x = 5 と導きだせますが、この時のイコール記号に込められた意味合いは「x は 5に等しい」というものでした。左辺と右辺が等しい、等価であるという意味でイコール記号を使っていました。「xは5であり、5はxでもある」ということです。
それに対してプログラミングの世界ではイコール記号の使い方が数学とは少しだけ違います。数学の世界では、イコールを挟んだ左辺と右辺は「同値である」というメッセージでしたが、プログラミングの世界では「左辺に右辺を代入する」という意味になります。
string greeting = "Hello, World!";
という先ほどのサンプルでは、変数 greeting に足して “Hello, World!” を格納するという命令を出しているというように記述しました。変数は「値を格納できる箱」のようなものという例えを考えると、「箱に値を詰める」すなわち「代入する」という言葉がピッタリになります。
未経験はこのイメージを持っていないために、イコールの意味を混乱して捉えてしまうことがあります。変数 greeting は “Hello, World!” であり、“Hello, World!” が greeting であるというのは間違いです。あくまでも変数は「箱」のようなものなので、「値そのものと同値である」とは言えないのです。どちらかいうと「greeting という箱の中に “Hello, World!” が入っている」というイメージが正しいのです。
変数の使い方
前項までに変数のイメージについて解説したので、 C# の変数を使うときの基本を解説します。 C# では変数を使うときに「変数を使います」と明言する必要があります。先ほどの例でいうと「string greeting = 」の左辺側「string greeting」の部分に当たります。
string とはなんだろう?と疑問に思った人もいるかと思いますが、ここでは「文字列」とだけ覚えておきましょう。これについては後述しますが、データには「種類」に近い考え方があり、string もその一種だということです。詳細には「文字列型」というものになりますが、今はそこまで気にしなくていいです。
さて、変数を使うには「変数を使います」と明言する必要があり、これを「変数の宣言」と呼んでいます。変数を使う時の宣言にはデータの種類も記述する必要があり、さきほどの例では string(データの種類)の greeting(変数名)を使いますという宣言をしていることに該当します。またイコール記号は「代入」を意味するので、変数の宣言に続けてイコールを続けて、代入したい値を設定することも可能です。
(変数の種類)(変数名) = (初期値);
上記の公式に当てはめて考えると string greeting = “Hello, World!” という一行は、「文字列を設定できる greeting という変数を用意して、 “Hello, World!” という文字列を設定する」という処理を記述しています。変数の宣言の後にイコールを続けて値を代入することを「変数の初期化」とも呼びます。
変数の再代入
変数の使い方を確認しました。変数は値を一時的に格納できる箱のようなもので、変数を使うには宣言が必要でした。そのあと値を代入することができます。また変数には「値を再代入することが可能」です。再代入とは作成した変数に対して、同一の種類である場合は再度別の値を代入することです。新しいアプリケーションを作成して App06 を作成してみましょう。
string greeting = "Good Morning!";
Console.WriteLine(greeting);
greeting = "Good Evening!";
Console.WriteLine(greeting);
上記のサンプルでは、変数 greeting に対して “Good Morning!” を代入してコンソールに出力したあと、さらに “Good Evening!” と再代入してコンソールに出力しています。順番にメッセージが出力されているため、変数の再代入がなされていることがわかります。
とはいえ、むやみに変数の再代入を使うことは良いこととは言えません。今回はシンプルなアプリケーションなので、再代入しても迷うことがありませんが、もっと複雑なアプリケーションになりソースコードが物凄く長いものになったとしたら分かりづらくなります。
こういう場合は変数を別に定義して、それぞれ異なる変数として値を保持しておくほうが賢明です。変数は greeting といった抽象的な名称よりも、もっと具体的な名称のほうがわかりやすくてお勧めです。greetingInMorning や greetingInEvening といった変数名にしておくほうがわかりやすいですよね。App06 を以下のように書き換えてみましょう。
string greetingInMorning = "Good Morning!";
Console.WriteLine(greetingInMorning);
string greetingInEvening = "Good Evening!";
Console.WriteLine(greetingInEvening);
上記のようにして、変数名に意味を持たせるほうがぐっと理解が深まる感じがしますね。geetingInMorning は朝の挨拶ですし、greetingInEvening は夜の挨拶になるので、変数名と値の意味が合致するので、ほかの人が読んでも理解しやすいと思います。
少し話題がそれましたが、変数の再代入にはルールがあるので言っておきます。一つ目は再代入するときは「種類の記述は不要」であること、二つ目は異なる種類のデータは代入できないということです。
変更前の App06 には greeting = “Good Evening!” とあったように、最初に変更を宣言したときに書いていた string がありませんでした。これが「種類の記述が不要」という意味です。また再度代入するときは同一の種類のデータしか再代入しかできないため、再代入の値は “Good Evening!” となっていました。文字列には文字列を、数値には数値といったようにデータの種類が異なると「別物」として扱われるので注意が必要になります。
第5章 データの型
前章では変数の基本な知識について解説しました。変数とは何かについて学ぶことができたと思います。その中で string というキーワードが出てきており、string は「文字列である」という内容に触れてきました。データの型という概念に相当します。
この章ではプログラミング学習においても重要な知識である「型」について学んでいきます。特に C# はデータの扱い方がより厳密なプログラミング言語になるので、しっかりと理解しておきましょう。
概要:データの型とは
前章で変数を学習した際に、変数を使用する時は「データの種類」も一緒に宣言する必要があると解説しました。「データの種類」というのが「データの型」であり、一般的には「型」と呼んでいます。まずは全体的なイメージをつけるために、「型」についてざっと見ていきます。この章で扱うのは以下の型になります。
キーワード | 型の意味・概要 |
string | 文字列を扱うことのできる型 |
int | 数値(整数値)を扱うことができる型 |
double | 小数点などを含めた幅広い数値を扱うことができる型 |
bool | 真偽(True / False)を扱うことができる型 |
string についてはすでに出てきていますが、それ以外にも様々な型があります。本当はもっとたくさんの型があるのですが、本書では上記のみをいったんは解説していきます。「型」とはデータの種類に該当するので、宣言した変数が「どのようなデータを扱っているのか」という目印にもなります。
string 型
これまでも出てきた「文字列」は string型と呼ばれています。厳密にいうと「文字」が連なって文章のようになっているデータを表すのが string 型になります。Hello World! という文字列は、H や e 、l 、o といった個別の文字が複数に組み合わさっているデータです。文字が列のようになっているので文字列になります。
文字列型は string というキーワードを使用して明示的にデータの種類を表し、ダブルクォーテーションで挟まれた部分を文字列のデータとして扱うことができます。ダブルクォーテーションは、文字列であることを分かりやすくするためにあると思っておけば良いかと思います。
これまでにstring 型のサンプルもいくつか作ってきているので、ここではサンプルコードは不要かと思います。不安な人は各自で復習をしておきましょう。
Int型とdouble型
数値を扱うときに使用するのが int 型と呼ばれるものです。それ以外にも数値を扱う型として flout や double といった型もあります。ここでは int 型と double 型について学習します。
int 型は整数値を扱うことができる型なので、小数点の値を格納するような変数には使用することができません。その点、double 型は小数点も扱うことができ、int 型よりも幅広い数値が使用できます。サンプルを作成してみましょう。
int number = 5;
Console.WriteLine(number.ToString());
double smallNumber = 0.005;
Console.WriteLine(smallNumber.ToString());
上記のサンプルはint 型の変数と double 型の変数を宣言して、それぞれに値を格納してコンソールに出力するサンプルです。変数 number や smallNumber をコンソールに出力する際に .ToString() と付いていますが、これは「型変換」と呼ばれるものです。
コンソールに出力するには文字列を渡す必要があると、これ間にも触れてきていますが、number や smallNumber は数値型でした。そのため数値型から文字列型に変換する必要があります。そこで使用するのは .ToString() です。「文字列にする」は文字を読んでそのまま、という感じですね。
本書では主に int型を主に使うことを想定しています。int型の格納可能数値の範囲は -2,147,483,648 ~ 2,147,483,647と十分に広いので、基本的な計算に十分対応できます。小数点が発生するような場合はint型を使用すると情報(小数点以下)が落ちるので、そういう場合は double 型を使用していきます。
bool型
最後に触れたいと考えているのが bool型 と呼ばれる型になります。「ブール型」と呼んであげてください。データの種類の正式名称は boolean(ブーリアン)ですが、C# では bool として使用されています。
bool 型が格納できるのは 「真」および「偽」の2種類になります。bool 型の変数が主に使われるのは「真偽を判定する場合」です。あまり聞きなれないと思いますが、C#では true か false の格納が可能です。
真偽の判定というのは、命題に対して「正しい」か「正しくないか」を判断することを言います。例えば「入力値は5より大きいか?」という命題があったとして、入力値が3であれば、3は5より小さいので「偽」になります。それに対して入力値が7だった場合は、7は5より大きいので「真」の値を持つことができます。
ここではサンプルアプリケーションは作成しないことにします。というのも、ここから先に「分岐」という内容を学ぶので、その時に嫌というほど触れるからです。したがって、今の段階では「true と false を格納できるbool型があったな」と覚えてもらえれば十分です。
第6章 計算方法のいろいろ
コンピューターは計算機の一種なので色々な計算ができます。ここではいろいろな数値計算の方法と、文字列の計算方法(結合)に触れていきます。どれも重要な内容なのでしっかりと覚える必要があります
数値計算をする方法
C# で数値を計算するにはいくつかのキーワードがあります。ざっと挙げると以下のようになります。基本的な計算は普段から私たちが使うものと一緒です。剰余という聞きなれない言葉がありますが、これについては後ほど改めて扱います。
記号 | 内容 |
+ | 足し算 |
– | 引き算 |
* | 掛け算 |
/ | 割り算 |
% | 余剰(余り) |
早速ですが、サンプルのアプリケーションを作成して、どのように計算するのかを確認していきましょう。
int add = 10 + 5;
Console.WriteLine(add.ToString());
int subtract = 10 - 3;
Console.WriteLine(subtract.ToString());
int multiply = 3 * 5;
Console.WriteLine(multiply.ToString());
int devide = 20 / 5;
Console.WriteLine(devide.ToString());
int mod = 11 % 5;
Console.WriteLine(mod.ToString());
主要な計算方法すべてを一気に記載しています。実行してみると、コンソール画面には以下のように出力されているのを確認できるかと思います。
15
7
15
4
1
動きを簡単に解説すると、それぞれの計算結果を変数に格納して、それらを文字列に型変換してコンソール画面に出力しています。変数名はわかりやすいように計算方法にしています。
最後の int mod = 11 % 5; について解説します。コンソールに出力されている値を確認すると 1 が表示されています。これは11 を 5 で割った余りが表示されています。 11 ÷ 5 = 2 … 1 になるので、余りに該当する 1 が変数 mod に格納されます。剰余とは「余り」のことを指しています。
また、変数と変数を使って計算を行うことも可能です。変数が数値型である場合に限られますが、変数同士でも上記の方法を使って計算することが可能です。新しいアプリケーションを作成して確認してみましょう。
int numberA = 20;
int numberB = 3;
int add = numberA + numberB;
Console.WriteLine(add.ToString());
int sub = numberA - numberB;
Console.WriteLine(sub.ToString());
int mul = numberA * numberB;
Console.WriteLine(mul.ToString());
int dev = numberA / numberB;
Console.WriteLine(dev.ToString());
int mod = numberA % numberB;
Console.WriteLine(mod.ToString());
変数を2つ用意して、それぞれの演算子を使用して計算を行っています。実行すると以下のようにコンソール画面に出力されていると思います。
23
17
60
6
2
上記の例において「int dev = numberA / numberB;」は「20 / 3 = 6.666666・・・」と続きますが、この結果では「6」となっています。Int 型は「小数」の値を格納できないため、端数が落ちて 6 になってしまっています(6に丸まっている)。数値の計算は以上となります。
文字列計算(結合)
次は文字列を使った計算をやっていきます。とはいえ、文字列は引き算や割り算することはできず、基本的に加算(足し算)はできます。文字列と文字列を足し算することを、「文字列結合」と呼んでいます。
文字列を簡単に表現すると「文字列をくっつける(合成する)」という感じです。実際にサンプルを見てみると分かると思いますので、早速 App10 を作成していきましょう。
string hello = "Hello";
string space = " ";
string world = "World";
string exclamation = "!";
string morningGreeting = hello + space + world + exclamation;
Console.WriteLine(morningGreeting);
上記のアプリケーションを実行してみると、以下のようにコンソールに表示されるはずです。
Hello World!
いくつかの変数を定義して、それらをくっつけて一つの文字列にさせました。文字列結合とはこのように、足し算の記号を使用して文字列をどんどんつなげていく(結合)していくことです。まさに文字列を足し算していくわけです。何かの条件でメッセージを切り替えたり、文言を一部だけ変えたりするようなときに使えるので覚えておきましょう。
第7章 分岐の使い方
第6章ではプログラミングで必須な「分岐」というものを扱います。分岐とは「分かれる」という意味です。私たちは日常生活でも様々な分岐に遭遇しています。様々な選択肢のうちから選び取るような状況です。
- 降水確率が70%だったら傘を持っていこう(70%未満なら傘を持って行かない)
- 卵があったらオムライスを作ろう(卵がなければ他の何かを作る)
- 信号が青だったら進もう(それ以外なら止まる)
といったように、日常生活では様々な条件をもとに、それらを満たす・満たさないで選び取る内容を変えることがあります。こうした状況・行動を分岐とよんでいます。
if 文の概要
C# で分岐を扱うときは if 文という形式を使います。if とは英語で「もし~ならば」という条件を表す単語ですが、プログラミングでもまさに同じような状況で使います。先ほどの3つの例でも「降水確率が70%だったら」「卵があったら」「信号が青だったら」という条件がありました。
分岐では条件の結果を真または偽で判定します。第4章で扱ったデータの型の中に bool 型があったと思いますが、まさにbool 型によって判断されます。条件を満たしているか、満たしていないかによって行動を変えるわけです。まずは簡単なサンプルから作ってみましょう。
if (true)
{
Console.WriteLine("真の場合");
}
else
{
Console.WriteLine("偽の場合");
}
if ( … ) { … } という見慣れない表現が出てきました。If ( … ) の括弧の中の条件を満たす場合は if のすぐ下の中括弧内の処理を実行します。上記の場合では「真の場合」という文字がコンソールに表示されます。これは if の横の括弧に直接 true を書いているため、常に if 文の条件を満たしています。逆に言うと、上記の処理では「偽の場合」は絶対に表示されません。
さて、ここから先はさらに if 文について深堀をしていこうと思うのですが、その前に bool 型の変数の使い方、そして条件の判定方法について詳しく解説していきます。条件の判定方法を先にマスターしておくことで、if 文の理解がよりかんたんになっていきます。
条件判定をする方法
if 文は条件を判定して行動を「分岐」させるものだと前項では解説しました。条件を判定するには、そのやり方を学ぶ必要がありますので、まずは条件判定の方法について解説していきます。
条件判定には主に「比較演算子」と呼ばれるものを使います。比較演算子というのは、提示された条件を比較して満たしていたら true になり、満たしていないならば false になる演算子です。以下に覚えておくべき比較演算子の一覧を作成しましたので覚えましょう。
記述方法 | 意味 |
A == B | AとBが同値ならtrue(AとBが異なるならfalse) |
A != B | AとBが異なるならtrue(AとBが同値だったらfalse) |
A <= B | AがB以下ならtrue(AがBより大きいならfalse) |
A >= B | AがB以上ならtrue(AがB より小さいならfalse) |
A < B | AがBより小さいならtrue (AがBより以上ならfalse) |
A > B | AがBより大きいならtrue(A が B より以下ならfalse) |
一覧表だけを見てもわからないと思いますので、コンソールアプリを実際に作ってみて動きを確認していきましょう。App12 を作成して以下を記述して実行させてみてください。
bool isEqual1 = "Hello" == "Hello";
Console.WriteLine(isEqual1.ToString());
bool isEqual2 = "Hello" == "hello";
Console.WriteLine(isEqual2.ToString());
bool isEqual3 = "Hello" != "Hello";
Console.WriteLine(isEqual3.ToString());
bool isEqual4 = "Hello" != "hello";
Console.WriteLine(isEqual4.ToString());
まずは比較演算子の中でも最もポピュラーな「同値判定」の演算子です。上記の表では 「==」 と「!=」の行に該当します。2つの文字である “Hello” と “hello” を演算子を用いて同値かどうかを判定してみました。
“Hello” と “Hello” は同値なので isEqual1 はtrue、“Hello” と “hello” は異なる値なので、「同値であるか(==)」を判定する演算子の下では false となります。また「!=」は「異なる値であるか」の判定なので、“Hello” と “Hello” は同値なので false となり、“Hello” と “hello” は異なるので true となります。
bool isEqual1 = 5 <= 4;
Console.WriteLine(isEqual1.ToString());
bool isEqual2 = 5 <= 5;
Console.WriteLine(isEqual2.ToString());
bool isEqual3 = 5 <= 6;
Console.WriteLine(isEqual3.ToString());
先ほどの一覧の中で3行目の比較演算子を使ってアプリケーションを作成してみました。「<=」は「左辺が右辺以下であるかを」を判定する演算子になります。
isEqual1 は 左辺が5で右辺が4なので条件を満たさないので false とあり、2つ目は左辺が5で右辺が5であるため「左辺が右辺以下」の「以下(左辺が右辺を含む)」条件に該当するので true、3つ目は5は6よりも小さい値なので左辺が右辺よりも小さくなるので true です。
bool isEqual1 = 5 >= 4;
Console.WriteLine(isEqual1.ToString());
bool isEqual2 = 5 >= 5;
Console.WriteLine(isEqual2.ToString());
bool isEqual3 = 5 >= 6;
Console.WriteLine(isEqual3.ToString());
新しいアプリケーションである App14 を作成して、4行目の比較演算子である「>=」を使用したサンプルを作成してみました。
isEqual1 は 左辺が5で右辺が4なので、左辺が右辺よりも値が大きく、条件を満たすため true となり、2つ目は左辺が5で右辺も5であり、左辺が右辺「以上(含む)」という条件を満たすため true となります。3つ目は 左辺が右辺よりも小さいので条件は満たさないため false となります。
5行目と6行目は「<=」と「>=」の比較演算子から「=」の条件を省いたものになりますので、App13 と App14 においてisEqual2 の値が false になります。
比較演算子は if 文を覚える中で絶対に必要な知識であるため、必ず押さえておく必要があります。特に「==」や「!=」といった見慣れない演算子は、いくつか練習して使えるようにしておくと良いでしょう。サンプルでは文字列で比較していますが、数値型やbool型同士でも比較することができます。
if 文の使い方
ここからは if 文を使ったプログラミングのやり方をみていきます。if 文の基本は「条件によって行動を分ける」ということなので、条件の判定がとても重要になります。前項の「条件判定をする方法」をしっかりと理解しておくことが重要です。
まずは if 文の最も基本的な文法である、条件分岐が1つになるパターンです。以下のような記述をしたときは、「条件式」が true である場合は “{ }” で囲まれた部分の処理を実行します。
if( 条件式 )
{
(何かの処理)
}
日常生活でも、例えば「5,000円以上の購入で500円割引!」や「8,000円以上の購入で送料無料!」といった、特定の条件によって何か特典を受けられる場面があると思います。そういったときに使える文法になります。サンプルアプリケーションを作ってみましょう。
int totalAmount = 5100;
if (totalAmount >= 5000)
{
Console.WriteLine("500円割引の対象です。");
totalAmount = totalAmount - 500;
}
Console.Write("合計金額:");
Console.Write(totalAmount.ToString());
Console.Write("円");
上記のようなアプリケーションを作成して、 totalAmount = 5100 ; の 5100 をいろいろな値にして試してみてください。4999 を設定すると「500円割引の対象です。」のメッセージが表示されず、 5000 を設定するとメッセージが表示されるはずです。
totalAmount = totalAmount – 500; の部分は、totalAmount という変数に対して、今の totalAmount から 500 を引いた値を totalAmount に代入するという動きを表しています。いったん変数の中身を取り出して変更し、もう一度、変数として格納するイメージですね。
if ~ else ~ 文の使い方
前項では一番単純な if 文の使い方を紹介しました。よく使うので覚えておきましょう。次に解説するのは「A の場合は○○の処理をして、それ以外は××の処理をする」というようなパターンで使われる if 文の形式を紹介します。文法は以下になります。
if( 条件式 )
{
}
else
{
}
「A の場合は○○の処理をして」の部分は if ( ) { … } の中で行い、「それ以外は××の処理をする」という箇所は else { … } の中で処理を実行します。
たとえば、「5の倍数なら当たりでそれ以外はハズレ」みたいなくじ引きのケースが挙げられるかもしれません。if () { … } else { … } を使用する場面は、大きく分けて条件が2つのグループに分けられる時です。「特定の条件の時と、それ以外」というような分け方の場合に有効です。App16 を作って以下をコーディングしてみましょう。
int userNumber = 25;
if (userNumber % 5 == 0)
{
Console.WriteLine("アタリ");
}
else
{
Console.WriteLine("ハズレ");
}
まさにサンプルで挙げた状況を再現してみました。5の倍数を表すには「5で割った余りが0」という条件を満たせば検証できますので、if 文の条件式に当てはめています。userNumber を初期化している部分を25以外にして試してみましょう。5の倍数やそれ以外の場合で試してみると違いが分かるはずです。
if ~ else ~ の文は 「Aの時とそれ以外」という特定の条件を表現するときによく使う文法なので覚えておきましょう。
if ~ else if ~ else 文の使い方
最後のパターンとして紹介しておくのが if ~ else if ~ else 文と呼ばれるものです。これは複数個の分岐が並列で存在する場合によく使用される基本文法になります。「Aの時は〇〇、Bの時は××、Cの時は△△、それ以外は□□」という場合に使用します。
if( 条件式1 )
{
}
else if( 条件式2 )
{
}
else
{
}
上記の場合では3つの分岐となっていますが、else if (条件式) 何個でも接続可能です。ただし、多くを並列で繋ぎすぎるとコードが読みにくくなり、バグが混在しやすくなるので注意が必要になります。早速、App17 を作成して動きを確認してみましょう。
int yourAmount = 10;
if (yourAmount < 10)
{
Console.WriteLine("10未満の数です。");
}
else if (yourAmount < 100)
{
Console.WriteLine("10以上、100未満の数です。");
}
else
{
Console.WriteLine("100以上の数です。");
}
int 型の変数 yourAmount をいろいろと変更して動かしてみましょう。以下の数で実行してみると処理がよくわかると思います。
- 9
- 10
- 99
- 100
この4つの数字で アプリケーションを動かしてみると、どのように動いているかがわかると思います。たとえば 10 の時は、最初の条件である yourAmount < 10 を満たしませんので、「10未満の数です。」は表示されません。しかし 2つ目の条件である yourAmount < 100 は満たしますので、「10以上、100未満の数です。」がコンソール上に表示されます。
どれか一つでも条件を満たしてif 文の分岐内の処理が行われた場合は、それ以降につながっている分岐には入ることができません。if ~ else で書かれたブロックは、どれか一つが必ず実行される仕組みになっているのです。
第8章 型変換と例外
第4章ではデータの型として、数値や文字列といった基本的な型を紹介してきました。プログラミングを行う上でデータの型は重要になるので、しっかりと理解しておく必要があります。
さて、この章では文字列や数値のデータの型を制限はありますが、双方で変換する方法を学びます。データの型を変換するときは主に画面側から受け取った値を、内部的な処理をするときなどに多用しますので理解しましょう。
数値から文字列への変換
最初に紹介しておくのは数値から文字列に変換する方法です。数値から文字列に変換するのはすでに解説しているので、ここでは復習がてらにサンプルを作成して、思い出してもらえれば十分かと思います。早速、サンプルの App18 を作っていきます。
int number = 100;
Console.WriteLine(number.ToString());
double number2 = 100.105;
Console.WriteLine(number2.ToString());
App18 にて数値を文字列に変換している個所は number.ToString() という部分です。 .ToString() を続けると文字列に変換することができます。 Console.WriteLine(); の括弧の中は文字列を記述しておきたいので、その例にならって数値型である int 型を文字列に変換してコンソール画面に出力しています。
また、2つ目も数値型である double 型を文字列に変換するサンプルになります。double 型も同様に .ToString() を続けることで文字列に変換できます。と、ここまでは前回までに触れている内容になるので、そこまで難しくはないと思います。double 型については初めてでしたが、int 型と同様になるので特に問題はないはずです。
文字列から数値への変換
さて、今度は文字列から数値への変換を見ていきます。これも覚えてしまえばさほど難しくはありません。今回は2つほど変換する方法を紹介しておきたいと思います。まずはサンプルである App19 を作成してみましょう。
string moji1 = "100";
int number = int.Parse(moji1);
Console.WriteLine(number.ToString());
string moji2 = "100.10";
double number2 = double.Parse(moji2);
Console.WriteLine(number2.ToString());
まず紹介しておくのは int.Parse(); と double.Parse(); です。() の中に記述した文字列を数値に変換してくれる処理になります。それぞれ number と number2 を ToString() で文字列に戻してコンソールに出力させていますが、変数としては int number / double number と数値の型の変数に値が格納されています
さて、もうひとパターン同じような処理ができる方法がありますので紹介しておきます。新しく App20 を作成して別のサンプルを見ていきましょう。
string moji1 = "100";
int number = Convert.ToInt32(moji1);
Console.WriteLine(number);
string moji2 = "100.305";
double number2 = Convert.ToDouble(moji2);
Console.WriteLine(number2);
ここで使用したのが Convert.ToInt32(); というもので、括弧の間に「数字に該当する文字列」を渡すとint型の値に変換してくれます。これはdoubleでも同様です。重要なのは「数字に該当する」という部分で、数字以外の文字列を渡してしまうとアプリケーションが落ちてしまいます。
string helloworld = "Hello, World!";
int number = int.Parse(helloworld);
上記のようなアプリケーションを作成して実行してみると以下のような画面が現れるかと思います。
「ハンドルされていない例外」とありますが、これは「例外」と呼ばれるもので「想定外の動きをしています。問題です。」と教えてくれているものです。そのまま F5 キー、もしくは上にある「▷続行」のボタンを押下すると、コンソール画面が以下のようになります。
どちらにせよ「例外」が発生してしまうのはアプリケーションにとって良いことではありません。事前に予測して回避策を練っておくか、例外が発生したときの対応を盛り込んでおくか、のどちらかをアプリケーションに組み込んでおく必要があります。
変換の例外に対応する
さて、前項では変換に失敗して例外が発生した場合に、アプリケーションがどうなるかを紹介しました。変な文字がコンソール画面上に現れたと思います。ここでは例外が発生するのに対して、どのように対応すればいいかを解説していきます。
例外に対応するには大きく分けて2つの戦略があると筆者は思っています。
- 例外になる条件を未然に防ぐ
- 例外が発生してもアプリケーションを落とさない
大きく分けると上記の2件があると思っています。可能な限り例外になる条件を未然に防ぐように努力をしつつ、そのうえで更なる防衛ラインとして2つ目の手法をとるのが一般的な感じがしています。とはいえ、この内容は上級レベルになって、もっと深く学べばよいと思います。
我々が現在、知りえている例外は「文字列を数値に変換するときに、数値になれない文字列で型変換をする」場合の1件です。これをどのように扱っていくか、という話を進めていきます。
例外を未然に防ぐ
例外を未然に防ぐ、というのはどうみても難しいと感じるかもしれません。現在は「文字列を数値に変換するときに、数値になれない文字列で型変換をする」が発生条件ですから、これを逆に考えて「数値にならない文字列は変換させない」ようにして防げばよいことになります。
一つの例としては、数値になれない文字列の場合は「終了します」や「再度入力してください」「正しく入力してください」「正しくないため終了します」といったメッセージを表示してあげたりすればよいかもしれません。上記のイメージからサンプルを作っていきましょう。
Console.WriteLine("数値を入力してください。");
string input = Console.ReadLine();
int converted;
bool isParsed = int.TryParse(input, out converted);
if (isParsed == false)
{
Console.WriteLine("正しくないため終了します。");
}
else
{
Console.Write("入力した数値:");
Console.Write(converted.ToString());
}
少し難しくなってきたかもしれません。今回新しく出てきたのは int.TryParse(input, out converted); という箇所になります。int.Parse() に対して int.TryParse() という処理は、数値に変換できるかを確認する処理になります。
int.TryParse() のカンマで区切られた一つめの値は、コンソール画面から入力された文字列を渡しています。また2つ目の out converted は、直前で定義された int converted に対して値を設定する処理をしています。もし一つめの値として渡した文字列が数値に変換できるものだったら、 bool IsParsed の値は true となり、変換できない文字列の場合は false となります。
この bool 型の変数である IsParsed の値を使って if 文で分岐を作成して、うまく変換できた場合と変換できなかった場合の処理を分けているのが上記の内容となります。isParsed が true だった場合は else で囲まれた処理をするので、int 型の変数 converted の中身を文字列に型変換してコンソール画面に出力しています。
作成したサンプルで 3 と入力した場合と、 a と入力した場合で処理結果が期待通りになっているかもきちっと確認してください。3 と入力した場合は「入力した数値:3」とコンソールに表示され、 a と入力した場合は「正しくないため終了します。」と表示されたかと思います。
と、これまでと打って変わって、かなりプログラミング的な記述内容になってきたと感じるかもしれません。事前に発生するかもしれない例外に対応するには、「発生する可能性をなるべく潰しておく」という視点の切り替えが必要となります。裏を返すと「どのような条件で例外が発生するのかを考える必要がある」ということでもあります。
アプリケーションを落とさない
未然に例外を防ぐのとあわせて対応しておきたいのが「例外が発生しても、アプリケーションをどうにか維持する」という行為です。これは「未然に防ぐ」のとは異なり「予期できないので抜け道を用意する」という最後の手段のような感じがします。こういう場合には try ~ catch ~ 構文というものを使用します。
try
{
}
catch (Exception ex)
{
}
try { } で囲まれた中に処理を記述していき、何かしらの例外が発生したら catch { } の中に記述した内容の処理を行うという意味を表しています。イメージし難いと思いますので、App22 と同様の動きをする App23 のサンプルを作って確認してみましょう。
try
{
string input = Console.ReadLine();
int converted = int.Parse(input);
Console.Write("入力した数値:");
Console.Write(converted.ToString());
}
catch (Exception ex)
{
Console.WriteLine("正しくないため終了します。");
}
catch () の括弧内に記載されている Exception ex については、いったんは無視してもらって構いません。これはこういうものだ、で現時点では良いと思います。興味ある人のために説明しておくと、発生した例外の情報が ex の中に格納されている、というものになります。現時点では詳しく説明はしません。
重要なのは int.Parse() の処理でどんな文字列も「一度は変換してしまおう」という動きになっている点です。先ほどの例では「数値に変換できるか」をチェックした上で変換処理をしていましたが、ここでは少し書き方が異なっていますね。
この場合は、例外を未然に防ぐ前の記述方法と変わりません。しかしながら a と入力してエンターを押下すると、ちゃんと「正しくないため終了します。」が表示されます。これは int.Parse() で例外の発生を検知すると、catch という処理に飛ばされる動きをしていることが理由です。
このように見てみると、try ~ catch ~ は非常に便利に見えますが、どんな例外も拾ってしまい、処理が飛ばされてしまうので要注意です。ちゃんと発生しえる例外を考慮したうえでチェック処理を盛り込み、そのうえでの予防線として try ~ catch ~ を使用するようにしましょう。
本書では「正しく考える」という観点から、「未然に防ぐ」に重点をおいてサンプルを書いていこうと思っています。なので try ~ catch ~ を使用することは、ほとんどのケースでないでしょう。しかしながら「こんな処理があったな」と頭にインデックスを作っておくことが重要なので紹介しました。
練習問題
- 画面から数字を入力させ、その入力値が偶数であった場合は「入力値は偶数です。」と表示し、それ以外は「入力値は偶数ではありません。」というメッセージを出力させてください。例外の場合も考慮してください。
- 2つの数字を入力させ、それぞれ数値に変換し、2つとも変換できたら合計値を画面に表示させましょう。どちらかが数値に変換できなかった場合は「正しくないため終了します。」と画面に表示させて合計値の計算は行わないようにしましょう。(ヒント:入力を受け取る文字列型の変数は2つ用意しましょう)
第9章 コメントと変数名
if 文などを学んできましたが、「少しプログラミングが難しくなってきた」と感じている人もいるかもしれません。そんな人は「コメント」を活用すると頭が整理されやすくなります。この章ではソースコードに処理に影響をしないコメントを書く方法をメインに紹介していきます。
また他人にソースコードをわかりやすくする方法の一つとして「変数名を正しくつける」というものがあります。理解しやすい変数名を付けるコツを紹介していきます。この章は C# を学ぶだけでなく、ほかのプログラミング言語に対しても応用できる重要な内容です。
コメントを書く方法
これまで作ってきたアプリケーションはすべてサンプルとして書いてもらっていましたが、今読み返してみると「どうしてこうしたのだっけ?」と思えてしまうときもあるかもしれません。実際に製品レベルのコードを書いているときも混乱する場面があります。
- どんな考えをもってコーディングをしたのか
- 技術的にどんな選択をしてこの実装を選んだのか
そうしたときに便利なのが「コメント」と呼ばれるものです。ソースコード内にコメントを記述することで「どんな処理にするべきか」を考えながら構想を練ることが可能です。熟練のエンジニアとはいえ、自分が書いたコードすら、半年後には忘れてしまうものなのです。 ソースコード内にコメントを残すメリットは以下のように挙げられます。
- 思考を整理しながら作業することができる
- 未来の自分が現在の自分の思考を理解できる
- 他人がコードを読んだ時の助けになる
一番重要なのは「他人(未来の自分を含め)が読んだ時に、当時に考えたことの理解を助けてくれる」ことです。コードを書いた張本人ですら過去のことを忘れるので、他人にとって解読するのは困難です。そんな時にコメントを活用することで「どんなことを考えたのか」や「どうしてこの処理をしたのか」というポイントを書き残すことが出来ます。
C# では単行のコメントだけでなく、複数行にわたるコメントを記述することもできますので、そのやり方を紹介していきます。コメントのやり方を覚えることで、自分のコードがわかりやすくなるだけでなく、考え方を整理しながらコーディングを組み立てるのに役に立ちます。
//1:単行のコメントはこう書きます
int number = 100; //2:行のあと全部がコメントになります
/*
3.複数行のコメントは
こんな感じで使います
*/
string comment = "Hello, World!";
C# ではコメントを記載するには「//」と「/* */」の2通りの方法があります。1で書いたやり方は行の先頭に // を記載することで以降の内容がコメントとなります。2は 行内に // と書いたところの後すべてがコメントになるサンプルです。3は複数行でコメントを書くときに使用する方法です。
どんな時にコメントを残すのか?コメントに何を残すのか?ということですが、「どうしてそうなったか」や「どうしてその処理をするか」といった「思考の中身」を記述することを筆者はオススメしています。
とはいえ、まずはコメントを記述するように癖をつけるのが先決かなと思っています。特に、将来的にエンジニアとして仕事をしたいと思っているのなら、コメントは絶対に書き残す必要があります。将来的にはコメントの質にもこだわっていく必要がありますが、これはプログラミングを学ぶ過程で洗練していけばよいですので、いまは「コメントを書くこと」を習慣にするようにしてください。
練習問題(第7章のサンプル解答)
- 画面から数字を入力させ、その入力値が偶数であった場合は「入力値は偶数です。」と表示し、それ以外は「入力値は偶数ではありません。」というメッセージを出力させてください。例外の場合も考慮してください。(第7章 練習問題 1)
Console.WriteLine("数値を入力してください。");
string input = Console.ReadLine();
int inputNumber;
bool canConvert = int.TryParse(input, out inputNumber);
if (canConvert == false)
{
// 入力値が数値でない場合は終了する
Console.WriteLine("正しくないため終了します。");
}
else
{
//数値を2で割った余りが0の場合は偶数である
if (inputNumber % 2 == 0)
{
Console.WriteLine("入力値は偶数です。");
}
else
{
Console.WriteLine("入力値は偶数ではありません。");
}
}
コメントをつける練習の一環として、第7章の練習問題のサンプル解答を記載してみました。あなたにとってはどんなコメントが必要でしたでしょうか?重要だと思うコメントを書いて練習していきましょう。
- 2つの数字を入力させ、それぞれ数値に変換し、2つとも変換できたら合計値を画面に表示させましょう。どちらかが数値に変換できなかった場合は「正しくないため終了します。」と画面に表示させて合計値の計算は行わないようにしましょう。(第7章 練習問題 2)
Console.WriteLine("1つ目の数値を入力してください。");
string input1 = Console.ReadLine();
int convertNum1;
bool canConvert1 = int.TryParse(input1, out convertNum1);
Console.WriteLine("2つ目の数値を入力してください。");
string input2 = Console.ReadLine();
int convertNum2;
bool canConvert2 = int.TryParse(input2, out convertNum2);
//1つ目の入力値が変換されていたら、2つ目の入力値を確認する
if (canConvert1 == true)
{
if(canConvert2 == true)
{
//2つの入力値がともに変換されているなら合計を表示
int total = convertNum1 + convertNum2;
Console.Write("入力値の合計は ");
Console.Write(total.ToString());
Console.Write(" です。");
}
else
{
//2つ目が変換できなかった場合のメッセージ表示
Console.WriteLine("正しくないため終了します。");
}
}
else
{
//1つ目が変換できなかった場合のメッセージ表示
Console.WriteLine("正しくないため終了します。");
}
少しコーディングを難しくなっていますが、コメントをつけながら頭を整理していけば問題も解けるはずです。こういう複雑だと思う場合は積極的にコメントを活用していきましょう。
変数名の種類やコツ
変数名を付けるときは英語を使ってつけるのが基本です。そのとき、できるだけ「どんな内容の変数であるか」を意識して名前を付けるようにしましょう。これまでに作成したアプリケーションでも、それなりに工夫した変数名を付けるようにしていました。たとえば、以下のような変数名です。
- canConvert
- convertNum
「どういう意味を持つ変数か」「何のための変数か」がほかの人に理解しやすいように考えるように気を付けていきましょう。変数名を付けるときは動詞を先に付けると意味が分かりやすくなります。何か処理をするような場合は「do~」「get~」「set~」「create~」など、「is~」「can~」は状態や可否などを表すときなどに使うと便利です。
また、変数名にはいろいろな「ケース」があります。いわゆる「書き方の種類」みたいなものですね。プログラミング言語やどういう用途で使うのかによって変わってきますが、以下に代表的な種類をまとめておきました。
CamelCase(キャメルケース)
- 最初の単語はすべて小文字
- 単語の先頭は大文字、頭以外は小文字
- 例:canConvert
PascalCase(パスカルケース)
- 語の頭は大文字、頭以外は小文字
- 例: CanConvert
SnakeCase(スネークケース)
- すべての単語は大文字
- 単語と単語の間はアンダースコア
- 例:CAN_CONVERT
今の段階ではCamelCaseを使用するようにしていれば十分です。変数名の書き方にも種類があったな程度で問題ありません。より難易度の高い内容に移っていったときにパスカルケースなども使うのですが、必要になった段階で改めて解説をしたいと考えています。
第10章 繰り返し文の使い方
ここからはプログラミングにおいて if 文と同じくらい重要な「繰り返し文」について学んでいきます。繰り返し文を学ぶことで、特定の処理を何回も繰り返す処理を行うことができ、たくさんのデータを取り扱うことができるようになります。当章では以下のトピックを学びます。
- for 文
- while 文
繰り返し文は他にも書き方がありますが、もっとも基本となる2つの文法を解説します。どちらも重要なので、この章を通してしっかりと学んでください。前章で学んだソースコード内のコメントも、「必要だと思う箇所」で「必要だと思う内容」で「自由」に記述してみてください。最初はたくさんコメントを書いて慣れていきましょう。
for 文の使い方
まずは for 文のサンプルを早速作成していきたいと思います。for 文は文法の解説をしてもわかりづらいので、実際に書いて動かして学んでいくほうが理解はしやすいと筆者は考えています。早速、App27 を作成していきましょう。
for (int i = 1; i <= 10; i = i + 1)
{
Console.WriteLine(i.ToString());
}
コンソール画面上には1 から 10 の数字が表示されたと思います。これが「繰り返し文」と呼ばれるものです。「コンソールに数字を表示する」という処理を繰り返して実行するように記載をしています。
for文は3つの要素で構成されています。左から int i = 0 / i <= 10 / i = i + 1 とセミコロンで区切られているのでわかりやすいかと思います。そこに記載されている 3 つの要素は以下の2つを表現しています。
- int i = 0:開始条件
- i <= 10:繰返し範囲
- i = i + 1:増加条件
一番左に記述されている int i = 0 は、どの条件から for 文を開始するかの条件を記述しています。int i = 1 と書いているので1から始まります。開始条件に int i = 0; と書いているので for 文の中で使用できる変数 i が定義されています。
また2つ目の i <= 10 の部分は、「iが10以下の場合は繰り返します」という、繰り返しを継続する条件を示しています。最後の i = i + 1 の部分は for 文が一周まわった時に、どんな処理をするかの条件を記載しています。ここでは「i に 1 を足して新しい i として代入する」と記載されていますね。
まとめると、この繰り返し文は「 i の値が1から始まり、1周するごとに1ずつカウントアップされ、i の値が10以下の間だけ繰り返される」と記述している命令が記載されていることになります。for() { } で囲まれた中括弧の中に「コンソールに i を文字列にしたものを表示する」という処理が書かれているので、コンソール画面上には1 ~ 10 の数字が表示されたのです。
練習問題: for 文
- 1から20をコンソールに表示させる繰り返し文を書いてください。
- 1から20をコンソールに表示させる繰り返し文で、iの開始を0からにしてください。
- 1から20までの数を1,3, 5,7…,19と奇数を表示させてください。
- 1から20までの数を0, 2, 4, …20と偶数を表示させてください。
- 1から10までの数を足し、最後に合計数をコンソールに表示させてください。
インクリメントとデクリメント
for 文の増加条件を記述するときは i = i + 1 と書くと説明しましたけど、単純に書くべき文字数も多く感じますよね。C# では1ずつ増加する場合や、1ずつ減少する場合に簡単に書くことのできる記法が用意されています。それを「インクリメント」「デクリメント」と呼んでいます。記述例は以下のような感じになります。
通常 | インクリメント・デクリメント |
i = i + 1; | i++; |
i = i – 1; | i–; |
変数名に続けて ++ を記述すると「変数の値に1増加させた値を再代入する」という意味になります。その逆は — と記述し、「変数の値を1減少させた値を再代入する」という意味になります。こうした記法は for 文などを使用する上で覚えておくと、少しでも楽にコーディングできるので覚えておくと良いでしょう。とはいえ、慣れるまでは i = I + 1; を使って書くのでもいいです。
for (int index = 1; index <= 10; index++)
{
Console.WriteLine(index.ToString());
}
1行目の最後の部分で index++ と記述しています。これでインクリメントが表現できます。前回では for 文のループを管理するのにi と一文字の変数にしていましたが、より意味が分かるようにするならば index といった、意味のある文字を変数名に用意するのがオススメです。
for (int index = 10; index > 0; index--)
{
Console.WriteLine(index.ToString());
}
このサンプルではデクリメントを使ってみました。Index– の部分ですね。これは index = index – 1 の略になります。インクリメントとセットで覚えておき、for 文で使用できるようになると良いでしょう。
while文の使い方
もう一つ覚えておくべき繰り返し文の書き方があります。それは while 文というものです。 for 文は特定の条件をインクリメント・デクリメントしながら処理をするようなイメージでしたが、while 文はもうちょっと柔軟に条件を設定することができます。
for 文は使ってみてわかったと思いますが、数字のカウントで繰り返しを制御することが多いため「○○を満たしている間は繰り返す」という条件が、どうしても数字での制御に縛られてしまします。
その点、while 文は数字の条件に縛られることなく、if 文を扱うかのように繰り返しの条件を設定できる点で柔軟性があると筆者は思っています。もちろん書き方を工夫することで、for 文と同じような繰り返しも書くことができます。まずは早速、かんたんなサンプルから始めていきましょう。
int count = 1;
while (count <= 10)
{
Console.WriteLine(count.ToString());
count++;
}
上記のサンプルはコンソールに 1 から 10 を表示するサンプルです。while { } で囲まれた外側にループの回転数を管理する変数を定義して、1回数字を表示するごとにカウントを1繰り上げています。
while 文で繰り返しの条件を指定する場合は while (条件式) と書き、このサンプルではcount の値が10 以下である場合はwhile() { } の中括弧(“{}”)で囲まれた部分の処理が行われるようになります。
do … while … 文の使い方
先ほどの while 文は繰り返しの条件を前側に記述して、繰り返しを管理していました。それとは別に後側に繰り返しの条件を持ってくるdo … while… 文という記述方法もあるので紹介しておきます。使用頻度でいうと while 文よりは落ちるのですが、「処理をした後に次の繰り返しを行うか」を判定できるので覚えておくと柔軟な発想ができたりします。
int count = 10;
do
{
Console.WriteLine(count.ToString());
count--;
}
while (count > 0);
今回のサンプルは 10 から始まって 1 までをデクリメントしていくサンプルを作成してみました。後側の条件が「count の変数が 0 より大きい場合」となっているので、countが1以上の場合は繰り返しが行われます。
コンソールに数字を表示したらデクリメントする、と処理を記述しているので、10から始まって徐々に数値が落ちていき、最後、1 を表示した後のデクリメントで 0 になったタイミングで次のループに移る条件から外れるのでアプリケーションが終了する仕組みになっています。
break; を使う方法
ここでは break という「繰り返しを途中で抜ける」処理の方法を紹介します。たとえば「3の倍数が来たら処理を終了する」という条件で「繰り返しを終了」させたい場合などに使えるキーワードになります。
1 から 10 までを繰り返す中で、7が来たら処理を終了するというサンプルを作ってみましょう。構想としては繰り返しの中に分岐を仕込んで、条件を満たしていたら繰り返しを抜けるということになります。
for (int index = 1; index <= 10; index++)
{
Console.WriteLine(index.ToString());
if (index == 7)
{
Console.WriteLine("ループを終了します。");
break;
}
}
1から10の繰り返しの中で、変数 index の値が 7 であるかの条件分岐を仕込んでおき、7が来たらメッセージを表示して繰り返しから抜けるという処理にしてあります。1~7 の数字が表示され、7 の後に「ループを終了します。」というメッセージが出たら、コンソールが止まります。
ループから抜け出したら、ループに戻ることはありません。繰り返し処理の中で特定の条件を満たす場合があれば処理を終了することができるので、特定のデータを発見したいときなどに break を使用することが多いです。ついでに while 文でも書いておきましょう。
int index = 1;
while (index <= 10)
{
Console.WriteLine(index.ToString());
if (index == 7)
{
Console.WriteLine("ループを終了します。");
break;
}
index++;
}
continue; を使う方法
前回は特定の条件の時に繰り返しを終了する処理でした。今回はもう一つのバリエーションである「繰り返しを飛ばす」処理を紹介していきます。たとえば 1 から 10 の繰り返しの中で奇数の場合は処理をしたくないときがあるような場合に使用できます。
そういう場合には continue というキーワードを使用することで、いまの繰り返しを飛ばして、次の繰り返しに移ることが可能です。break キーワードのようにループ全体から抜けるのではなく、「いまのループから抜ける」というイメージです。
for (int index =1; index <= 10; index++)
{
if (index % 2 == 1)
{
continue;
}
Console.WriteLine(index.ToString());
}
「奇数だったら」という条件分岐を仕込んでおき、満たす場合は次のループへ移るような処理にしています。したがって1, 3, 5, 7, 9 はコンソールに表示されることがありません。偶数は表示されています。まさにスキップされていますね。
int index = 0;
while (index <= 10)
{
index++;
if (index % 2 == 1)
{
continue;
}
Console.WriteLine(index.ToString());
}
while を使って書いても同じように continue キーワードを使用することができます。特定の場合のみ、後続の処理をしたくないという場面では多用するので break とあわせて continue も覚えておきましょう。
無限ループ
繰り返しを永遠に続けてしまう「無限ループ」というものがあります。特に初心者にとっては while 文を使用すると無限ループを発生させてしまい、永遠にプログラムが動き続けてしまう場合がありますので気を付けましょう。
また、あえて無限ループを発生させて処理を行うパターンもあります。たとえば、繰り返しを何回続けていいかわからないが、特定の条件でループを終了させる必要のある場合です。そういう場合では for 文を使うよりも while 文を使うほうが一般的なので、今後の知識のために紹介しておきたいと思います。
while (true)
{
Console.WriteLine("何か入力してください。");
string input = Console.ReadLine();
int convert;
if (int.TryParse(input, out convert))
{
if (convert < 0)
{
Console.WriteLine("終了します。");
break;
}
}
}
上記のサンプルは -1 が入力されるまで何かの入力を促すサンプルです。-1 以外が入力されると「何か入力してください。」と表示して、入力されるまで待機するようにしています。
while (true) とすることで無限に繰り返しを実行する無限ループを作り出すことが可能です。ちゃんとループから抜け出す条件を設定しておかないと、アプリを強制終了しない限りは終わりとならないので注意しましょう。無限ループを使うときは、あわせて「どんな条件で終了するか」もきちんと設計する必要があります。
第11章 複数の値を変数へ
たとえば -1 が入力されるまで数値の入力を受け付けて、数字だった場合にすべての入力値を画面に表示したい、というような処理を作ろうとしたときに、これまで通り1つの変数に対して1つの値しか持つことができないと都合が悪くなります。
-1 が入力されるまで、という特定の条件を満たすまで繰り返しの処理がされる場合に、いったい何回の繰り返しが行われるか予想することができないからです。そういう場合は事前に変数を定義しておくのが不可能であることは一目瞭然です。
そんな時に使用するのが「配列」や「リスト」といった、一つの変数に複数の値を同時に持つことのできる機能があります。マンションのようなものだと考えると分かりやすいと思います。大きな建物を複数の部屋を作り、それぞれに部屋番号を割り振ることで大きな建物内でもきちんと個別管理できるようになっていますよね。
配列やリストも「何番目に格納されているか」という識別子をもって、1つの変数にあたかも複数の値を持っているかのようにふるまうことができます。特に「リスト」は「何個追加できるか」という部分が可変なので必要な分だけ追加できるので、近年のプログラミングでは主流です。
配列を使う方法
早速、サンプルアプリケーションを作っていきますが、最初に作成するのは「配列」と呼ばれる機能です。配列は「格納できる個数を先に決める必要がある」という点でリストよりも明確な使用用途で使うことが多いです。
int[] array = new int[3];
//値を設定する
array[0] = 1;
array[1] = 2;
array[2] = 3;
for (int index = 0; index < array.Length; index++)
{
//配列から値を取り出してコンソールに表示する
int value = array[index];
Console.WriteLine(value.ToString());
}
いくつか重要なトピックがありますので、順を追って解説していきましょう。
まず重要なのは配列を宣言している部分です。 int[] array = new int[3]; という箇所ですが、int[] の部分が int 型の配列を意味しています。そのあとに続く array の部分が変数名です。イコールの後の new int[3]; というのは、int 型の値を 3 つ格納できる配列を用意するという意味になります。
new というキーワードは「新規で作成する」「新しく用意する」という程度だと、現段階で思ってもらえれば十分です。また、配列もリストも共通しているのが、格納できる値の型は決まっている、ということです。int[] で定義した配列は int 型の値しか格納できません。
コメントで「値を設定する」という部分を見ていきましょう。ここでは array[0] = 1; としています。配列の格納される際に振られる「何番目の要素か」という部分は 0 番目から始まり、1, 2 … と続いていきます。「変数 array の 0 番目の要素に 1 を格納する」という意味となり、以降の処理も同様となります。
次に見るのは for 文の継続条件にある array.Length の部分です。配列の要素の数を示しています。最初に3 つの値を格納できる配列を用意しているので、array.Length の値は 3 となります。
そして最後のトピックが int value = array[index]; の部分です。int 型の変数 value に対して配列の特定部分の中身を取得して格納するという意味なのですが、配列の要素を取得するには array[0] と記述する必要があります。これは値を設定したときと同じです。配列の要素にアクセスする場合(設定・取得)は、変数名[要素の番号] と書くと覚えておきましょう。
- 文字列型でリストを作成し、3つの好きな食べ物を値として格納して、すべて表示させてください。
それでは練習として上記の処理をするアプリケーションを作成してみてください。
App38
string[] array = new string[3];
array[0] = "カレー";
array[1] = "寿司";
array[2] = "ラーメン";
for (int index = 0; index < array.Length; index++)
{
string meal = array[index];
Console.WriteLine(meal);
}
上記のように作成できましたでしょうか。これで配列の基礎的な説明は完了となります。どちらかというと、次項で説明するリストのほうが使う場面が多いのですが、配列も重要な概念ですので覚えておきましょう。
リストを使う方法
前項では「配列」について紹介しました。プログラミング技術においても配列は非常に重要で、この機能のおかげで様々なデータを取り扱えるようになったといっても良いでしょう。
さて、ここでは近年のプログラミングの現場ではより重要となっている「リスト」を解説します。この章のはじめの方でも記載していますが、リストは配列をより強力に、柔軟にしたものになります。配列は初めに格納可能な数を決めていましたが、リストは初めに決めておく必要がありません。実際に使ってみましょう。
List list = new List();
list.Add("Good morning!");
list.Add("Good afternoon!");
list.Add("Good evening!");
for (int index = 0; index < list.Count; index++)
{
var message = list[index];
Console.WriteLine(message);
}
配列と基本的に似ているので、配列とリストで異なる部分を中心に解説していきます。まずリストの定義の仕方が配列とは少し違いますね。 new List(); となっています。 new キーワードは一緒ですが、そのあとが少しだけ違います。
List というキーワードの後に < > があり、間に string がはさまっています。リストの場合は < > の間に格納したい値の型を記述する決まりがあります。もちろん int 型のリストを使いたい場合は new List(); となります。
リストに値を設定する場合は .Add(); を使用します。今回は string 型のリストなので、Add の括弧内に渡す値も文字型を引き渡しましょう。また、リストの要素の合計数は .Count; で取得することができます。要素番号は配列と同じで 0 から配列に入っていきます。特定の番号に格納されている要素にアクセスする場合は配列と同じになります。
- 画面からの入力値を3回受け取って、3回入力された後、画面に入力値を表示させてください。
上記の動きをするアプリケーションを、ぜひともチャレンジとして取り組んでみてください。いろいろと考えることはありますが、3回入力するという部分をどうするか、3回の入力をどのように格納するか、3回分の入力値を画面に表示するにはどうするか。考えることはありますね。
List list = new List();
for (int index = 0; index < 3; index++)
{
Console.WriteLine("何か入力してください。");
var input = Console.ReadLine();
list.Add(input);
}
Console.WriteLine("出力します。");
for (int index = 0; index < list.Count; index++)
{
Console.WriteLine(list[index]);
}
こんな感じにできましたでしょうか?ほかにも色々なパターンで作ることができます。たとえば while 文を使ってみたり、無限ループを使用してリストの要素数が 3 になったら処理をさせないようにしたり。同じ処理をするのでも、自由な発想で作り変えられるのがプログラミングの良いところでもあります。もうひとつチャレンジとして、こんなアプリケーションを作ってみましょう。
- 3回の数値を入力してもらい、入力された数値の合計値を画面に表示する
List storage = new List();
while (true)
{
Console.WriteLine("数値を入力してください。");
string input = Console.ReadLine();
int number;
if (int.TryParse(input, out number))
{
//数値に変換できたらリストに追加する
storage.Add(number);
}
//3つ格納出来たらループから抜ける
if (storage.Count == 3)
{
break;
}
}
//合計値を算出してコンソールに表示する
int total = 0;
for (int index = 0; index < storage.Count; index++)
{
total = total + storage[index];
}
Console.Write("合計値:");
Console.WriteLine(total.ToString());
少し長いので難しいかと思いますが、処理を一つ一つ分解しながら整理していき、ちゃんと処理が通る道を作ってあげることで難しいと思えるアプリケーションでも問題なく作ることができるはずです。解答サンプルも、これまでに学習したもので作り上げていますよね。
練習問題
- 3 回入力を促し、入力値を逆から出力するようにしてください
- 3 回の数値が入力されたら、入力された数値の平均値を表示してください
- 3 回の偶数が入力されるまで処理を続けて、入力された合計値を表示してください
第12章 ANDとOR
さて、ついに本書も 12 章までやってきました。徐々に C# でプログラミングを書いていくことに慣れてきたころかもしれませんね。ここで取り扱うのは AND と OR というトピックになります。ざっくりというと「複合的に条件を判断する方法」になります。複合的に条件を判断する、というのはいくつかの条件が組み合わさって一つの条件として機能するということを指します。
たとえば「傘をさす」には「雨が降っている」「傘を持っている」という2つの条件を満たしている必要がありますよね。この2つの条件を満たしていることを AND と表現します。また、コンビニで買い物をするには、現金または交通系ICカード、クレジットカード、バーコードなど複数の選択肢のうちどれかでも満たしていれば買い物ができます。
このように「A かつ B(AとBの両方を満たす)」という表現をAND とし、「A または B(A か B のどちらかを満たす)」という表現を OR としています。これを C# で使う方法を学びます。
AND を使う方法
それでは AND を使う方法を解説していきます。C# で「A かつ B」という表現をするには && というキーワードを使用します。簡単なサンプルを見ていきましょう。
int number1 = 8;
int number2 = 4;
int total = number1 + number2;
if (total > 10 && total % 2 == 0)
{
Console.WriteLine("10以上、かつ偶数です。");
}
number1 と number2 の合計値が「10 より大きい、かつ偶数である」という条件に && を使って表現しました。 8 + 4 は12 なので条件を満たすので if 文の中の処理が実行されます。合計値が10以下や、奇数になるように number1 と number2 を変えてみて実行してみるとコンソールにはなにも表示されないはずです。
コツは && で条件を区切って total > 10 と total % 2 == 0 という2つの条件を満たすかどうかを個別に確認することです。一気に確認せず、左から順に条件を確認していきましょう。
&& という条件は AND なので、たくさんの条件を付けることができます。「A かつ B かつ C」という条件も作り出せます。たとえば「10 以上、20 以下、かつ偶数」というような条件も if (total >= 10 && total <= 20 && total % 2 == 0) と && を続けることで可能です。
とはいえ条件を複数つけていくとソースコードが読みにくくなっていくので、必要に応じて if 文に分岐させて、さらに中の if 文で条件を確認するという選択肢をとることもあります。
OR を使う方法
プログラミングで重要な概念である AND の次に学ぶのは OR になります。OR は一般的に「A または B」と呼んで使うことが多いですね。詳しくいうと「Aの条件を満たす、もしくは B の条件を満たす」という、2つのうちのどちらかを満たす場合に使います。
C# で「または」を使う場合には || キーワードを使用します。 && はキーワードを挟んで両側を満たす場合を考えましたが、 || はキーワードを挟んだ右か左かを満たす場合を考えればよくなります。早速、簡単なアプリケーションを作ってみましょう。
string input = Console.ReadLine();
int number;
if (int.TryParse(input, out number))
{
if (number == 5 || number == 8)
{
Console.WriteLine("5または8でした。");
}
}
Console.WriteLine("終了します。");
入力値を受け取って、int 型に変換できた場合に「5または8である場合」にメッセージを表示させるアプリケーションを作ってみました。あんまり難しくないので「こういう感じで使えばいいのか」と思ってもらえれば良いと思います。
|| キーワードで左右に分解すると「numberは5と同値である」と「numberは8と同値である」という2つの条件で判定を行います。そして、そのどちらかを満たす場合に if 文の分岐の中に入っていきメッセージを表示させるのです。
第13章 練習問題
本書もだいぶ進んできました。ここまでに習ってきた内容の復習と応用を兼ねて、いくつかの練習問題を作ってみました。簡単に解けるものから少し難しいものまで何個か用意しているので、最後の練習として取り組んでみてください。
if 文
- 画面の入力値が10以下の場合は「入力値は10以下です。」、それ以外の場合は「入力値は10よりも大きいです。」と表示させるようにしてください。
- 画面からの入力値を2つ受け取り、「合計値:〇〇」と表示させるようにしてください。そのときはガイダンスとして「1つ目の数値を入力してください。」「2つ目の数値を入力してください。」も表示させ、それぞれのメッセージの後に入力値を受け取るようにしてください。
- 2つの入力値を受け取り、2つの入力値の合計が偶数だったら「入力値の合計は偶数です。」と表示し、奇数である場合は「入力値の合計値は奇数です。」と表示させてください。
FizzBuzz
- 1から100を出力してください。ただし3の倍数の場合は「Fizz」、5の倍数では「Buzz」、15の倍数では「FizzBuzz」を出力するようにしてください。
for (int index = 1; index <= 100; index++)
{
string output = "";
if (index % 15 == 0)
{
output = "FizzBuzz";
}
else if (index % 5 == 0)
{
output = "Buzz";
}
else if (index % 3 == 0)
{
output = "Fizz";
}
else
{
output = index.ToString();
}
Console.WriteLine(output);
}
ほかにも文字結合を使ってこの問題を解くこともできます。別のやり方を考えてみてください。プログラミングは一つの解答に対して複数のアプローチできる場合があります。発送の自由さも大切です。
for 文と if 文
- 以下のような九九表を作成してみましょう。
for (int tate = 1; tate <= 9; tate++)
{
for (int yoko = 1; yoko <= 9; yoko++)
{
int total = tate * yoko; //数字と数字の間隔用のスペース
string output = " "; //出力文字を整形する -> 9:" 9" / 10:"10"
if (total < 10)
{
output += " ";
}
output += total.ToString();
Console.Write(output);
}
Console.WriteLine();
}
2重ループを思いつけるかが回答の肝になります。縦のループと横のループが九九表を表し、縦と横の掛け算になることを思いつけば十分でしょう。文字の整形は好みですが2桁ぞろえにするとよいです。
- 12 × 12 の表を作ってみましょう。
for (int tate = 1; tate <= 12; tate++)
{
for (int yoko = 1; yoko <= 12; yoko++)
{
int total = tate * yoko;
string output = " "; //間隔用スペース
if (total < 10)
{
//1桁なら2桁埋めて3桁
output += " ";
}
if (10 <= total && total < 100)
{
//2桁なら1桁埋めて3桁
output += " ";
}
output += total.ToString(); //計算結果を設定
Console.Write(output);
}
Console.WriteLine();
}
九九表の応用で12 × 12 の表も作成できます。今回は最大桁数が3桁になるので、それに合わせて桁を揃えるようにします。10 以下なら 2 桁、10以上、100以下なら 1 桁埋めて 3 桁にします。表をきれいにして見た目も整えるとこまでチャレンジしてみてください。
- 入力値を受け取って、その入力値分の階段(■で表現すること)を作りましょう。数値でない場合は数値が入力されるまで繰り返すようにしましょう。以下の画像はサンプルです。
int inputNumber;
while (true)
{
Console.WriteLine("数値を入力してください。");
string input = Console.ReadLine();
if (!int.TryParse(input, out inputNumber))
{
Console.WriteLine("数値ではありません。");
Console.WriteLine("");
continue;
}
break;
}
for (int tate = 0; tate < inputNumber; tate++)
{
for (int yoko = 0; yoko <= tate; yoko++)
{
//表示は縦と同じところまで -> 3行目なら3列
Console.Write("■");
}
Console.WriteLine();
}
階段をどのように表現するかが重要ですが、縦の番号と横の番号が一致するという条件を考えつけばうまくいきます。for 文の継続条件に縦の値を設定するようにしてもいいですし、if 文をうまく使って for 文を制御するのも良いでしょう。もう一つのサンプル解答を掲載します。ほかのパターンで解けないかも考えてみてください。
int inputNumber;
while (true)
{
Console.WriteLine("数値を入力してください。");
string input = Console.ReadLine();
if (!int.TryParse(input, out inputNumber))
{
Console.WriteLine("数値ではありません。");
Console.WriteLine("");
continue;
}
break;
}
for (int tate = 0; tate < inputNumber; tate++)
{
for (int yoko = 0; yoko <= inputNumber; yoko++)
{
//表示は縦と同じところまで -> 3行目なら3列
Console.Write("■");
//横と縦が一致したら、
//横のループから抜けて次の行へ進む
if (yoko == tate)
{
break;
}
}
Console.WriteLine();
}
以上、いくつかの練習問題と難しいと思う問題についてはサンプルの解答を記載しました。ここで挙げた問題については、スラスラと回答できるようになると良いかと思います。
あとがき
駆け足でしたが C# で必要基礎となる文法について学んできました。本書で紹介した内容は基礎中の基礎に当たりますが、まったくプログラミングに触ったことのない人であれば、このような内容でも十分に大変に感じたことでしょう。
本書は「まったくの未経験者が初めてプログラミングに触れる」という想定で執筆していますので、ここで筆を下すのが妥当だと思っています。これ以上の内容は本書に書かれていた内容を理解した先にあるものになります。まずは「初級編をやり切った!」という感慨に浸ってもらえればと思います。
プログラミングを学ぶことは難しい反面、難しさの中に面白さがあると筆者は思っています。私自身も未経験者としてIT企業に入社してから、毎日、必死にプログラミングに食らいついてきました。プログラミングが面白くなるのは「問題解決に取り組んだ時」だと感じています。
本書でも各トピックの後に、学んだ内容を少し難しくした練習問題を掲載していますが、問題が「解けた!」「できた!」という快感がプログラミングの醍醐味です。プログラミングは、問題解決のために脳を回転させて考え、解決にチャンレンジして、それを達成する。その繰り返しです。簡単に言ってしまうと「思考力」が試されるのです。そんな世界への第一歩として、本書が少しでもお役に立つならばうれしく思います。