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

За допомогою ключового слова 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++

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

.NET

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

Див. також

  • Бітове поле[en] — структура даних, яка відображає один або кілька сусідніх бітів
  • Гнучкий елемент масиву[en] — функція мови C, завдяки якій структура може містити останнім членом масив без заданого розміру
  • Пасивна структура даних[en] — інша назва для записів
  • Об'єднання (структура даних) — тип даних, який допускає значення, які можуть мати кілька різних подань

Примітки

  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.
  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.
  • п
  • о
  • р
Мова програмування C
БібліотекиМожливості мови
  • Рядки
  • Синтаксис
  • Препроцесор
  • Типи даних та оголошення змінних у C
  • Функції
НащадкиC та інші мови
Категорія Категорія