IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Comment déclarer un tableau avant sa définition ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2007
    Messages
    45
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 45
    Points : 52
    Points
    52
    Par défaut Comment déclarer un tableau avant sa définition ?
    Bonjour,

    J'ai deux tableaux static.
    Le contenu du 1er tableau fait référence au 2d tableau, et réciproquement (le contenu du 2d tableau fait référence au 1er).
    Je dois donc déclarer ces tableaux avant de pouvoir défini leur contenu.

    Voici mon code (simplifié) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    struct type_fleche  // Flèche de l'automate
    {	int etiquette;		    	// étiquette de la flèche
    	type_fleche *etatSuivant;	// état d'arrivée de la flèche
    };
     
    extern type_fleche etat0[], etat1[];
     
    static type_fleche
    	etat0 [] =
    	 {{ 0, etat1},
    	  { 1, etat0}
         },
    	etat1 [] =
    	 {{ 0, etat1},
    	  { 1, etat1},
    	  { 2, etat0}
    	 };
    Cela compile bien avec VisualC++. Mais avec Mingw, j'obtiens l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: 'etat0' was declared 'extern' and later 'static' [-fpermissive]
    Je reconnais que le compilateur a raison ... mais j'ai essayé plein d'autres solutions, et je n'arrive pas à déclarer un tableau static avant de le définir.

    Quelqu'un pourrait-il m'aider ?

    Merci d'avance

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 677
    Points
    13 677
    Billets dans le blog
    1
    Par défaut
    Il me semble compliqué d'être à la fois externe et static puisque ce sont deux sortes de linkage différents. La solution est sans doute de les déclarer / définir sans les initialiser puis des les initialiser dans une fonction init().

    Néanmoins, je vois que l'erreur est donné par [-fpermissive] et il me semble que cela est une option C++ et non C (https://gcc.gnu.org/onlinedocs/gcc-4...t-Options.html). Chez moi en tout cas, j'ai surtout une erreur pour la définition du type.
    D:\....c|3|error: unknown type name 'type_fleche'|
    Voilà un code qui devrait faire l'affaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <stdio.h>
     
    struct type_fleche  // Flèche de l'automate
    {
        int etiquette;		    	// étiquette de la flèche
        struct type_fleche *etatSuivant;	// état d'arrivée de la flèche
    };
     
    static struct type_fleche etat0[2], etat1[3];
     
    void init(void)
    {
        etat0 [0] = (struct type_fleche) {0, etat1};
        etat0 [1] = (struct type_fleche) {1, etat0};
     
        etat1 [0] = (struct type_fleche) {0, etat1};
        etat1 [1] = (struct type_fleche) {1, etat1};
        etat1 [2].etiquette = 2;
        etat1 [2].etatSuivant = etat0;
    }
     
    int main(void)
    {
        init();
        printf("etat0 --> %p\n", etat0);
        printf("etat1[2] = %d %p\n", etat1[2].etiquette, etat1[2].etatSuivant);
    }

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 191
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 191
    Points : 17 150
    Points
    17 150
    Par défaut
    Sinon, tu ne les définis pas static.

    Autre solution, les créer statiquement, dans un fichier d'implémentation à part, et proposer des fonctions pour y accéder.
    Comme cela, tu rends la variable elle-même non globale.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Membre émérite
    Avatar de skeud
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2011
    Messages
    1 091
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2011
    Messages : 1 091
    Points : 2 724
    Points
    2 724
    Billets dans le blog
    1
    Par défaut
    En fait tu dois faire comme cela:

    Déclarer ton tableau en static dans un fichier (là ou tu fais l’instanciation de ton tableau).
    Déclarer ton tableau en extern dans un fichier ou tu ne fais pas l’instanciation, mais pas besoin de le déclarer static.

    Normalement, ça devrait fonctionner.

    (D'ailleurs, je ne suis même pas sur que le déclarer static veuille dire grand chose étant donné que c'est une variable globale ....).
    En général on déclare statique des variable dont le scope n'est pas tout le programme, à savoir:

    Des variable dans une fonction.
    Des variable dans une classe.(pas ton cas comme tu es en C).
    Pas de solution, pas de probleme

    Une réponse utile (ou +1) ->
    Une réponse inutile ou pas d'accord -> et expliquer pourquoi
    Une réponse à votre question


  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 191
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 191
    Points : 17 150
    Points
    17 150
    Par défaut
    le déclarer static dans un fichier n'est pas l'objectif voulu.

    Je donne des noms pour l'explication: main.c, autre.c, autre.h.
    le code de l'application est réparti entre main.c et autre.c.
    autre.h permet à main.c d'utiliser le reste du code.

    Il convient d'ajouter tableaux.h, et son implémentation tableaux.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    //pas de garde, ce ne sont que des déclarations
    extern const int tabs_size;
    extern int tab1[], tab2[];
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #include "tableaux.h"
    const int tabs_size = 4;
    int tab1[] = {0,1,2,3};
    int tab2[] = {0,10,20,30};
    Le code sera compilé en trois unités de compilations: main.o, autre.o et tableaux.o.

    Si tableaux.c déclare les tableaux static, on aura la situation suivante:
    • tableaux.o aura des symboles non liables, les variables statiques
    • main.o et autre.o auront donc des symboles étrangers à résoudre (les variables extern) sans définition.


    éventuellement, on peut rappeler le "extern" dans la définition des variables.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 677
    Points
    13 677
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par skeud Voir le message
    En fait tu dois faire comme cela:

    Déclarer ton tableau en static dans un fichier (là ou tu fais l’instanciation de ton tableau).
    Déclarer ton tableau en extern dans un fichier ou tu ne fais pas l’instanciation, mais pas besoin de le déclarer static.
    Il ne doit pas faire comme cela car le linker ne pourra pas utiliser des tableaux statiques pour résoudre un linkage externe.

    Citation Envoyé par skeud Voir le message
    (D'ailleurs, je ne suis même pas sur que le déclarer static veuille dire grand chose étant donné que c'est une variable globale ....).
    En général on déclare statique des variable dont le scope n'est pas tout le programme, à savoir:

    Des variable dans une fonction.
    Des variable dans une classe.(pas ton cas comme tu es en C).
    Elle n'est pas globale, elle est statique à l'unité de compilation. Cela revient à une visibilité private en orienté objet : seules les fonctions de l'unité de compilation peuvent la voir. Si une variable à vocation à être utilisée dans d'autres unités de compilation, l'idée d'un getter et d'un setter suggérée par leternel me semble être la meilleure solution.

Discussions similaires

  1. Comment déclarer un tableau de tableaux ?
    Par Imène_23 dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 01/08/2011, 17h25
  2. [XL-2007] Comment déclarer un tableau en Public?
    Par mumu27 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 01/07/2010, 13h57
  3. [AC-2000] Comment déclarer un tableau et son utilisation
    Par AmisNoob dans le forum VBA Access
    Réponses: 3
    Dernier message: 01/12/2009, 19h05
  4. comment déclarer un tableau de pointeur
    Par hanou88 dans le forum C
    Réponses: 2
    Dernier message: 23/01/2009, 01h56
  5. Comment déclarer un tableau de TextBox ?
    Par zappacosta dans le forum Visual C++
    Réponses: 2
    Dernier message: 01/11/2006, 22h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo