構造体

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動先: 案内検索

構造体(こうぞうたい、: structure)はプログラミング言語におけるデータ型の一つで、1つもしくは複数の値をまとめて格納できる型。それぞれのメンバ(フィールド)は型が異なっていてもよい点が配列と異なる。

C/C++C#などでstructとしてサポートされているほか、Visual Basicのユーザ定義型や、PascalAdarecord型も構造体に相当する。

クラスベースオブジェクト指向言語では、抽象データ型としてのクラスが構造体の役割をも内包する。Cの文法を継承した言語ではstructキーワードを含むこともあるが、言語によってその役割は異なる。 例えば、C++ではアクセシビリティの初期値がpublicであることを除いては、classと同等の機能を持つことができる。 また、C#では値型として扱われる軽量なオブジェクト型を定義するためにstructキーワードを使用し、制限されたclassとして振る舞う。 同じくCの文法を継承したJavaでは、structキーワードは存在しない。

オブジェクト指向言語でないCなどでオブジェクト指向プログラミングを模倣するために構造体を使うこともある。標準ライブラリのFILE型がその典型的な例である。

C言語の例[編集]

#include <stdio.h>

/* PersonalDataを構造体として定義 */
struct PersonalData
{
  /* メンバ変数 (つまり構造体の要素) を名前と年齢とする */
  char Name[100];
  int Age;
};

/* 上で定義された構造体を使ってみる */
int main(void)
{
  struct PersonalData pd; /* 構造体変数の宣言 */
  struct PersonalData *ppd; /* 構造体へのポインタ */

  scanf("%s", pd.Name); /* 値を入力 */
  scanf("%d", &(pd.Age)); /* 値を入力 */

  ppd = &pd;
  ppd->Age++; /* ポインタの参照先のメンバにアクセスするには->を使う。*/

  printf("%s-%d\n", pd.Name, pd.Age);
  return 0;
}

C#の例[編集]

C#における構造体は、軽量のオブジェクトを表す値型である。 [1]

組み込みの軽量な型(bool,char,int,double,etc...)もまた構造体である。

// 数値も構造体であり、オブジェクトである。
string str = 123.ToString();

structキーワードを使用した、ユーザー定義の構造体の例を下に示す。

public struct ImmutablePoint {
    /// <summary>カプセル化されたフィールド</summary>
    private int _x, _y;
    /// <summary>X座標を取得するプロパティ。設定はできない</summary>
    public int X => _x;
    /// <summary>Y座標を取得するプロパティ。例示のため設定可能とした</summary>
    public int Y {
        get => _y;
        set => _y = value;
    }
    /// <summary>コンストラクタ</summary>
    public ImmutablePoint(int x,int y) {
        _x = x;
        _y = y;
    }
    /// <summary>System.ValueTypeのToString()メソッドをオーバーライド</summary>
    public override string ToString() => $"({_x},{_y})";
}

class Hogehoge {
    // フィールドで定義された構造体内の全てのフィールドは0初期化されている
    static ImmutablePoint s_point;
    static void Main() {
        // 下記は (0,0)が表示される
        Console.WriteLine(s_point.ToString());
        // 暗黙のインスタンス呼び出し
        var zeroPoint = new ImmutablePoint();
        // 下記は (0,0)が表示される
        Console.WriteLine(zeroPoint.ToString());

        // 明示的なインスタンス呼び出し
        var point = new ImmutablePoint(5, 11);
        ShowPoint(point);

        // 下記は (5,11)が表示される
        Console.WriteLine(point.ToString());

        Console.ReadLine();
    }

    // 構造体型(値型)は、仮引数に値のコピーが渡されるため、
    // メソッド内での仮引数の操作によって、実引数の値は変更されない。
    // もし、ImmutablePoint型がstructではなくclassで宣言されていたならば、
    // プロパティYへの値の設定は実引数の値に影響する。
    static void ShowPoint(ImmutablePoint p) {
        var x = p.X;
        var y = p.Y;
        // point.X = 2; 設定不可
        p.Y = 2;
        // 下記は (5,2)が表示される
        Console.WriteLine(p.ToString());
    }
}

C#のデータ型も参照のこと。

アライメント[編集]

構造体のメンバのメモリレイアウトは、必ずしも連続しているとは限らない。実行環境に合わせてアクセス効率が最適になるよう、コンパイラによってバイト境界に応じた無名の詰め物(パディング)が挿入されることがある。このパディングはシリアライズや相互運用などで問題になることがあるため、フィールド属性やコンパイラ特有のディレクティブによってアライメントを明示的に調整できる言語や処理系も存在する[2] [3]

脚注[編集]

[ヘルプ]

関連項目[編集]