C++. Структуры. Часть 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 байт. Для поля yearWin32) выделится 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_native, для которых выделяется память

// заполнение структур значениями
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


Связанные темы