Как инициализировать массив структур в C? - PullRequest
0 голосов
/ 06 августа 2020

Я кодирую на плате разработки с процессором ARM, поэтому я использую IAR WORKBENCH в качестве IDE. Интересно, почему компилятор выдает ошибку при обучении ручной инициализации массива структур, код ниже: Определение структуры:

typedef void (*Function)(void);

typedef struct _Task
{
    uint8_t priority;
    Function *func;
    uint8_t exec_state;
}Task; 

Попытка инициализировать массив структур :

Task* task_array_test[3] = {
        HIGH , &Switch_LED_RED , IDLE,
        MED , &Switch_LED_RED , IDLE,
        LOW , &Reset_LED      , IDLE
};

IDLE, LOW, MED, HIGH - макросы со значениями типа int без знака.

Ошибки компилятора:

Error[Pe144]: a value of type "unsigned int" cannot be used to initialize an entity of type "Task *" 
Error[Pe144]: a value of type "void (*)(void)" cannot be used to initialize an entity of type "Task *" 
Error[Pe146]: too many initializer values 

Любая помощь приветствуется!

Ответы [ 5 ]

2 голосов
/ 06 августа 2020

Первое, что уже упоминалось @pmg - подойдет массив типа Task, вероятно, не потребуется массив указателей Task*

Кроме того, вам не нужно func для также иметь тип Function*:

typedef void (*Function)(void);

typedef struct _Task
{
    uint8_t priority;
    Function func;
    uint8_t exec_state;
}Task; 

Инициализация вашего массива будет выглядеть так:

Task task_array_test[] = {
        HIGH , Switch_LED_RED , IDLE,
        MED ,  Switch_LED_RED , IDLE,
        LOW ,  Reset_LED      , IDLE
};

Но я предпочитаю помещать каждый элемент в фигурные скобки для лучшего чтения :

 Task task_array_test[] = {
            { HIGH , Switch_LED_RED , IDLE },
            { MED ,  Switch_LED_RED , IDLE },
            { LOW ,  Reset_LED      , IDLE }
    };
1 голос
/ 06 августа 2020

Вы можете инициализировать, используя составной литерал, например:

Task* task_array_test[3] = {
        &(Task) {HIGH , Switch_LED_RED , IDLE},
        &(Task) {MED , Switch_LED_RED , IDLE},
        &(Task) {LOW , Reset_LED      , IDLE}
};

Вы также можете:

Task s1 = {HIGH , Switch_LED_RED , IDLE};
Task s2 = {MED , Switch_LED_RED , IDLE};
Task s3 = {LOW , Reset_LED      , IDLE};

Task* task_array_test[3] = {&s1, &s2, &s3};

В определении структуры у вас есть член func, объявленный как

Function *func;

, что делает func указатель на указатель на тип, потому что Function сам по себе является указателем:

typedef void (*Function)(void);

Вместо этого должно быть:

typedef struct _Task
{
    uint8_t priority;
    Function func;       //Note that * removed
    uint8_t exec_state;
} Task; 

Также , вам не нужно использовать & с именем функции при назначении его указателю функции. Имя функции дает адрес функции.

1 голос
/ 06 августа 2020

У вас есть несколько проблем с вашим кодом.

Во-первых: функция типа уже является указателем на функцию, нет необходимости снова объявлять ее указателем. Это заканчивается указателем на указатель функции.

typedef struct _Task
{
    uint8_t priority;
    Function func; // Leave out the *
    uint8_t exec_state;
}Task;

Второй Правильный способ инициализации массива будет таким.

Task task_array_test[] = {
    {HIGH , &Switch_LED_RED , IDLE},
    {MED , &Switch_LED_RED , IDLE},
    {LOW , &Reset_LED      , IDLE},
};

Нет задачи *, только задача. Пустой [] уже указывает его как массив.

Вот небольшая тестовая программа, которую я написал, чтобы доказать, что она работает.

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

typedef void (*Function)(void);

static int i;

#define HIGH 10
#define MED  5
#define LOW  1
#define IDLE 1

void Switch_LED_RED(void){
   i++;
}

void Reset_LED(void){
   i++;
}

typedef struct _Task
{
    uint8_t priority;
    Function func;
    uint8_t exec_state;
}Task;

Task task_array_test[] = {
    {HIGH , &Switch_LED_RED , IDLE},
    {MED , &Switch_LED_RED , IDLE},
    {LOW , &Reset_LED      , IDLE},
};

int main(){    
    std::cout << "I starts with the value: " << i << std::endl;
    while (i < 3){
      task_array_test[i].func();  
    }
    std::cout << "I has now the value: " << i << std::endl;
    return 0;
}
0 голосов
/ 06 августа 2020

Вы пробуете этот код

struct _Task
{
   int a,b,c;
}Task[3]; 
int main()
{
Task[0].a= HIGH;
Task[0].b= Switch_LED_RED;
Task[0].c= IDLE;
Task[1].a= MED ;
Task[1].b= Switch_LED_RED;
Task[1].c= IDLE;
Task[0].a= LOW ;
Task[0].b= Switch_LED_RED;
Task[0].c= IDLE;
}
0 голосов
/ 06 августа 2020

Если вам нужны указатели, вы можете сделать это:

Task* task_array_test[] = {
    &(Task){HIGH , &Switch_LED_RED , IDLE},
    &(Task){MED , &Switch_LED_RED , IDLE},
    &(Task){LOW , &Reset_LED      , IDLE},
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...