6日目のゴール
初級編 6日目のテーマは
「“意味のある型(クラス)”を、ちゃんと“操作できる道具”として育てること」 です。
5日目でやったことはこうでした。
名前+点数 → Student クラス
日付+勉強時間 → StudyLog クラス
クラスの配列で「複数件」を扱う
今日はここに、
特定の人を探す(検索)
条件に合うものだけ数える・取り出す(フィルタ)
クラスを引数・戻り値に使うメソッドを書く
という「データを“扱う力”」を足していきます。
5日目の Student をもう一度出しておく
今日もこの Student を使っていく
まずは、昨日の Student をもう一度。
class Student
{
public string Name;
public int Score;
}
C#そして、配列で複数人を持つ形。
Student[] students = new Student[count];
C#6日目は、この Student[] に対して
誰か1人を探す
平均以上の人だけ数える
最高点の人を返す
といった「操作メソッド」をどんどん書いていきます。
「名前で探す」メソッドを作る
まずは“線形探索”という基本パターン
「太郎さんの点数を知りたい」と思ったとき、
配列の中から「Name が ‘太郎’ の Student」を探したくなります。
そのためのメソッドを作ってみましょう。
using System;
class Program
{
static void Main(string[] args)
{
Student[] students = CreateSampleStudents();
Console.Write("探したい名前を入力してください:");
string targetName = Console.ReadLine();
Student found = FindByName(students, targetName);
if (found == null)
{
Console.WriteLine("その名前の生徒は見つかりませんでした。");
}
else
{
Console.WriteLine(found.Name + " さんは " + found.Score + " 点です。");
}
}
static Student[] CreateSampleStudents()
{
Student[] students = new Student[3];
students[0] = new Student { Name = "太郎", Score = 80 };
students[1] = new Student { Name = "花子", Score = 95 };
students[2] = new Student { Name = "次郎", Score = 70 };
return students;
}
static Student FindByName(Student[] students, string name)
{
for (int i = 0; i < students.Length; i++)
{
if (students[i].Name == name)
{
return students[i];
}
}
return null;
}
}
class Student
{
public string Name;
public int Score;
}
C#ここで深掘りしたいのは FindByName です。
static Student FindByName(Student[] students, string name)
{
for (int i = 0; i < students.Length; i++)
{
if (students[i].Name == name)
{
return students[i];
}
}
return null;
}
C#やっていることはシンプルです。
配列を先頭から順に見る
Name が一致したら、その Student をその場で return
最後まで見ても見つからなければ null を返す
ここでの超重要ポイントは、
戻り値の型が Student になっている
「見つからなかったときは null を返す」という約束をしている
という2つです。
Student を戻り値に使えるようになった瞬間、
クラスが「ただの入れ物」から「関数の世界の一員」に昇格します。
「見つからないかもしれない」戻り値の扱い方
null チェックは“セット”で考える
FindByName の戻り値は、
「Student かもしれないし、null かもしれない」です。
なので、呼び出し側では必ずこう書きます。
Student found = FindByName(students, targetName);
if (found == null)
{
Console.WriteLine("見つからないパターン");
}
else
{
Console.WriteLine("見つかったパターン");
}
C#この「null かどうかを必ずチェックする」という習慣は、
クラスを扱ううえでとても大事です。
「見つからない可能性がある検索メソッド」
→ 戻り値はクラス型(Student)
→ 見つからないときは null
→ 呼び出し側で null チェック
このパターンを、6日目で体に染み込ませておきましょう。
「条件に合う人を数える」メソッド
平均以上の人は何人いる?
次は、「条件に合うものを数える」パターンです。
例えば、
平均点を計算する
平均以上の点数の人が何人いるか数える
という処理を、メソッドで書いてみます。
using System;
class Program
{
static void Main(string[] args)
{
Student[] students = CreateSampleStudents();
double average = CalcAverage(students);
int countAbove = CountAboveOrEqual(students, average);
Console.WriteLine("平均点: " + average);
Console.WriteLine("平均以上の人の人数: " + countAbove);
}
static Student[] CreateSampleStudents()
{
Student[] students = new Student[4];
students[0] = new Student { Name = "太郎", Score = 80 };
students[1] = new Student { Name = "花子", Score = 95 };
students[2] = new Student { Name = "次郎", Score = 70 };
students[3] = new Student { Name = "三郎", Score = 60 };
return students;
}
static double CalcAverage(Student[] students)
{
int total = 0;
for (int i = 0; i < students.Length; i++)
{
total = total + students[i].Score;
}
double average = (double)total / students.Length;
return average;
}
static int CountAboveOrEqual(Student[] students, double threshold)
{
int count = 0;
for (int i = 0; i < students.Length; i++)
{
if (students[i].Score >= threshold)
{
count++;
}
}
return count;
}
}
class Student
{
public string Name;
public int Score;
}
C#ここでのポイントは、
Student[] を引数に取るメソッドが増えているCalcAverage は「平均を返す」CountAboveOrEqual は「条件に合う人数を返す」
という「役割の分担」です。
CountAboveOrEqual の中身は、
3日目にやった「条件に合うものを数える」パターンそのものです。
「最高点の人」を返すメソッド
クラスを“丸ごと”返す感覚
5日目では、「最高点」と「その人の名前」を
別々の変数で持っていました。
6日目では、
「最高点の Student をそのまま返す」
という形にしてみます。
using System;
class Program
{
static void Main(string[] args)
{
Student[] students = CreateSampleStudents();
Student top = FindTopStudent(students);
Console.WriteLine("最高点の人は " + top.Name + " さん (" + top.Score + " 点) です。");
}
static Student[] CreateSampleStudents()
{
Student[] students = new Student[4];
students[0] = new Student { Name = "太郎", Score = 80 };
students[1] = new Student { Name = "花子", Score = 95 };
students[2] = new Student { Name = "次郎", Score = 70 };
students[3] = new Student { Name = "三郎", Score = 60 };
return students;
}
static Student FindTopStudent(Student[] students)
{
Student best = students[0];
for (int i = 0; i < students.Length; i++)
{
if (students[i].Score > best.Score)
{
best = students[i];
}
}
return best;
}
}
class Student
{
public string Name;
public int Score;
}
C#ここでのキモは FindTopStudent です。
static Student FindTopStudent(Student[] students)
{
Student best = students[0];
for (int i = 0; i < students.Length; i++)
{
if (students[i].Score > best.Score)
{
best = students[i];
}
}
return best;
}
C#やっていることは、
「最大値を求めるパターン」と同じです。
ただし、
最大値(int)ではなく
「最大値を持っている Student そのもの」を best に入れている
という違いがあります。
この書き方ができると、
「最高点の人」
「最も勉強時間が長い日」
「一番評価の高い本」
などを、全部「クラスごと返す」形で書けるようになります。
「条件に合う人だけ表示する」メソッド
フィルタリングの基本パターン
次は、「条件に合うものだけを処理する」パターンです。
例えば、
80 点以上の人だけ表示する
というメソッドを書いてみます。
using System;
class Program
{
static void Main(string[] args)
{
Student[] students = CreateSampleStudents();
Console.WriteLine("80点以上の人:");
PrintAboveOrEqual(students, 80);
}
static Student[] CreateSampleStudents()
{
Student[] students = new Student[4];
students[0] = new Student { Name = "太郎", Score = 80 };
students[1] = new Student { Name = "花子", Score = 95 };
students[2] = new Student { Name = "次郎", Score = 70 };
students[3] = new Student { Name = "三郎", Score = 60 };
return students;
}
static void PrintAboveOrEqual(Student[] students, int threshold)
{
for (int i = 0; i < students.Length; i++)
{
if (students[i].Score >= threshold)
{
Console.WriteLine(students[i].Name + " さん: " + students[i].Score + " 点");
}
}
}
}
class Student
{
public string Name;
public int Score;
}
C#ここでは、
「条件に合うものだけ Console.WriteLine する」
という形にしています。
もし余裕が出てきたら、
「条件に合う Student だけを別の配列に集める」
という方向にも進めますが、
初級編では「表示するだけ」で十分です。
6日目のミニアプリ:簡易「成績ビューア」
メニューから「いろいろな見方」を選べるようにする
4日目で作った「メニュー付きアプリ」の形に、
5日目・6日目の Student 操作を組み込んでみます。
仕様はこうです。
あらかじめ数人分の Student を用意しておく
メニューから以下を選べる
1: 全員の一覧を表示
2: 最高点の人を表示
3: 名前で検索
4: 平均以上の人だけ表示
0: 終了
コード例です。
using System;
class Program
{
static void Main(string[] args)
{
Student[] students = CreateSampleStudents();
while (true)
{
PrintMenu();
int choice = ReadInt("番号を選んでください:");
if (choice == 0)
{
Console.WriteLine("終了します。");
break;
}
Console.WriteLine();
switch (choice)
{
case 1:
PrintAll(students);
break;
case 2:
ShowTopStudent(students);
break;
case 3:
SearchByName(students);
break;
case 4:
ShowAboveAverage(students);
break;
default:
Console.WriteLine("0〜4 の範囲で選択してください。");
break;
}
Console.WriteLine();
}
}
static void PrintMenu()
{
Console.WriteLine("===== 成績ビューア =====");
Console.WriteLine("1: 全員の一覧を表示");
Console.WriteLine("2: 最高点の人を表示");
Console.WriteLine("3: 名前で検索");
Console.WriteLine("4: 平均以上の人だけ表示");
Console.WriteLine("0: 終了");
}
static Student[] CreateSampleStudents()
{
Student[] students = new Student[4];
students[0] = new Student { Name = "太郎", Score = 80 };
students[1] = new Student { Name = "花子", Score = 95 };
students[2] = new Student { Name = "次郎", Score = 70 };
students[3] = new Student { Name = "三郎", Score = 60 };
return students;
}
static int ReadInt(string message)
{
while (true)
{
Console.WriteLine(message);
string text = Console.ReadLine();
int value;
bool ok = int.TryParse(text, out value);
if (ok)
{
return value;
}
else
{
Console.WriteLine("数字として解釈できませんでした。もう一度入力してください。");
}
}
}
static void PrintAll(Student[] students)
{
Console.WriteLine("【全員の一覧】");
for (int i = 0; i < students.Length; i++)
{
Console.WriteLine(students[i].Name + " さん: " + students[i].Score + " 点");
}
}
static void ShowTopStudent(Student[] students)
{
Student top = FindTopStudent(students);
Console.WriteLine("【最高点】");
Console.WriteLine(top.Name + " さん: " + top.Score + " 点");
}
static void SearchByName(Student[] students)
{
Console.Write("検索したい名前を入力してください:");
string name = Console.ReadLine();
Student found = FindByName(students, name);
if (found == null)
{
Console.WriteLine("その名前の生徒は見つかりませんでした。");
}
else
{
Console.WriteLine(found.Name + " さん: " + found.Score + " 点");
}
}
static void ShowAboveAverage(Student[] students)
{
double average = CalcAverage(students);
Console.WriteLine("平均点: " + average);
Console.WriteLine("【平均以上の人】");
for (int i = 0; i < students.Length; i++)
{
if (students[i].Score >= average)
{
Console.WriteLine(students[i].Name + " さん: " + students[i].Score + " 点");
}
}
}
static Student FindTopStudent(Student[] students)
{
Student best = students[0];
for (int i = 0; i < students.Length; i++)
{
if (students[i].Score > best.Score)
{
best = students[i];
}
}
return best;
}
static Student FindByName(Student[] students, string name)
{
for (int i = 0; i < students.Length; i++)
{
if (students[i].Name == name)
{
return students[i];
}
}
return null;
}
static double CalcAverage(Student[] students)
{
int total = 0;
for (int i = 0; i < students.Length; i++)
{
total = total + students[i].Score;
}
double average = (double)total / students.Length;
return average;
}
}
class Student
{
public string Name;
public int Score;
}
C#ここまで来ると、
かなり「アプリっぽい」雰囲気になってきたはずです。
6日目で絶対に押さえておきたいポイント
「クラスを引数・戻り値に使う」感覚
今日の一番大事なポイントは、これです。
Student[] を引数に取るメソッドをたくさん書いたStudent を戻り値にするメソッドも書いた
「見つからないときは null」という約束を覚えた
具体的には、次のパターンを体で覚えてほしいです。
名前で検索して、見つかった Student を返す(見つからなければ null)
最高点の Student を返す
平均を計算する(double を返す)
条件に合うものを数える(int を返す)
クラスをこうやって“普通に”引数・戻り値に使えるようになると、
コードが一気に「現実の会話」に近づきます。
もし余裕があればやってみてほしいこと
StudyLog でも同じことをやってみる
5日目の StudyLog を使って、
最も勉強時間が長い日を返すメソッド
平均以上勉強した日だけ表示するメソッド
特定の日付の記録を検索するメソッド
などを、自分で設計して書いてみてください。
やることは全部、今日やった Student の応用です。
6日目のまとめ
初級編 6日目で、あなたは
「クラスを作れる人」から
「クラスを“操作する道具”として使いこなす人」
へと一歩進みました。
検索(FindByName / FindTopStudent)
集計(CalcAverage / CountAboveOrEqual)
フィルタ(条件に合うものだけ表示)
メニュー付きアプリへの組み込み
7日目は、
ここまでの要素をまとめて
「小さな“自分用アプリ”」として形にしていきます。
そこまで行くと、もう立派に「C# でアプリを書ける人」です。

