1
votes

Comment initialiser un tableau qui est un élément d'une structure en C?

J'ai une structure comme celle-ci dans un fichier d'en-tête.

const testStruct t2 = { 0, {1,2 ..}, {3.4...} }

J'ai initialisé les éléments individuellement dans une autre fonction comme ci-dessous.

void foo()
{
   testStruct t[2];
   t[0].a = 10;
   for(int i = 0; i < 10; i++)
   {
      t[0].b[i] = i;
   }
   for(int i = 0; i <5; i++)
   {
       for(int j =0; j < 6; j++)
       {
          t[0].c[i][j] = j;
       }
    }

Ce type d'initialisation fonctionne. Mais j'utilise ceci dans un projet C intégré. Et je rencontre des problèmes de RAM parce que la structure prend une taille énorme. Après avoir recherché des solutions, j'ai trouvé que je pouvais placer des variables dans la ROM en les rendant constantes. Mais je ne suis pas capable de rendre cette structure constante. Un des moyens que j'ai trouvé était d'initialiser la structure en tant que constante comme ci-dessous.

typedef struct test
{
   int a;
   int b[10];
   int c[5][6];
}testStruct;

Le problème est que je ne sais pas comment initialiser les éléments du tableau. Parce que la taille du tableau dans mon projet comprend plus de 100 éléments. Je veux savoir s'il y a moyen d'initialiser cette structure et d'en faire une constante pour qu'elle soit stockée dans la ROM.

Toute aide est appréciée :)


7 commentaires

Vous pouvez faire la version de la liste contreventée même s'il s'agit de plus de 100 éléments


Salut. Pourrai-je utiliser une boucle for ou tout autre type de boucle? ou devrais-je simplement saisir plus de 100 éléments manuellement?


Vous devez entrer tous les éléments manuellement - à moins que les autres après les valeurs initialisées soient tous nuls.


Merci pour les commentaires. J'essayais de voir s'il y avait un autre moyen de ne pas avoir besoin de mettre à jour les valeurs manuellement chaque fois que l'entrée doit être modifiée.


Vous pourriez avoir un autre programme qui génère la source C pour l'initialiseur, et vous l'exécutez plus tôt dans votre processus de construction


Il y a 2 options: - Soit tout coder en dur, soit générer le code d'initialisation du tableau en externe via des scripts. - Ou utilisez des astuces macro comme celles-ci: stackoverflow.com/a/61746724/584518


Si ces valeurs init sont vraiment les valeurs que vous utilisez, je vous demanderais plutôt pourquoi vous avez besoin des structures, des tableaux, etc. Il pourrait être tout aussi normalement calculé par une fonction. Si les valeurs ne sont pas si contigues, un outil générateur est une bonne chose, et utilisez un fichier xxx_cfg.c pour générer également des configurations et compiler séparément sans toucher au code fixe.


3 Réponses :


0
votes

Vous ne pouvez pas simplement faire des boucles lors de l'initialisation des constantes en C. Vous devriez trouver un autre moyen de résoudre ce problème. Je peux suggérer deux solutions:

  1. Utilisez un générateur de tableaux en ligne, comme celui-ci: https: // yupana-engineering. com / online-c-array-generator , ou
  2. Écrivez votre propre générateur en utilisant BASH, Python ou un autre langage de script qui peut être intégré dans votre processus de construction lors de l'étape de pré-construction.

1 commentaires

Vous pouvez même écrire des scripts dans le langage appelé C :) C'est drôle comment les programmeurs C oublient souvent qu'ils sont en fait des programmeurs, et écrire un petit programme qui génère un fichier texte .c n'est pas sorcier. De nombreux IDE sont livrés avec des «solutions» qui contiennent plusieurs projets - cela peut être utilisé pour avoir des projets séparés générant des scripts, des cas de test, des simulations, etc. liés au projet principal, mais sans en faire partie. Il est également possible d'être intelligent avec les programmes de contrôle de version et d'avoir plusieurs dépôts entrelacés les uns avec les autres. Etc.



0
votes

Cela se fait normalement en "codant en dur" tout. Dans le cas où les initialiseurs sont complexes, la source C pour les initialiseurs pourrait être générée par des scripts externes.

Dans certains cas, vous pouvez également le résoudre avec le pré-processeur, mais ce n'est pas un outil idéal pour le tâche, car cela rend le code difficile à lire. Et aussi, afin de proposer des formes aussi variées de macros "intelligentes" spécifiques à un projet, vous avez besoin d'une connaissance C assez étendue des fonctionnalités obscures du langage en combinaison avec un état d'esprit "sortir des sentiers battus".

In votre cas par exemple, où vous avez besoin de séquences numériques, vous pourriez préparer quelques macros comme celles-ci:

static const sequence_trick trick = { .arr_max=(int[]){0,1,2,3,4,5,6,7,8,9} };

trick.arr // here you have a const array of length n, compile-time initialized to values 0,1,..., n

Après quoi vous pouvez initialiser la structure comme ceci:

#define SEQUENCE_TYPE(n) typedef union { int arr_max[10]; int arr[n]; } sequence_trick;

Une autre astuce serait de créer une union avec une macro comme

const testStruct t[2] =
{
  [0] = 
  {
    .a = 10,
    .b = SEQUENCE(10),
    .c = { SEQUENCE(6),SEQUENCE(6),SEQUENCE(6),SEQUENCE(6),SEQUENCE(6) },
  },
};

Et puis

#define SEQ1 0,
#define SEQ2 SEQ1 1,
#define SEQ3 SEQ2 2,
#define SEQ4 SEQ3 3,
#define SEQ5 SEQ4 4,
#define SEQ6 SEQ5 5,
#define SEQ7 SEQ6 6,
#define SEQ8 SEQ7 7,
#define SEQ9 SEQ8 8,
#define SEQ10 SEQ9 9,

#define SEQUENCE(n) {SEQ##n}


0 commentaires

0
votes

Vous l'avez déjà fait de la manière normale / typique / facile?

const int x = 5;
const float y = 1.5F;
const double z = 2.1;
const char s[]="hello world";
const int a[5]={1,2,3,4,5};

Je ne suis pas sûr de comprendre la question comme vous l'avez déjà fait et d'avoir mis en œuvre la réponse.

}/*c*/,
}/*1*/,
};

c'est C donc vous devenez libéral avec les accolades chaque élément majeur a son propre ensemble, bien que gcc n'aimait pas que l'élément a le sien.

}/*c*/,
}/*1*/
};


1 commentaires

Si j'ai mal compris et que la question est de savoir si je peux lancer ceci, RUNTIME, ET le mettre en ROM pendant que je le fais, c'est une autre histoire. Oui, certainement possible, mais ce n'est pas ainsi que vous le faites. Et cela dépend en partie du matériel et des pages d'effacement rom / flash et autres, mais généralement possible. La solution ci-dessus consiste à créer les données avant / pendant la compilation. Pas au moment de l'exécution.