Передача массива структуры между функциями
У меня есть структура "регистр", объявленная следующим образом:
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 ответа:
В 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
на указателе даст вам размер фактического указателя, а не данные, на которые он указывает.