構造体とは? わかりやすく解説

構造体

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2025/05/23 23:36 UTC 版)

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

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

クラスベースオブジェクト指向言語では、抽象データ型としてのクラスが構造体の役割をも内包する。Cの文法を継承した言語ではstructキーワードを含むこともあるが、言語によってその役割や性質は異なる。

  • C++structは、アクセシビリティの初期値がpublicであることを除いて、classと同等の機能を果たす。メンバー変数だけでなくメンバー関数を持つこともでき、派生型を定義することもできる。
  • Javaでは、structキーワードは存在しない。すべてのユーザー定義型は参照型であり、構造体に相当するデータ構造はclassキーワードを使ってクラスとして実現する必要がある。Java 16ではイミュータブルな「レコードクラス」をサポートする[2][3]
  • Kotlinでは、データを保持するためだけのクラスとして、data class構文により「データクラス」を定義することができる[4]。データクラスはミュータブル[注釈 1]だが、通常のクラス同様に参照型であることには変わりなく、変数の代入は参照のみのコピーとなる。そのため、すべてのプロパティをコピーした新たなオブジェクトを生成するには、コンパイラの推論によって暗黙的に自動定義されたcopy()関数を使うなどする。サブクラスを定義することはできない。
  • C#では、構造体の定義にstructキーワードを使用する[5]classキーワードにより定義されるクラス[6]は「参照型」である一方、構造体は軽量なオブジェクト型を定義するための「値型」であり、クラスと比較していくつかの制約がある。
  • VB.NETでは、構造体の定義にStructureキーワードを使用する[7]。姉妹言語であるC#の構造体と類似の機能である。
  • Swiftでは、構造体の定義にstructキーワードを使用する。C#と同様、classキーワードにより定義されるクラスは参照型である一方、構造体は値型である[8][9]。SwiftのクラスはObjective-Cのクラスに対応する概念であり相互運用できるが、構造体は相互運用することができない。

オブジェクト指向言語でないCなどでオブジェクト指向プログラミングを模倣するために構造体を使うこともある。

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;
}

下記は構造体へのポインタをユーザー定義のオブジェクト型のハンドルとして利用する例である。

/* MyObject.h */
/* 構造体の前方宣言 */
typedef struct MyObject MyObject;

extern MyObject* MyObject_create(void); /* コンストラクタの代替 */
extern void MyObject_destroy(MyObject* obj); /* デストラクタの代替 */
extern void MyObject_setPosition(MyObject* obj, double x, double y);
extern void MyObject_getPosition(const MyObject* obj, double* outX, double* outY);
/* MyObject.c */
#include <stdlib.h>
#include <assert.h>
#include "MyObject.h"

/* 構造体の定義 */
struct MyObject {
    double x, y;
};

MyObject* MyObject_create(void) {
    return calloc(1, sizeof(MyObject));
}
void MyObject_destroy(MyObject* obj) {
    free(obj);
}
void MyObject_setPosition(MyObject* obj, double x, double y) {
    assert(obj);
    obj->x = x;
    obj->y = y;
}
void MyObject_getPosition(const MyObject* obj, double* outX, double* outY) {
    assert(obj && outX && outY);
    *outX = obj->x;
    *outY = obj->y;
}

近代的なAPI設計では、このようにしてC互換のオブジェクト指向インターフェイスを定義することがよくある。例えばOpenCL[10]Vulkan[11]などで類似の手法が実際に利用されている。ヘッダーでは構造体の前方宣言だけをすることにより、構造体の具体的な詳細(定義)はAPIのユーザーからは隠蔽されており、不透明な型 (opaque type) として扱われる(カプセル化)。

この手法を使うことで、C互換のインターフェイスを維持しつつ、API関数の実装をCだけでなくC++や他の言語で記述することもできるようになる。また、オブジェクトの生成・破棄を含むあらゆる操作をAPI関数経由に限定し、オブジェクトハンドルを介した操作のみを提供することで、異なるABI間でも正しくオブジェクトをやりとりすることができるため、C/C++以外の他の言語向けバインディング(ラッパーライブラリ)を記述することも容易になる。

C#の例

C#における構造体は、小規模なデータ構造の定義に適した値型 (value type) である[5]。C#におけるクラスはヒープ割り当てを必要とし、完全な継承機能をサポートする参照型 (reference type) である[6]一方、構造体はヒープ割り当てを必要としない軽量な値型であり、代わりに派生型を定義できないなど、制限されたクラスとして振る舞う。クラスと構造体の使い分けに関しては、ガイドラインが提示されている[12]

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

// int 型の数値リテラルも構造体 (System.Int32) のインスタンスであり、オブジェクトである。
string str = 123.ToString();

structキーワードを使用した、ユーザー定義の構造体の例を下に示す。プロパティやメソッド定義の一部にC# 6.0やC# 7.0で追加された糖衣構文が使用されているが、構造体自体はC# 1.0当初から存在する言語機能である。なお、C#の構造体は引数付きコンストラクタをユーザー定義することはできるが、引数のないコンストラクタ(デフォルトコンストラクタ)をユーザー定義することはできない。また、フィールドやプロパティを宣言時初期化することもできない。引数のないコンストラクタでは、各フィールドはその型の既定値で初期化される。C# 10.0以降の構造体は、引数のないコンストラクタをユーザー定義することもできるようになった[13]

using System;

