Как объявить и инициализировать массив указателей на структуру в C?

Системный вызов Waitpid на C Программирование и разработка

В языке C массивы предназначены для хранения данных сходного типа в смежных ячейках памяти. Мы можем создавать массивы либо из примитивных типов данных, таких как int, char или float, либо из пользовательских типов данных, таких как структуры и объединения. Мы также можем создавать массивы указателей на языке C. Сегодня мы узнаем, как создавать массивы указателей структуры или указателей на структуру на языке C, как статически, так и динамически.

Создание массивов указателей структуры (статические массивы)

1) 1D Arrays

Мы можем статически выделить память для 1D и 2D массивов на языке C. Статическая память выделяется в памяти стека. Мы можем сделать статическое выделение памяти для указателей структур следующими способами:

Шаг 1 — Объявление и инициализация одномерных массивов

Допустим, у нас есть структура «узел», и мы создали разные указатели на эту структуру. Теперь, чтобы создать одномерный массив этих указателей в статической памяти, мы должны следовать следующему синтаксису:

Синтаксис:

<struct_name> * <array_name> [ <size_of_array> ] ; // Declaration
<array_name> [ <index_number> ] = <pointer_to_the_structure> ; // Initialization

Мы можем получить доступ к указателям внутри нашего массива так же, как мы обращаемся к обычным элементам массива. Есть только небольшая модификация, которую нам нужно использовать для доступа к данным, присутствующим внутри нашего указателя структуры.

Шаг 2 — Доступ к указателям в массиве

Синтаксис:

<array_name> [<index_number>] -> <data to be accessed which is present inside the structure >

Пример:

С

// C Program to implement
// structure pointer arrays
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
    int number;
    char character;
} node;
int main(void)
{
    // First pointer to structure
    node* structure_ptr1 = (node*)malloc(sizeof(node));
    // Second pointer to structure
    node* structure_ptr2 = (node*)malloc(sizeof(node));
    // Declaration of
    // structure-pointer-array of size 2
    node* struct_array[2];
    // Initializing structure pointers
    structure_ptr1->number = 100;
    structure_ptr1->character = 'a';
    structure_ptr2->number = 200;
    structure_ptr2->character = 'b';
    // Initializing this array with pointers
    struct_array[0] = structure_ptr1;
    struct_array[1] = structure_ptr2;
    // Printing data of structures
    printf("Data:\n");
    printf("%d and %c\n", struct_array[0]->number,
           struct_array[0]->character);
    printf("%d and %c\n", struct_array[1]->number,
           struct_array[1]->character);
    return 0;
}

Выход

Data:
100 and a
200 and b

В приведенном выше примере у нас есть структура, называемая «узел». Мы сделали 2 указателя на эту структуру, а именно — «structure_ptr1» и «structure_ptr2» и инициализировали их. После этого мы объявили массив — «struct_array» размера 2 и инициализировали его нашими указателями на структуру.

2) 2D-массивы

Шаг 1 — Объявление и инициализация 2D-массивов

Синтаксис:

<structure_name>  * <array_name> [number_of_rows][number_of_columns];
<array_name> [row_number][column_number] = <pointer_to_structure> ;

Шаг 2. Доступ к элементам нашего 2D-массива

Синтаксис:

< array_name >[ <row_number> ][ <column_number> ] -> <data to be accessed which is present inside the structure >;

Пример:

С

// C Program to implement
// structure pointer 2-D array
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
    int number;
    char character;
} node;
int main(void)
{
    // First pointer to structure
    node* structure_ptr1 = (node*)malloc(sizeof(node));
    // Second pointer to structure
    node* structure_ptr2 = (node*)malloc(sizeof(node));
    // Third pointer to structure
    node* structure_ptr3 = (node*)malloc(sizeof(node));
    // Fourth pointer to structure
    node* structure_ptr4 = (node*)malloc(sizeof(node));
    // Declaration of
    // structure-pointer-array
    // of size 2 X 2
    node* structure_array[2][2];
    // Initializing structure pointers
    structure_ptr1->number = 100;
    structure_ptr1->character = 'a';
    structure_ptr2->number = 200;
    structure_ptr2->character = 'b';
    structure_ptr3->number = 300;
    structure_ptr3->character = 'c';
    structure_ptr4->number = 400;
    structure_ptr4->character = 'd';
    // Initializing this array with pointers
    structure_array[0][0] = structure_ptr1;
    structure_array[0][1] = structure_ptr2;
    structure_array[1][0] = structure_ptr3;
    structure_array[1][1] = structure_ptr4;
    // Accessing the values of these structure pointers from
    // 2D array
    printf("Data:\n");
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            printf("%c - ",
                   structure_array[i][j]->character);
            printf("%d\t\t", structure_array[i][j]->number);
        }
        printf("\n");
    }
}

Выход

Data:
a - 100        b - 200        
c - 300        d - 400

Вот как мы объявляем и инициализируем двумерный массив указателей на структуры. Здесь мы используем ту же структуру — «узел» и сделали для нее 4 указателя: «structure_ptr1», «structure_ptr2», «structure_ptr3» и «structure_ptr4». После этого мы объявили 2D-массив размером — 2 X 2, а именно —structure_array.

Примечание. Тип данных массива должен быть таким же, как и у структуры, за которой следует знак * (звездочка), что означает массив указателей структуры.

Создание массивов указателей структур (динамические массивы)

1) 1D массивы

Поскольку мы знаем, что в языке C мы также можем динамически выделять память для наших переменных или массивов. Динамически выделяемые переменные или массивы хранятся в куче. Чтобы динамически выделять память для массивов указателей структур, необходимо следовать следующему синтаксису:

Синтаксис:

< structure_name >  ** < array_name > = <structure_name **> malloc ( sizeof( <structure_name> )* size ) ;

