Структури. Частина 2. Виділення пам’яті для структури. Вкладені структури. Масиви native-структур.

Структури. Частина 2. Виділення пам’яті для структури. Вкладені структури. Масиви native-структур.

Дана тема базується на темах:


Зміст


1. Яким чином виділяється пам‘ять для структурної змінної? Приклад застосування операції sizeof

Оголошення структурної змінної здійснюється в 2 етапи:

  • оголошення шаблону структури як нового типу даних. На цьому етапі пам‘ять не виділяється. Формується тільки інформація про вміст структури;
  • оголошення самої змінної. На цьому етапі виділяється пам‘ять для кожного поля (змінної), що описується в шаблоні структури.

Приклад. Нехай задано шаблон native-структури, що описує книгу в бібліотеці.

struct Book
{
    char title[70];
    char author[50];
    int year;
    float price;
};

Після такого опису пам‘ять не виділяється.

Якщо описати змінну тип Book, тоді для такої змінної виділиться пам’ять.

Book B; // під змінну B виділяється 128 байт

Розмір пам‘яті, що виділяється для змінної B становитиме: 70 + 50 + 4 + 4 = 128 байт. Для поля title виділиться 70 байт (тип char займає 1 байт). Для поля author виділиться 50 байт. Для поля year (в Win32) виділиться 4 байти (тип int). Для поля price виділиться 4 байти (тип float).

В залежності від розрядності операційної системи та конфігурації обладнання ця цифра може бути іншою.

Приклад. Визначення розміру пам‘яті, що виділяється для структурної змінної.

// Як визначити розмір пам'яті, виділеної для структурної змінної
Book B;
int size;
size = sizeof(B); // size = 128

2. Які особливості використання вкладених структур у програмах?

Шаблон будь-якої структури може містити в собі інші структури. Якщо в структурі описується інша структурна-змінна, тоді для цієї змінної пам‘ять виділяється згідно правил виділення пам‘яті для структурної змінної (див. п.1).



3. Приклад оголошення та використання вкладеної native-структури

Нехай задано два шаблони структур, які оголошуються в окремому файлі “MyStruct.h”:

– шаблон Point, що описує точку на координатній площині:

// Шаблон native-структури, що описує точку на площині
struct Point
{
    int x;
    int y;
};

– шаблон Triangle, що описує трикутник на площині:

// Шаблон native-структури, що описує фігуру трикутник
struct Triangle
{
    Point p1; // вкладена структура
    Point p2; // вкладена структура
    Point p3; // вкладена структура
    char comment[50]; // коментарій до фігури
};

У шаблоні Triangle описується три вкладені структури (точки) типу Point.

Демонстрація роботи зі структурою Triangle .

// вкладена native-структура
Triangle T; // для змінної T виділяється пам'ять

// заповнення значень змінної T
T.p1.x = 25;
T.p1.y = 36;
T.p2.x = 100;
T.p2.y = 55;
T.p3.x = 60;
T.p3.y = 56;
strcpy(T.comment, "Triangle #1");

Для використання методу strcpy() та підключення файлу структури потрібно на початку модуля програми вписати:

#include <cstring>
#include "MyStruct.h"

У native-структурі

  • можна оголошувати іншу native-структуру;
  • можна оголошувати value-структуру;
  • не можна оголошувати ref-структуру, оскільки вона є типом-посиланням.

4. Приклад оголошення та використання вкладеної ref-структури

Нехай задано шаблон ref-структури, що описує точку на координатній площині

// Шаблон ref-структури
ref struct Point_ref
{
    int x;
    int y;
};

Однак, ця структура може бути вкладеною в ref-структурі. Приклад

// Шаблон ref-структури, що описує прямокутник
ref struct Rectangle_ref
{
    Point_ref p1; // p1 – вкладена ref-структура
    Point_ref p2; // p2 – вкладена ref-структура
    char * comment; // текст в прямокутнику
};

...

// демонстрація використання вкладеної ref-структури
Rectangle_ref R1;

R1.p1.x = 23;
R1.p1.y = 34;
R1.p2.x = 55;
R1.p2.y = 68;

R1.comment = new char[50];
strcpy(R1.comment, "This is rectangle");

У ref-структурі:

  • можна оголошувати іншу ref-структуру;
  • можна оголошувати value-структуру;
  • не можна оголошувати native-структуру. Система видає повідомлення: “Mixed types are not supported” (“Змішані типи не підтримуються”).

5. Приклад оголошення та використання вкладеної value-структури

Нехай задано два шаблони value-структур, що описують точку (Point_value) та трикутник (Triangle_value)

// Шаблон value-структури, що описує точку
value struct Point_value
{
    int x;
    int y;
};

// Шаблон value-структури, що описує трикутник
value struct Triangle_value
{
    // p1, p2, p3 – вкладені value-структури
    Point_value p1;
    Point_value p2;
    Point_value p3;
    char * comment;
};

...

// вкладена value-структура
Triangle_value T1;

T1.p1.x = 100;
T1.p1.y = 120;
T1.p2.x = 115;
T1.p2.y = 145;
T1.p3.x = 150;
T1.p3.y = 109;
T1.comment = new char[50];
strcpy(T1.comment, "This is a triangle");

У шаблоні value-структури:

  • можна оголошувати іншу вкладену value-структуру;
  • не можна оголошувати вкладену ref-структуру
  • не можна оголошувати вкладену native-структуру.

6. Як оголосити масив структур (native)? Приклад оголошення та використання

Для native-структур оголошення масиву відбувається класичним для C/C++ способом.

Нехай задано шаблон структури Point_native, яка описує точку на площині.

// Шаблон native-структури, що описує точку на площині
struct Point_native
{
    int x;
    int y;
};

Приклад 1. Оголошення та використання масиву структур як значень.

// Масив native-структур
// оголошення масиву з іменем M
Point_native M[10]; // оголошується 10 структур типу Point, для яких виділяється пам'ять

// заповнення структур значеннями
for (int i=0; i<10; i++)
{
    M[i].x = i*(i-2);
    M[i].y = i*3;
}

int d;
d = M[5].x; // d = 15
d = M[0].y; // d = 0

Приклад 2. Оголошення та використання масиву покажчиків на native-структури.

// Масив покажчиків на 10 native-структур
Point_native * PM[10];

// виділення пам'яті для кожної структури
for (int i=0; i<10; i++)
{
    PM[i] = new Point_native;
}

// заповнення структур довільними значеннями
for (int i=0; i<10; i++)
{
    PM[i]->x = i*5+2;
    PM[i]->y = i*i*i;
}

// перевірка
int d;
d = PM[4]->x; // d = 22
d = PM[4]->y; // d = 64

7. Приклад оголошення та використання масиву native-структур, який є окремим полем структури (вкладеним в стуктуру)

Структура може містити вкладений масив структур.

Нехай задано шаблон native-структури Point_native, що описує точку на площині

// Шаблон native-структури, що описує точку на площині
struct Point_native
{
    int x;
    int y;
};

Масив з n точок (n = 1..10) можна представити у вигляді такого шаблону:

// масив native-структур всередині native-структури
PointsArray pt;

// заповнення довільними значеннями
pt.n = 6;
for (int i=0; i<pt.n; i++)
{
    pt.pA[i].x = i*5;
    pt.pA[i].y = i*i;
}

// перевірка
int d;
d = pt.pA[3].x; // d = 15
d = pt.pA[2].y; // d = 4

8. Приклад оголошення та використання двовимірного масиву native-структур

Нехай задано native-структуру, що описує точку на площині.

// native-структура
struct MyPoint
{
    int x;
    int y;
    int color;
};

Тоді робота з двовимірним масивом таких структур розміром 5*10 буде приблизно такою

// Оголошення масиву з іменем A розміром 5*10
MyPoint A[5][10];

// заповнення значеннями
for (int i=0; i<5; i++)
    for (int j=0; j<10; j++)
    {
        A[i][j].x = i*2 + j*j;
        A[i][j].y = i*i + j;
        A[i][j].color = i+j;
    }

// перевірка
int d;
d = A[3][4].x; // d = 22
d = A[2][5].y; // d = 9


Зв’язані теми