Skip to content

第6章 配列

この章では、複数の値をまとめて管理するための 配列 を学習します。

これまでの章では、1 つの値を 1 つの変数で管理してきました。

int score1 = 80;
int score2 = 75;
int score3 = 90;

点数が 10 件、100 件と増えた場合、変数を 1 つずつ用意するのは現実的ではありません。

配列を使うと、複数の点数・社員名・商品価格などを 1 つのまとまりとして管理できます。


この章でできるようになること

Section titled “この章でできるようになること”

この章を終えると、次のことができるようになります。

  • 配列とは何かを説明できる
  • 同じ型の複数の値を配列で管理できる
  • 配列を宣言し、初期化できる
  • 配列の各要素にアクセスできる
  • 配列のインデックスが 0 から始まることを説明できる
  • for 文を使って配列の要素を順番に処理できる
  • Length を使って配列の要素数を取得できる
  • 初期化を伴わない配列を作成し、後から値を代入できる
  • foreach 文を使って配列の要素を順番に取り出せる
  • 2 次元配列の基本を説明できる
  • 配列で起きやすい範囲外アクセスのエラーを理解できる

項目内容
開発環境Visual Studio 2022
プロジェクト種類コンソール アプリ
対象フレームワーク.NET 8
ソリューション名Chapter06
プロジェクト名Ch06_Array

csproj の Nullable は disable に変更してください

プロジェクト作成後、Ch06_Array.csproj を開き、<Nullable>disable</Nullable> に変更してください。

詳しい手順は、第 1 章「1-1 プロジェクトを作成する」を参照してください。


作業を始める前に、次の内容を確認してください。

  • Visual Studio 2022 でコンソールアプリを作成できる(不安な場合は 付録 B「VS2022 の準備と基本操作」 を参照)
  • csproj の Nullable を disable に変更できる
  • intstring の変数を作成できる
  • for 文を使って指定回数の繰り返しができる
  • Console.ReadLineint.Parse を使える
  • Console.WriteConsole.WriteLine の違いを説明できる
  • 第 5 章の課題を Git に提出済みである

5 人分の点数から平均点を求めるプログラムを考えます。

配列を使わない場合、次のように書けます。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int score1 = 80;
int score2 = 75;
int score3 = 90;
int score4 = 68;
int score5 = 85;
int total = score1 + score2 + score3 + score4 + score5;
double average = (double)total / 5;
Console.WriteLine($"合計点:{total}");
Console.WriteLine($"平均点:{average}");
}
}
}

実行結果:

合計点:398
平均点:79.6

点数が増えると変数も増え、修正も大変になります。このような場面で配列を使います。


Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = { 80, 75, 90, 68, 85 };
int total = scores[0] + scores[1] + scores[2] + scores[3] + scores[4];
double average = (double)total / 5;
Console.WriteLine($"合計点:{total}");
Console.WriteLine($"平均点:{average}");
}
}
}

実行結果:

合計点:398
平均点:79.6

int[] scores は「int 型の配列」を表します。[] が「配列」を意味する記号です。


配列は、同じ型の値を順番に並べた箱のようなものです。

scores
インデックス 0 1 2 3 4
値 80 75 90 68 85

配列の各値には番号が付いています。この番号を インデックス といいます。

C# の配列のインデックスは 0 から始まります

1番目の要素 → scores[0]
2番目の要素 → scores[1]
3番目の要素 → scores[2]

配列の宣言には 2 通りの書き方があります。

書き方使う場面
初期値ありint[] scores = { 80, 75, 90 };最初から値が決まっている場合
要素数だけ指定int[] scores = new int[5];後から値を入れる場合

どちらを使うかは、値をプログラムの中で決めるか、入力や計算で後から決めるかによります。


次のコードを入力して実行してください。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = { 80, 75, 90, 68, 85 };
Console.WriteLine(scores[0]);
Console.WriteLine(scores[1]);
Console.WriteLine(scores[2]);
}
}
}

実行結果:

80
75
90

エラーになる例:範囲外のインデックス

Section titled “エラーになる例:範囲外のインデックス”

次のコードは実行時にエラーになります。

int[] scores = { 80, 75, 90, 68, 85 };
Console.WriteLine(scores[5]);

要素数は 5 ですが、インデックスは 0 から始まるため、有効な番号は 0 〜 4 です。

要素数:5
使えるインデックス:0, 1, 2, 3, 4

scores[5] は存在しないためエラーになります。要素数と最後のインデックスは 1 つ違うことを覚えておきましょう。


補足:配列のコピーには注意が必要

Section titled “補足:配列のコピーには注意が必要”

次のコードは、配列のコピーになりません。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = { 80, 75, 90 };
int[] backup = scores; // コピーしているように見えるが…
backup[0] = 0;
Console.WriteLine($"scores[0] = {scores[0]}");
Console.WriteLine($"backup[0] = {backup[0]}");
}
}
}

実行結果:

scores[0] = 0
scores[0] が変わってしまっている
backup[0] = 0

int[] backup = scores; と書くと、backupscores同じ配列を指す だけで、配列そのものはコピーされません。そのため、片方を変更するともう片方の値も変わってしまいます。

このような「同じものを指す」性質を持つ型を 参照型 と呼びます。詳しくは 第 11 章「値型と参照型」 で改めて学習します。

今の段階では「配列を別の変数に代入しても、中身がコピーされるわけではない」とだけ覚えておけば十分です。本当にコピーが必要な場面は、後の章で扱います。


配列は繰り返し処理と組み合わせることで便利になります。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = { 80, 75, 90, 68, 85 };
int total = 0;
for (int i = 0; i < 5; i++)
{
total += scores[i];
}
double average = (double)total / 5;
Console.WriteLine($"合計点:{total}");
Console.WriteLine($"平均点:{average}");
}
}
}

実行結果:

合計点:398
平均点:79.6

i の値が 012 … と変化するにつれ、scores[i]scores[0]scores[1]scores[2] … と変化します。

i の値アクセスする要素
0scores[0]80
1scores[1]75
2scores[2]90
3scores[3]68
4scores[4]85

配列のインデックスが 0 から始まるため、for 文も int i = 0 から始めます。


先ほどのコードでは、要素数を 5 と直接書いていました。

for (int i = 0; i < 5; i++)

要素数が変わるたびにこの数字を修正するのは手間がかかります。Length を使うと自動的に要素数を取得できます。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = { 80, 75, 90, 68, 85 };
int total = 0;
for (int i = 0; i < scores.Length; i++)
{
total += scores[i];
}
double average = (double)total / scores.Length;
Console.WriteLine($"合計点:{total}");
Console.WriteLine($"平均点:{average}");
}
}
}

実行結果:

合計点:398
平均点:79.6

これで点数を追加しても for 文を修正する必要がなくなります。配列を扱うときは、できるだけ Length を使いましょう。


エラーになる例:条件式に <= を使う

Section titled “エラーになる例:条件式に <= を使う”

次のコードは実行時にエラーになります。

for (int i = 0; i <= scores.Length; i++)
{
Console.WriteLine(scores[i]);
}

i <= scores.Length だと i = 5 のときも実行されますが、最後の有効なインデックスは 4 です。

配列と for 文を組み合わせるときは、基本的に次の形を使います。

for (int i = 0; i < scores.Length; i++)

社員名一覧を番号付きで表示する

Section titled “社員名一覧を番号付きで表示する”

文字列の配列も同じように使えます。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
string[] employeeNames = { "山田二郎", "佐藤昭夫", "山口洋子", "田中浩介" };
for (int i = 0; i < employeeNames.Length; i++)
{
Console.WriteLine($"{i + 1}番目:{employeeNames[i]}");
}
}
}
}

実行結果:

1番目:山田二郎
2番目:佐藤昭夫
3番目:山口洋子
4番目:田中浩介

インデックスは 0 から始まりますが、i + 1 にすることで画面上の番号を 1 から始められます。


6-3 初期化を伴わない配列の宣言

Section titled “6-3 初期化を伴わない配列の宣言”

要素数だけを決めて配列を作る

Section titled “要素数だけを決めて配列を作る”

値が後から決まる場合は、要素数だけを先に指定して配列を作ります。

int[] scores = new int[5];

この時点では、各要素に型の初期値が入ります。

初期値
int0
double0.0
boolfalse
stringnull(まだ何も入っていない状態)

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = new int[5];
scores[0] = 80;
scores[1] = 75;
scores[2] = 90;
scores[3] = 68;
scores[4] = 85;
for (int i = 0; i < scores.Length; i++)
{
Console.WriteLine(scores[i]);
}
}
}
}

実行結果:

80
75
90
68
85

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
string[] departments = new string[3];
departments[0] = "総務";
departments[1] = "営業";
departments[2] = "開発";
for (int i = 0; i < departments.Length; i++)
{
Console.WriteLine(departments[i]);
}
}
}
}

実行結果:

総務
営業
開発

補足:配列のサイズは後から変更できない

Section titled “補足:配列のサイズは後から変更できない”

C# の配列は、一度作ったら要素数を変更できません

int[] scores = new int[3];
// 後から「やっぱり 5 個にしたい」はできない
// scores.Length = 5; ← エラー(Length は読み取り専用)

要素数を変えたい場合は、別の配列を作って中身をコピーする必要があります。

業務アプリでは「件数が事前に分からない」「途中で追加・削除したい」というケースが多くあります。そのような場面では、配列より柔軟な List<T> という仕組みを使います。詳しくは 第 12 章「List と LINQ」 で学習します。

この章では、「件数が決まっているデータをまとめて扱う」ときに配列を使う、と覚えておけば十分です。


配列は、入力された値を順番に保存するときにも使えます。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = new int[3];
for (int i = 0; i < scores.Length; i++)
{
Console.WriteLine($"{i + 1}人目の点数を入力してください。");
string input = Console.ReadLine();
scores[i] = int.Parse(input);
}
Console.WriteLine("入力された点数:");
for (int i = 0; i < scores.Length; i++)
{
Console.WriteLine(scores[i]);
}
}
}
}

実行例:

1人目の点数を入力してください。
80
2人目の点数を入力してください。
75
3人目の点数を入力してください。
90
入力された点数:
80
75
90

入力ループと表示ループを分けることで、「全員分入力してから一覧表示する」という処理が書けます。


入力した点数から合計・平均・最高点を求めます。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = new int[3];
for (int i = 0; i < scores.Length; i++)
{
Console.WriteLine($"{i + 1}人目の点数を入力してください。");
string input = Console.ReadLine();
scores[i] = int.Parse(input);
}
int total = 0;
int maxScore = scores[0];
for (int i = 0; i < scores.Length; i++)
{
total += scores[i];
if (scores[i] > maxScore)
{
maxScore = scores[i];
}
}
double average = (double)total / scores.Length;
Console.WriteLine($"合計点:{total}");
Console.WriteLine($"平均点:{average}");
Console.WriteLine($"最高点:{maxScore}");
}
}
}

実行例:

1人目の点数を入力してください。
80
2人目の点数を入力してください。
75
3人目の点数を入力してください。
90
合計点:245
平均点:81.66666666666667
最高点:90

最高点を求める処理のポイントは、最初の要素を仮の最高点として設定し、それより大きい値があれば更新していく点です。

int maxScore = scores[0]; // 最初の要素を仮の最高点に設定
for (int i = 0; i < scores.Length; i++)
{
if (scores[i] > maxScore)
{
maxScore = scores[i]; // より大きい値があれば更新
}
}

配列の中に特定の値があるかどうかを調べます。

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
string[] employeeNames = { "山田二郎", "佐藤昭夫", "山口洋子", "田中浩介" };
Console.WriteLine("検索する社員名を入力してください。");
string keyword = Console.ReadLine();
bool found = false;
for (int i = 0; i < employeeNames.Length; i++)
{
if (employeeNames[i] == keyword)
{
found = true;
break;
}
}
if (found)
{
Console.WriteLine("該当する社員が見つかりました。");
}
else
{
Console.WriteLine("該当する社員は見つかりませんでした。");
}
}
}
}

