Перейти до вмісту

struct (мова програмування C)

Матеріал з Вікіпедії — вільної енциклопедії.

У мові програмування C struct — ключове слово, яке використовують для визначення складеного типу даних (запису)  – розташованого в пам'яті іменованого набору значень. Це дозволяє отримати доступ до різних значень через один ідентифікатор (часто вказівник). Структура може містити дані різних типів. Наприклад, структура клієнта банку може містити поля: ПІБ, адреса, телефон, баланс.

Структура займає суцільний блок пам'яті, зазвичай вирівняний за межами слів. Аналогічна функція доступна в деяких асемблерах для процесорів Intel. Отже, кожне поле в ній розташоване з певним фіксованим зміщенням від початку.

Оператор sizeof[en], як і для примітивного типу даних, повертає кількість байтів, необхідних для збереження структури. Вирівнювання окремих полів у структурі (відносно меж слів) залежить від реалізації та може включати доповнення. Сучасні компілятори зазвичай підтримують директиву #pragma pack, яка встановлює розмір у байтах для вирівнювання[1].

Функцію C struct запозичено з однойменної концепції в ALGOL 68[en][2].

Оголошення

[ред. | ред. код]

Синтаксис для оголошення структури розглянемо на простому прикладі:

struct tag_name {
   type member1;
   type member2;
};

tag_name у деяких випадках зазначати не обов'язково.

За допомогою ключового слова typedef[en] на тип структури можна посилатися без використання ключового слова struct. Однак деякі посібники зі стилю програмування не радять цього, стверджуючи, що це може спричинити плутанину типів.

Наприклад:

typedef struct tag_name {
   type member1;
   type member2;
} thing_t;
thing_t thing;

У коді C++ typedef не потрібне, оскільки типи, визначені за допомогою struct є частиною звичайного простору назв, тому тип можна називати або struct thing_t або thing_t.

Ініціалізація

[ред. | ред. код]

Три способи ініціалізації структури розглянемо на прикладі такого типу:

struct point_t {
   int x;
   int y;
};

Коли можна задати суміжні члени, використовують ініціалізатори у стилі C89[3]:

struct point_t a = { 1, 2 };

Для несуміжного або непорядкового списку членів можна використати іменований стиль ініціалізатора[4]. Наприклад:

struct point_t a = { .y = 2, .x = 1 };

Якщо задано ініціалізатор або якщо об'єкт виділено статично, пропущені елементи ініціалізуються нулями. Третій спосіб ініціалізації структури полягає в тому, щоб скопіювати значення наявного об'єкта того ж типу:

struct point_t b = a;

Копіювати

[ред. | ред. код]

Стан структури можна скопіювати в інший примірник. Для копіювання байтів блоку пам'яті компілятор може використовувати memcpy().

struct point_t a = { 1, 3 };
struct point_t b;
b = a;

Вказівники

[ред. | ред. код]

Для посилання на struct за її адресою можна використовувати вказівники. Це корисно для передання структури у функцію, щоб уникнути витрат на копіювання структури. Оператор -> розіменовує вказівник (лівий операнд) і отримує доступ до значення члена структури (правий операнд).

struct point_t point = { 3, 7 };
int x = point.x;
point.x = 10;
struct point_t *pp = &point;
x = pp->x;
pp->x = 8;

В інших мовах

[ред. | ред. код]

У C++ struct по суті така ж, як і в C. Крім того, class — це те саме, що й struct, але з іншою типовою видимістю[en]: члени класу за замовчуванням є приватними, тоді як члени структури — публічними.

Мови .NET мають структуру даних, подібну до struct у C, яка в C# має назву struct, а у Visual Basic.NET — Structure). Вона надає багато можливостей класу, але діє як значеннєвий, а не посилальний тип. Наприклад, під час передавання .NET struct у функцію, значення копіюється, тому зміни вхідного параметра не впливають на передане значення[5].

Див. також

[ред. | ред. код]

Примітки

[ред. | ред. код]
  1. Struct memory layout in C. Stack Overflow.
  2. Ritchie, Dennis M. (March 1993). The Development of the C Language. ACM SIGPLAN Notices. 28 (3): 201—208. doi:10.1145/155360.155580. The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol's adherents would approve of. The central notion I captured from Algol was a type structure based on atomic types (including structures), composed into arrays, pointers (references), and functions (procedures). Algol 68's concept of unions and casts also had an influence that appeared later. [Архівовано 2019-04-11 у Wayback Machine.]
  3. Kelley, Al; Pohl, Ira (2004). A Book On C: Programming in C (вид. Fourth). с. 418. ISBN 0-201-18399-4.
  4. IBM Linux compilers. Initialization of structures and unions.
  5. Parameter passing in C#. Архів оригіналу за 30 травня 2016. Процитовано 14 серпня 2024. [Архівовано 2002-12-24 у Wayback Machine.]