public struct MutablePoint {
    /// <summary>カプセル化されたフィールド。</summary>
    private int _x, _y;
    /// <summary>X座標を取得・設定するプロパティ。</summary>
    public int X {
        get => _x;
        set => _x = value;
    }
    /// <summary>Y座標を取得・設定するプロパティ。</summary>
    public int Y {
        get => _y;
        set => _y = value;
    }
    /// <summary>原点からの距離を取得するプロパティ。</summary>
    public double Distance => Math.Sqrt((double)_x * (double)_x + (double)_y * (double)_y);
    /// <summary>引数付きコンストラクタ。</summary>
    public MutablePoint(int x, int y) {
        _x = x;
        _y = y;
    }
    /// <summary>System.ValueTypeのToString()メソッドをオーバーライド。</summary>
    public override string ToString() => $"({_x}, {_y})";
}

class Test {
    // フィールドで定義された構造体内の全てのフィールドはデフォルト値0で初期化されている。
    static MutablePoint s_point;
    static void Main() {
        Console.WriteLine(s_point.ToString()); // (0, 0) が表示される。
        // デフォルトコンストラクタ呼び出し。
        var zeroPoint = new MutablePoint();
        Console.WriteLine(zeroPoint.ToString()); // (0, 0) が表示される。
        // 引数付きコンストラクタ呼び出し。
        var point = new MutablePoint(5, 11);
        Console.WriteLine(TranslatePoint(point, 1, -9).ToString()); // (6, 2) が表示される。
        Console.WriteLine(point.ToString()); // (5, 11) が表示される。
        TranslatePoint(ref point, -2, 3);
        Console.WriteLine(point.ToString()); // (3, 14) が表示される。

        Console.WriteLine("Press any...");
        Console.ReadKey(true);
    }

    // 構造体型 (値型) は、仮引数に値のコピーが渡されるため、
    // メソッド内での仮引数の操作によって呼び出し元の実引数の値が変更されることはない。
    // 引数がrefパラメータならば、
    // あるいはMutablePoint型がstructではなくclassで宣言されていたならば、
    // 仮引数の状態の変更は実引数の状態に影響する。
    static MutablePoint TranslatePoint(MutablePoint p, int dx, int dy) {
        p.X += dx;
        p.Y += dy;
        return p;
    }
    static void TranslatePoint(ref MutablePoint p, int dx, int dy) {
        p.X += dx;
        p.Y += dy;
    }
}

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

C#の構造体は属性によってメモリレイアウトを明示的に指定することができるため、C/C++の構造体との相互運用に便利である。Windows APIなどで定義されている構造体と互換性のある型をC#の構造体によってユーザー定義することで、P/Invokeに利用できる。

VB.NETF#といった.NET言語も、構文は異なるがC#と同様の構造体を備えている[7][14]

C++/CLIでは、value structまたはvalue classによって.NETの構造体型を定義することができる[15]

アライメント

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

脚注

注釈

  1. ^ データクラスのすべてのプロパティをvalで宣言することで、イミュータブルにすることもできる。

出典

関連項目


構造体

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/04/10 09:37 UTC 版)

リテラル」の記事における「構造体」の解説

初期化C言語C99規格以降では Designated Initializer (指示付き初期化子ないし指示初期化子)により、任意の構造体において任意のメンバ初期値について指示ができる。

※この「構造体」の解説は、「リテラル」の解説の一部です。
「構造体」を含む「リテラル」の記事については、「リテラル」の概要を参照ください。

ウィキペディア小見出し辞書の「構造体」の項目はプログラムで機械的に意味や本文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。 お問い合わせ

「構造体」の例文・使い方・用例・文例

Weblio日本語例文用例辞書はプログラムで機械的に例文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。



構造体と同じ種類の言葉


固有名詞の分類


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「構造体」の関連用語

構造体のお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



構造体のページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
日本マイクロソフト株式会社日本マイクロソフト株式会社
© 2025 Microsoft.All rights reserved.
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアの構造体 (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
ウィキペディアウィキペディア
Text is available under GNU Free Documentation License (GFDL).
Weblio辞書に掲載されている「ウィキペディア小見出し辞書」の記事は、Wikipediaのリテラル (改訂履歴)、神社建築 (改訂履歴)、Go (プログラミング言語) (改訂履歴)、BALDR SKY (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。
Tanaka Corpusのコンテンツは、特に明示されている場合を除いて、次のライセンスに従います:
 Creative Commons Attribution (CC-BY) 2.0 France.
この対訳データはCreative Commons Attribution 3.0 Unportedでライセンスされています。
浜島書店 Catch a Wave
Copyright © 1995-2025 Hamajima Shoten, Publishers. All rights reserved.
株式会社ベネッセコーポレーション株式会社ベネッセコーポレーション
Copyright © Benesse Holdings, Inc. All rights reserved.
研究社研究社
Copyright (c) 1995-2025 Kenkyusha Co., Ltd. All rights reserved.
日本語WordNet日本語WordNet
日本語ワードネット1.1版 (C) 情報通信研究機構, 2009-2010 License All rights reserved.
WordNet 3.0 Copyright 2006 by Princeton University. All rights reserved. License
日外アソシエーツ株式会社日外アソシエーツ株式会社
Copyright (C) 1994- Nichigai Associates, Inc., All rights reserved.
「斎藤和英大辞典」斎藤秀三郎著、日外アソシエーツ辞書編集部編
EDRDGEDRDG
This page uses the JMdict dictionary files. These files are the property of the Electronic Dictionary Research and Development Group, and are used in conformance with the Group's licence.

©2025 GRAS Group, Inc.RSS