実行例:

検索する社員名を入力してください。
佐藤昭夫
該当する社員が見つかりました。

bool found = false で「まだ見つかっていない」という状態を作り、見つかったら true にして break します。


foreach 文は、配列の要素を先頭から順に 1 つずつ取り出すための構文です。

foreach (型 変数名 in 配列)
{
繰り返したい処理
}

for 文のようにインデックスを書く必要がなく、「全要素を順番に処理する」という意図がシンプルに伝わります。


Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
string[] employeeNames = { "山田二郎", "佐藤昭夫", "山口洋子", "田中浩介" };
foreach (string employeeName in employeeNames)
{
Console.WriteLine(employeeName);
}
}
}
}

実行結果:

山田二郎
佐藤昭夫
山口洋子
田中浩介

employeeNames の要素が先頭から順番に employeeName に入り、処理が実行されます。


Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[] scores = { 80, 75, 90, 68, 85 };
int total = 0;
foreach (int score in scores)
{
total += score;
}
double average = (double)total / scores.Length;
Console.WriteLine($"合計点:{total}");
Console.WriteLine($"平均点:{average}");
}
}
}

実行結果:

合計点:398
平均点:79.6

構文向いている場面
forインデックス番号が必要な場合(番号表示・最大値探索・値の書き換えなど)
foreach全要素を順番に取り出すだけでよい場合

注意:foreach で取り出した変数には代入できません

foreach (int score in scores)
{
score = 100; // エラー
}

配列の値を変更したい場合は for 文を使ってください。


これまで扱った配列は 1 列に並んだデータを管理するものでした。

2 次元配列は、行と列を持つ表のようなデータを管理できます。

1科目目 2科目目 3科目目
1人目 80 75 90
2人目 68 85 72
3人目 90 88 95

Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[,] scores =
{
{ 80, 75, 90 },
{ 68, 85, 72 },
{ 90, 88, 95 }
};
Console.WriteLine(scores[0, 0]); // 1人目・1科目目
Console.WriteLine(scores[1, 2]); // 2人目・3科目目
Console.WriteLine(scores[2, 1]); // 3人目・2科目目
}
}
}

実行結果:

80
72
88

2 次元配列では scores[行, 列] の形でアクセスします。行も列もインデックスは 0 から始まります。


2 重ループで 2 次元配列を表示する

Section titled “2 重ループで 2 次元配列を表示する”
Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[,] scores =
{
{ 80, 75, 90 },
{ 68, 85, 72 },
{ 90, 88, 95 }
};
for (int row = 0; row < scores.GetLength(0); row++)
{
for (int col = 0; col < scores.GetLength(1); col++)
{
Console.Write($"{scores[row, col]}\t");
}
Console.WriteLine();
}
}
}
}

実行結果:

80 75 90
68 85 72
90 88 95

scores.GetLength(0) は行数、scores.GetLength(1) は列数を返します。1 次元配列の Length に相当するものが、2 次元配列では GetLength(次元番号) になります。


Program.cs
namespace Ch06_Array
{
internal class Program
{
static void Main(string[] args)
{
int[,] scores =
{
{ 80, 75, 90 },
{ 68, 85, 72 },
{ 90, 88, 95 }
};
for (int row = 0; row < scores.GetLength(0); row++)
{
int total = 0;
for (int col = 0; col < scores.GetLength(1); col++)
{
total += scores[row, col];
}
Console.WriteLine($"{row + 1}人目の合計点:{total}");
}
}
}
}

実行結果:

1人目の合計点:245
2人目の合計点:225
3人目の合計点:273

total を外側ループの中で初期化することで、1 人ごとに合計をリセットしています。


補足:プロパティとメソッド

scores.Lengthscores.GetLength(0) は、どちらも配列の情報を取得しますが、形が違います。

種類特徴
プロパティscores.Length() がない。情報を取り出す
メソッドscores.GetLength(0)() がある。処理を呼び出す

第 7 章以降でクラスを学ぶときに、プロパティとメソッドの違いを詳しく扱います。今は「() があるかどうかで区別できる」と覚えておきましょう。