Обратите внимание на двойной указатель после имени структуры и во время приведения типа malloc к структуре. Этот двойной указатель необходим, поскольку мы указываем на массив указателей на структуру, и мы знаем, что используем двойные указатели, если хотим указать на другой указатель.

Пример:

С

// C Program to implement
// Dynamic Array of structure
// pointer
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int number;
char character;
} node;
int main(void)
{
// First pointer to structure
node* structure_ptr1 = (node*)malloc(sizeof(node));
// Second pointer to structure
node* structure_ptr2 = (node*)malloc(sizeof(node));
// Third pointer to structure
node* structure_ptr3 = (node*)malloc(sizeof(node));
// Fourth pointer to structure
node* structure_ptr4 = (node*)malloc(sizeof(node));
// Initializing structure pointers
structure_ptr1->number = 100;
structure_ptr1->character = 'a';
structure_ptr2->number = 200;
structure_ptr2->character = 'b';
structure_ptr3->number = 300;
structure_ptr3->character = 'c';
structure_ptr4->number = 400;
structure_ptr4->character = 'd';
// Declaring the array dynamically for structure
// pointers
// Note that double pointer is
// used for pointer to pointer
node** structure_array
= (node**)malloc(sizeof(node) * 4);
// Initializing the array of structure pointers
structure_array[0] = structure_ptr1;
structure_array[1] = structure_ptr2;
structure_array[2] = structure_ptr3;
structure_array[3] = structure_ptr4;
// Accessing dynamic 1D arrays - just like static 1D
// arrays
printf("Data:\n");
for (int i = 0; i < 4; i++) {
printf("%c - ", structure_array[i]->character);
printf("%d\t\t", structure_array[i]->number);
printf("\n");
}
}

Выход

Data:
a - 100        
b - 200        
c - 300        
d - 400

Вы можете ясно видеть в приведенном выше коде, как мы инициализировали массив указателей структуры в конце. Разница между этим и статическими массивами заключается только в том, что статические массивы размещаются в памяти стека, а они — в памяти кучи. Итак, вы можете изменить размер этих массивов в любое время.

Мы можем получить доступ к этим массивам точно так же, как и к статическим, поэтому для этого нет никаких изменений в синтаксисе.

Примечание. В случае статических массивов вы можете инициализировать весь массив сразу во время инициализации, например — node *struct_arr [10] = { struct_ptr1, struct_ptr2, struct_ptr3 …..}, тогда как динамически размещаемые массивы необходимо инициализировать индексом -по индексу.

2) 2D-массивы

Чтобы выделить динамические 2D-массивы указателей, сначала мы создадим 1D-массив динамически, а затем создадим подмассивы в каждом индексе этого 1D-массива (в основном массив массивов, содержащих указатели). Теперь для этого требуется использование тройных указателей. Разберемся в этом с помощью схемы:

Теперь для этого требуется использование тройных указателей

Пояснение к приведенному выше рисунку:

  • *** st_arr — это тройной указатель, используемый для доступа к двумерному массиву указателей структур. Теперь он сделан тройным указателем, потому что мы обращаемся к тем
  • массивам, каждый элемент которых имеет указатель на другой массив (подмассив). И каждый элемент этих подмассивов имеет указатель на структуру.
  • Каждый индекс st_arr[i] содержит подмассивы.
  • Каждый индекс подмассивов — st_arr[i][j] содержит указатель на структуру.
  • st_ptr — указатель на структуру.

Пример:

С

// C Program to implement
// 2D arrays of structure
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
    int number;
    char character;
} node;
int main(void)
{
    // First pointer to structure
    node* st_ptr1 = (node*)malloc(sizeof(node));
    // Second pointer to structure
    node* st_ptr2 = (node*)malloc(sizeof(node));
    // Third pointer to structure
    node* st_ptr3 = (node*)malloc(sizeof(node));
    // Fourth pointer to structure
    node* st_ptr4 = (node*)malloc(sizeof(node));
    // Initializing structure pointers
    st_ptr1->number = 100;
    st_ptr1->character = 'a';
    st_ptr2->number = 200;
    st_ptr2->character = 'b';
    st_ptr3->number = 300;
    st_ptr3->character = 'c';
    st_ptr4->number = 400;
    st_ptr4->character = 'd';
    // Declaring the array dynamically for structure
    // pointers    Step - 1
    // Note that double pointer is
    // used for pointer to pointer
    node*** structure_array
        = (node***)malloc(sizeof(node***) * 2);
    // Used double pointers, at each index to point to
    // arrays of structure pointers - Step 2
    for (int i = 0; i < 2; i++) {
        structure_array[i] = (node**)malloc(sizeof(node**));
    }
    // Initializing the array of structure pointers   - Step
    // 3
    structure_array[0][0] = st_ptr1;
    structure_array[0][1] = st_ptr2;
    structure_array[1][0] = st_ptr3;
    structure_array[1][1] = st_ptr4;
    // Printing the values of these structure pointers from
    // array
    printf("Data:\n");
    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            printf("%c - ",
                   structure_array[i][j]->character);
            printf("%d\t\t", structure_array[i][j]->number);
        }
        printf("\n");
    }
}

Выход

a - 100        b - 200        
c - 300        d - 400
  • В приведенном выше коде, как мы уже обсуждали, тройной указатель использовался для указания на массив массивов, содержащих указатели на структуры.
  • На втором этапе мы использовали двойные указатели, так как нам нужно было использовать указатель, который мог указывать на массив указателей на структуры.
  • На третьем шаге мы инициализировали наш динамический 2D-массив, как и статический 2D-массив, индексируя по -index.

Читайте также:  Модуль С++
Оцените статью
bestprogrammer.ru
Добавить комментарий