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

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. Архів оригіналу за 11 квітня 2019. Процитовано 14 серпня 2024. 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.
  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.]