つまずき原因対応
scores[5] でエラーになる存在しないインデックスにアクセスしている要素数 5 なら最後は scores[4]
i <= scores.Length と書いてエラーになる最後に範囲外アクセスしているi < scores.Length と書く
インデックスが 1 から始まると思ってしまう人間の数え方と混同しているC# の配列は 0 から始まる
Length<= scores.Length と書いてしまう最後のインデックスと要素数を混同要素数 5 → 最後のインデックスは 4
int[] backup = scores;backup を変更したら scores も変わってしまう配列は参照型で、代入はコピーではない第 11 章で詳しく学習。今は「同じ配列を指す」とだけ覚える
配列の要素数を増やしたい配列はサイズ変更不可第 12 章の List<T> を使う(本章では扱わない)
foreach で何番目か分からないforeach はインデックスを扱わない番号が必要なら for 文を使う
foreach の変数に代入しようとするforeach の変数は読み取り専用値を変更するなら for 文を使う
2 次元配列の行と列が逆になるscores[row, col] の意味が曖昧先に行・次に列と覚える
合計用変数の初期化位置を間違えるどこで初期化すべきか分からない行ごとに合計するなら外側ループの中で初期化する

  • 配列とは何かを説明できる
  • int[]string[] の意味を説明できる
  • 配列のインデックスが 0 から始まることを説明できる
  • 配列の要素にアクセスできる
  • Length を使って配列の要素数を取得できる
  • for 文で配列の要素を順番に処理できる
  • 入力された値を配列に保存できる
  • 最高値を求める処理の考え方を説明できる
  • foreach 文で配列の要素を順番に取り出せる
  • for 文と foreach 文の使い分けを説明できる
  • 2 次元配列の基本を説明できる
  • 配列を別の変数に代入してもコピーされないことを知っている
  • 配列の要素数は後から変更できないことを知っている

  1. 配列はどのようなときに使いますか。
  2. scores[0] は何を表していますか。
  3. 要素数が 5 の配列で、最後のインデックスはいくつですか。
  4. scores.Length は何を表していますか。
  5. for 文と foreach 文はどのように使い分けますか。
  6. 2 次元配列では scores[1, 2] はどのように読みますか。
  7. int[] backup = scores; で何が起きていますか。
  8. 「件数が後から増えるかもしれない」場面では、配列の代わりに何を使いますか。

この章の演習課題に取り組みます。

本章では タイマー方式 を試験導入します。次の 3 段階で進めてください。

段階時間内容
① 準備10 分(目安)上の「ペア確認」と、これから取り組む課題(仕様)の読み込み。ペアや講師に質問してよい
② ソロ作業30 分(タイマーで計測)一人で課題に取り組む。タイマーが鳴ったら、完成・未完成にかかわらず作業を止めて提出する
③ チーム時間講師が指定する発表開始時刻までチーム内でコードレビューを行い、発表者を決める。実装の続行も可。時間配分はチームで管理する

準備フェーズの終わりに講師が号令をかけ、そこから ソロ作業の 30 分タイマー を開始します。 評価対象はタイマー時点で提出されたコードです(タイマー後に書き足した分は評価には含まれません)。 発表開始時刻は厳守 です。チーム時間中も、その時刻が来たら全員手を止めて発表に移ります。

演習の進め方の詳細は、付録A「演習の進め方」 を参照してください。


課題はソリューション Kadai06 の中に作成してください。

各課題のプロジェクト名は次の通りです。

課題プロジェクト名
課題6-1Kd06_01_ArrayBasic
課題6-2Kd06_02_InputAndStats
課題6-3Kd06_03_EmployeeList
課題6-4(発展)Kd06_04_AboveAverage
課題6-5(発展)Kd06_05_TopScorer
課題6-6(発展)Kd06_06_ScoreDistribution
課題6-7(発展)Kd06_07_SubjectAverage

補足:ソリューションに複数のプロジェクトを追加する方法

最初の課題で Kadai06 ソリューションと Kd06_01_ArrayBasic プロジェクトを同時に作成します。

