Передача массива структуры между функциями


У меня есть структура "регистр", объявленная следующим образом:

typedef struct {
    int TypeID;
    unsigned char InstrumentType[128];
    unsigned char RegTag[128];
    unsigned char Protocol[128];
    int RegNum;
    unsigned char RW[128];
    unsigned char RegisterType[128];
    unsigned char Signed[128];
    unsigned char Inverted[128];
    unsigned char DataType[128];
    int Counts;
} Register;

У меня есть массив регистров под названием "Reg[9]" и я хочу создать функцию под названием "TransferValues", чтобы присвоить значения всем полям в структуре для каждого элемента массива. Как только значения будут обновлены, они будут выведены отдельно в main(). Как я могу передать массив в эту функцию и из нее?

3 3

3 ответа:

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

Небольшой пример использования указателя:

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <inttypes.h>

typedef struct {
    int32_t TypeID;
    char InstrumentType[128];
} Register;


void func ( Register *reg, size_t n_regs )
{
    for (size_t i=0; i< n_regs; i++)
    {
        reg[i].TypeID = (int32_t)(i);
        sprintf(reg[i].InstrumentType, "Instrument_%zu", i);
    }
}

int main (void)
{
    Register Reg[9] = {{0}};

    func(Reg, sizeof(Reg)/sizeof(Reg[0]));

    for (size_t i=0; i<sizeof(Reg)/sizeof(Reg[0]); i++)
    {
        printf ("Reg[%zu].TypeID = %"PRId32"\n", i, Reg[i].TypeID);
        printf ("Reg[%zu].InstrumentType = %s\n", i, Reg[i].InstrumentType);
    }
}

Как вы можете видеть, вы также должны передать в функцию, которую вы собираетесь записать размер передаваемого массива, чтобы быть уверенным, что он не выходит за пределы передаваемого массива.

Вы передаете Reg в эту функцию, используя синтаксис TransferValues(Reg);

Функция будет иметь вид

/*return type*/ TransferValues(Register* array)

(в теле функции вместо *(array + i) можно использовать array[i], где i - допустимый индекс массива, который может быть более читаемым.)

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

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

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

Важно знать, что использование массивоподобного объявления для типа функции, например

void TransferValues(Register regs[9])

Или

void TransferValues(Register regs[])

Не делает фактически объявляя regs массивом, компилятор молча преобразует regs в указатель (Register *regs). Это имеет последствия при попытке использовать трюк sizeof, чтобы получить количество элементов в массиве.

Для реального массива, например

Register regs[9]

Вы можете использовать sizeof(regs) / sizeof(regs[0]) для получения количества элементов в массиве. Это не работает в функции, поскольку все, что у вас есть, - это указатель, и выполнение sizeof на указателе даст вам размер фактического указателя, а не данные, на которые он указывает.