C#
 Computer >> コンピューター >  >> プログラミング >> C#

C#の配列の基本を徹底解説!宣言・初期化からループ処理・既定値まで

配列(Array)とは、同じ型の要素を固定数だけ格納できるデータ構造です。要素はメモリ上の連続した領域に保存されており、インデックスさえ分かれば非常に高速にアクセスできるという特徴があります。

この記事では、C#における配列の宣言・初期化の方法から、要素へのアクセス、ループ処理、そして見落としがちな「既定値」の挙動まで、サンプルコード付きでわかりやすく解説します。

配列の宣言と初期化

C#で配列を宣言・初期化する基本的な構文は以下のとおりです。

// 3つの言語名を格納する文字列配列を作成
string[] languages = new string[3];

配列を宣言した後は、角括弧([])を使って各要素に値を代入できます。

languages[0] = "csharp";
languages[1] = "visual basic";
languages[2] = "f#";

宣言と初期化を1行でまとめる簡潔な書き方

実は、上記の2つのステップは次のように1行でまとめて記述することも可能です。

string[] languages = new string[] { "csharp", "visual basic", "f#" };

さらに、C#の暗黙的に型指定される変数(var)を利用すれば、左辺の型指定を省略してより簡潔に書けます。

var languages = new string[] { "csharp", "visual basic", "f#" };

配列の要素へのアクセス

配列の任意の要素には、同じく角括弧記法でアクセスします。

string language = languages[0];
Console.WriteLine(language); // csharp と出力される

また、Length プロパティを使えば、配列に含まれる要素数を取得できます。

int count = languages.Length;
Console.WriteLine(count); // 3

注意点:配列のサイズは変更できない

重要なポイントとして、配列は一度作成するとサイズを変更できません。また、配列の範囲外にあるインデックスにアクセスしようとすると、例外がスローされます。

string lang = languages[3]; // System.IndexOutOfRangeException が発生

forループとforeachループによる繰り返し処理

配列の全要素を順番に処理したい場合は、言語が提供する for 文または foreach 文を使用します。

// forループ
for (int i = 0; i < languages.Length; i++)
{
    string l = languages[i];
    Console.WriteLine(l); // 言語名が順に出力される
}

// foreachループ
foreach (string l in languages)
{
    Console.WriteLine(l); // 言語名が順に出力される
}

foreach の方がインデックス管理が不要でシンプルに書ける一方、インデックスが必要な場面では for ループが便利です。状況に応じて使い分けましょう。

配列の既定値(デフォルト値)

配列を作成すると、C#コンパイラは各要素をその型の既定値で自動的に初期化します。たとえば、int 型の配列を作成すると、すべての要素は 0 になります。

var numbers = new int[3];
foreach (int num in numbers)
{
    Console.WriteLine(num); // 0 が3回出力される
}

値型の場合

要素が値型(structなど)である場合、その型の各メンバーにも既定値が割り当てられます。

Point[] a = new Point[4];
int x = a[2].X;
Console.WriteLine(x); // 0 が出力される

public struct Point { public int X, Y; }

参照型の場合

一方、参照型(classなど)の場合、コンパイラは各要素に対して null 参照を作成するだけです。そのため、初期化せずにメンバーへアクセスするとエラーになります。

User[] u = new User[4];
int y = u[2].Y; // NullReferenceException が発生

public class User { public int X, Y; }

このエラーを回避するには、次のように各要素を明示的に初期化する必要があります。

User[] users = new User[5];
for (int i = 0; i < users.Length; i++)
{
    users[i] = new User();
}

完全なサンプルコード

ここまでの内容をすべて含む実行可能なサンプルコードがこちらです。

using System;

class Program
{
    static void Main()
    {
        // 文字列配列を作成して値を代入
        string[] languages = new string[3];
        languages[0] = "csharp";
        languages[1] = "visual basic";
        languages[2] = "f#";

        // 宣言と初期化を同時に行うパターン
        string[] languagesTwo = new string[] { "csharp", "visual basic", "f#" };
        var languagesThree = new string[] { "csharp", "visual basic", "f#" };

        // 要素へのアクセス
        string language = languages[0];
        Console.WriteLine(language); // csharp

        // 要素数の取得
        int count = languages.Length;
        Console.WriteLine(count); // 3

        // string lang = languages[3]; // 範囲外アクセスで例外が発生するためコメントアウト

        // forループ
        for (int i = 0; i < languages.Length; i++)
        {
            string l = languages[i];
            Console.WriteLine(l);
        }

        // foreachループ
        foreach (string l in languages)
        {
            Console.WriteLine(l);
        }

        // 値型の配列は既定値 0 で初期化される
        var numbers = new int[3];
        foreach (int num in numbers)
        {
            Console.WriteLine(num); // 0 が3回出力される
        }

        Point[] a = new Point[4];
        int x = a[2].X;
        Console.WriteLine(x); // 0

        // 参照型の配列は null で初期化されるため、使用前に初期化が必要
        User[] u = new User[4];
        // int y = u[2].Y; // NullReferenceException が発生するためコメントアウト

        User[] users = new User[5];
        for (int i = 0; i < users.Length; i++)
        {
            users[i] = new User();
        }
    }
}

public struct Point { public int X, Y; }
public class User { public int X, Y; }

実行結果

csharp
3
csharp
visual basic
f#
csharp
visual basic
f#
0
0
0
0

まとめ

C#の配列は、固定長でありながら高速なアクセスを実現する基本的かつ重要なデータ構造です。押さえておきたいポイントは以下の4つです。

  • 配列は作成後にサイズを変更できず、範囲外アクセスは例外になる
  • 宣言と初期化は1行でまとめて書けるほか、var で型推論も可能
  • 値型の配列は各要素が既定値(0など)で自動初期化される
  • 参照型の配列は null で初期化されるため、使用前に明示的な初期化が必要

これらの特性を理解しておけば、配列に関する予期しないエラーを防ぎ、安全で効率的なコードを書けるようになります。

  1. Wi-Fiエクステンダーの仕組みとは?導入前に知っておきたい基礎知識と選び方

    Wi-Fiエクステンダーは、その名のとおりWi-Fi電波の届く範囲を広げる機器です。自宅のより多くの場所でインターネットを快適に利用できるようになります。広い住まいや職場、複数階建ての建物、厚い壁やその他の障害物がある環境では、Wi-Fiエクステンダーが電波を建物全体に行き渡らせてくれます。 Wi-Fiエクステンダーの仕組み Wi-Fiエクステンダーはルーターと無線で接続し、ルーターの電波が届かないエリアへ信号を拡張します。最適な設置場所を決めるまでには、多少の試行錯誤が必要になるかもしれません。 Wi-Fiエクステンダーには主に2つのタイプがあります。コンセントに直接差し込む小型タイプと、有

  2. JavaScriptで配列をreduceする方法|reduce()メソッドで配列要素を合計する

    JavaScriptのreduce()メソッドは、配列の各要素を先頭から順に処理し、その結果を1つの値にまとめる(畳み込む)ための配列メソッドです。数値の合計を求めるだけでなく、配列からオブジェクトを組み立てたり、条件に応じてデータを集約したりと、幅広い場面で活用されています。reduce()メソッドの基本構文 { return 戻り値; }, 初期値);accumulator(アキュムレータ):直前のコールバック関数が返した値(累積値)。最初のループでは初期値、または配列の第1要素が代入されます。currentValue:現在処理している配列の要素。初期値:累積値の出発点となる値。省略し