2 つ目以降の課題は、ソリューションエクスプローラーで Kadai06 を右クリックし、追加新しいプロジェクト から追加します。


以下は、本章のすべての課題に共通する作業です。各課題の本文には繰り返し書きません。

作業内容参照
プロジェクト作成時の設定最上位レベルのステートメントを使用しない」にチェック第 1 章 1-1
csproj の編集<Nullable>disable</Nullable> に変更第 1 章 1-1
コードを書く場所Main メソッドの中(本章 6-1 などのサンプル形式と同じ)6-1
ファイルを保存して実行Ctrl + S で保存 → F5 で実行第 1 章 1-2

特に 2 つ目以降のプロジェクト(Kd06_02_InputAndStats など)も、新規追加するたびに csproj の Nullable を disable に変更する 必要があります。忘れると警告が出やすくなります。

演習課題のコードは、本文と同じ namespace + class Program + Main の枠組みの中に書きます。

提出ルール(タイマー方式)

  • 準備フェーズの後、講師の号令で 30 分のタイマー をスタートします
  • タイマーが鳴ったら、完成・未完成にかかわらず手を止め、その場で git addgit commitgit push を行います
  • これがこの演習の 唯一の提出 です。タイマー後も実装を続けて構いませんが、書き足した分は評価対象には含まれません

コミットメッセージの形式:

Chapter06 タイマー提出: <どの課題まで完成> / <詰まったポイント>

例:

  • Chapter06 タイマー提出: 6-1〜6-2完成、6-3は途中 / 6-3 の i + 1 の使いどころで詰まっている
  • Chapter06 タイマー提出: 6-1〜6-3全て完成、発展未着手 / 特になし
  • Chapter06 タイマー提出: 6-1の途中まで / Length の使い方が分からない

「どこまでできたか」「詰まったポイント」は短くて構いません。順調なときも「特になし」と明示 してください(順調さの証拠になります)。

提出方法:Git が使えないときはサーバへコピー

Git の状態によっては、講師から「今回は push ではなくサーバへのフォルダコピーで提出」と指示が出ることがあります。その場合は、push の代わりに Kadai06 フォルダをサーバの所定の場所へコピーして提出してください(コピー手順は別途案内済みのとおり)。

このとき コミットメッセージが残せない ため、代わりに 提出メモ.txt というテキストファイルを提出先に作成します。コピーが終わってから、次の手順で作成してください。

  1. Kadai06 フォルダをコピーした、サーバ上の自分の名前のフォルダをエクスプローラーで開く
  2. 何もないところで右クリック → 新規作成 → テキスト ドキュメント を選ぶ
  3. ファイル名を 提出メモ.txt に変更する
  4. ダブルクリックで開き、次の内容を書いて保存する
どこまで完成: 6-1〜6-3完成、発展未着手
詰まったポイント: 特になし

書く内容は、コミットメッセージに書くはずだった「どこまで完成したか」「詰まったポイント」と同じです。順調なときも「詰まったポイント: 特になし」と明示 してください。

タイマー後のチーム時間の使い方

タイマー後、講師が指定する 発表開始時刻 までがチーム時間です。チーム内で次の 3 つを自由に管理してください。

  • コードレビュー:他のメンバーの commit を読んで、気づいたことを共有する
  • 発表者の選出:発表開始時刻に、チームから 1 人が要点を発表できるよう、誰が話すかを決めておく
  • 実装の続行(任意):途中だった課題を続けても構いません(提出後の追加分は評価対象外ですが、理解を深める意義はあります)

どの順番で進めるか、何分ずつ使うかはチームの判断です。ただし 発表開始時刻は厳守 です。その時刻までにレビューと発表者選出を必ず終わらせてください。



課題6-1 点数配列の合計と平均を求める

Section titled “課題6-1 点数配列の合計と平均を求める”

次の点数を配列に入れ、合計点と平均点を表示してください。

80, 75, 90, 68, 85

実行結果:

合計点:398
平均点:79.6

条件:

  • int[] を使って初期値ありで宣言する
  • for 文と Length を使って合計する
  • 平均は小数で表示する

課題6-2 N 人分の点数を入力して集計する

Section titled “課題6-2 N 人分の点数を入力して集計する”

何人分の点数を入力するかをキーボードから受け取り、その人数分の点数を入力して合計・平均・最高点を表示してください。

実行例:

何人分入力しますか。
4
1人目の点数を入力してください。
72
2人目の点数を入力してください。
88
3人目の点数を入力してください。
91
4人目の点数を入力してください。
65
合計点:316
平均点:79.0
最高点:91

条件:

  • new int[n] で要素数を動的に決める
  • 入力と集計をそれぞれ for 文で処理する
  • 最高点は最初の要素を仮の最高点として更新する

課題6-3 社員名一覧を番号付きで表示する

Section titled “課題6-3 社員名一覧を番号付きで表示する”

次の社員名を配列に入れ、番号付きで表示してください。

山田二郎, 佐藤昭夫, 山口洋子, 田中浩介

実行結果:

1番目:山田二郎
2番目:佐藤昭夫
3番目:山口洋子
4番目:田中浩介

条件:

  • string[] を使う
  • for 文を使う
  • 表示番号は 1 から始める(i + 1

発展課題は、講義サンプルの写経では解けません。これまで学んだ配列・forif を組み合わせて考えてください。必須課題が終わった人から取り組みます。


課題6-4 平均点を超えた人を数える

Section titled “課題6-4 平均点を超えた人を数える”

次の点数を配列に入れ、まず平均点を求めます。そのうえで、平均点を 超えた 人数と、その点数の一覧を表示してください。

68, 92, 75, 88, 71, 95, 80, 63

実行結果:

平均点:79
平均点を超えた人数:4人
平均点を超えた点数:92 88 95 80

条件:

  • int[] を初期値ありで宣言する
  • 配列を 2 回走査 する(1 回目で合計から平均を求め、2 回目で平均超えを判定する)
  • 平均は double で求める
  • 「平均点を超えた」は平均より大きい(>)で判定する

ヒント

平均点が決まらないと「超えたかどうか」は判定できません。1 つの for 文の中で同時にやろうとすると難しいので、合計を求めるループ判定するループ を分けて 2 回まわすのがコツです。


社員名の配列と点数の配列を用意します。同じインデックスが同じ人 を表します。

名前:山田二郎, 佐藤昭夫, 山口洋子, 田中浩介, 加藤昭彦
点数:78, 92, 85, 67, 88

最高点を取った人の名前と点数を表示してください。

実行結果:

最高得点者:佐藤昭夫さん(92点)

条件:

  • string[]int[] の 2 本の配列を使う
  • 最高点だけでなく、それが 何番目(インデックス) かも変数で覚えておく
  • for 文で比較し、より高い点が見つかったら 点数とインデックスの両方 を更新する

ヒント

「最高点」を覚える変数だけでは、後で名前を表示できません。int maxIndex = 0; のような変数も用意し、点数を更新するときに maxIndex も一緒に更新します。最後に names[maxIndex] で名前を取り出せます。


課題6-6 点数の度数分布を表示する

Section titled “課題6-6 点数の度数分布を表示する”

次の点数を配列に入れ、3 つの区分ごとに何人いるかを数えて表示してください。

82, 75, 91, 58, 67, 88, 73, 95, 49, 80

区分:

区分範囲
80 点以上
60 〜 79 点
60 点未満

実行結果:

80点以上:5人
60〜79点:3人
60点未満:2人

条件:

  • 集計用に int[] counts = new int[3] を用意する(counts[0] = 高、counts[1] = 中、counts[2] = 低)
  • for 文で点数を 1 つずつ見て、if / else if で該当する区分のカウンタを 1 増やす
  • 最後に 3 つのカウンタを表示する

ヒント

区分ごとに別々の変数を 3 つ作ってもよいですが、配列をカウンタとして使うと「何番目の区分か」を数字で扱えます。counts[0]++ のように、配列の要素を直接 1 増やせます。


課題6-7 科目ごとの平均点を求める

Section titled “課題6-7 科目ごとの平均点を求める”

4 人分・3 科目の点数を 2 次元配列で管理し、科目ごと の平均点を表示してください。

点数:

1科目目 2科目目 3科目目
1人目 80 75 90
2人目 68 85 72
3人目 90 88 95
4人目 76 60 81

実行結果:

1科目目の平均点:78.5
2科目目の平均点:77
3科目目の平均点:84.5

条件:

  • int[,] を使う
  • 講義(6-6「行ごとの合計を求める」)では行を外側ループにしたが、今回は列(科目)を外側ループ にする
  • GetLength(0) は人数(行数)、GetLength(1) は科目数(列数)
  • 平均は double で求める

ヒント

「科目ごと」に集計するので、外側のループで科目(列)を 1 つ選び、内側のループでその科目の全員(行)の点数を足します。講義サンプルとループの内側・外側が入れ替わる点に注意してください。


  • プログラムを Visual Studio から実行できる
  • 配列を宣言できている
  • インデックスが 0 から始まることを意識できている
  • Length を使っている
  • for 文の条件式が i < scores.Length になっている
  • 入力値を配列に保存できている
  • 最高値を求める処理で最初の要素を初期値にしている
  • インデントが整っている
  • 課題を提出した(Git の commitpush、または講師指示があれば Kadai06 フォルダをサーバへコピーし、提出先フォルダに 提出メモ.txt を作成)

タイマーが鳴ったら、第 6 章の課題プロジェクト群(Kadai06 ソリューション)をその場で Git に提出します。

Terminal window
git status
git add .
git commit -m "Chapter06 タイマー提出: <どこまで完成> / <詰まったポイント>"
git push

実行例:

Terminal window
git commit -m "Chapter06 タイマー提出: 6-1〜6-2完成、6-3は途中 / 6-3 の i + 1 の使いどころで悩んだ"

Git の詳しい操作は、付録 C「Git のインストールと提出ルール」 を参照してください。

コミットメッセージの形式は、本章冒頭「演習課題 > 提出ルール(タイマー方式)」を参照してください。

サーバへのコピーで提出する場合

講師から指示があった場合は、push の代わりに Kadai06 フォルダをサーバへコピーして提出します。コピー後、提出先(サーバ上の自分の名前のフォルダ)をエクスプローラーで開き、右クリック → 新規作成 → テキスト ドキュメント で 提出メモ.txt を作って「どこまで完成」「詰まったポイント」を書いてください。詳しくは本章冒頭「演習課題 > 提出方法:Git が使えないときはサーバへコピー」を参照してください。


この章で学んだ主な内容は次の通りです。

  • 配列は同じ型の複数の値をまとめて管理する仕組みである
  • int[]string[][] が「配列」を意味する
  • 配列のインデックスは 0 から始まる(要素数 5 なら最後は [4])
  • Length で要素数を取得できる。for 文の条件は i < 配列.Length
  • 配列は初期値ありと new 型[要素数] の 2 通りで作れる
  • 配列を別の変数に代入しても中身はコピーされない(参照型・第 11 章で詳しく学ぶ)
  • 配列の要素数は後から変更できない。動的に増減したい場合は List<T>(第 12 章)
  • 入力した値を配列に保存して後から処理できる
  • 最高値・最低値の探索は最初の要素を仮の値として更新していく
  • foreach 文は全要素を順番に取り出すシンプルな書き方
  • インデックスが必要なら for 文、不要なら foreach 文を使う
  • 2 次元配列では [行, 列] でアクセスし、GetLength(0) で行数・GetLength(1) で列数を取得する

次章からは オブジェクト指向プログラミング に入ります。

第 7 章では、複数のデータと処理を 1 つのまとまりとして扱う クラス を学びます。

また、第 7 章からはコードの書き方が少し変わります。namespace の書き方が次のように変わります。

// これまで(第1〜6章) — ブロック形式 namespace
namespace Ch06_Array
{
internal class Program
{
...
}
}
// 第7章から — ファイルスコープ namespace
namespace Ch07_Class;
internal class Program
{
...
}

インデントが 1 段浅くなり、コードが読みやすくなります。詳しくは第 7 章で説明します。