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 :

Dimensionnement tableau et compilation


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 2
    Points : 3
    Points
    3
    Par défaut Dimensionnement tableau et compilation
    Bonjour!

    Voici une affirmation que je trouve pour la 3eme fois (un prof et 2 bouquins différents) et pourtant le test me prouve le contraire.

    "Cette instruction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #define N 50
    ...
    int t[N];
    float h [2*N-1];

    est correcte. En revanche, elle ne le serait pas (en C) si N était une constante symbolique définie par const int N=50, les expressions N et 2N-1 n'étant alors plus calculables par le compilateur (elle sera cependant acceptée en C++)."


    J'ai testé sous Code::Blocks et Dev-C++ et les 2 cas fonctionnent! Pourquoi?
    Mon prof me dit que les parametres des compilateurs prennent en compte des versions de C améliorées par rapport au C initial.

    Mais si c'est le cas, j'imagine qu'on doit pouvoir paramétrer le compilateur sur une version du C, nan? ça se choisirait où?

    Pourquoi les deux écritures fonctionnent?

    Merci!

    Blutch

    P.S.: et voici un petit code pour que vous testiez

    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
    #include <stdio.h>
    main()
    {
    const int N=4;
    int i[N], n;
     
    //initialisation des valeurs des cellules du tableau
    for (n=0; n<4; n++)
        {
        i[n]=0;
        }
     
    //attribution de valeurs aux cellues du tableau
    for (n=1; n<4; n++)
        {
        i[n]=i[n-1]+1;
        printf("cellule numero %d",n);
        printf("\tvaleur=%d\n",i[n]);
        }
    }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 374
    Points : 23 631
    Points
    23 631
    Par défaut
    Je pense que cet exemple se réfère aux VLA (Variable Length Arrays) qui n'ont été introduits en C qu'avec C99. Ça veut donc dire que si tu compiles en C ANSI strict, le compilo risque de se plaindre, mais que sur tout compilateur normalement à jour, il y a longtemps que cela fonctionne.

    L'idée générale des tableaux étant de réserver une certaine quantité de mémoire dans la pile et de se référer à ce qu'il contient en utilisant un offset par rapport au pointeur de base, qui permet de repérer le début du tableau, ou de tout autre variable locale dans la pile. Pour ce faire, il est nécessaire de connaître à l'avance, c'est-à-dire à la compilation, cette taille pour que les instructions soient générées directement avec les bons offsets.

    Maintenant, la mémoire réservée dans la pile l'étant au moment où l'on entre dans un bloc, il n'y a rien qui empêche l'utilisation d'une variable définie au runtime pour déterminer cette taille. La seule chose, c'est que cela oblige le compilo à faire le distingo entre les variables locales ordinaires et les VLA, à maintenir un tableau d'offsets spécialement pour ces derniers, et à effectuer une indirection supplémentaire pour obtenir l'adresse effective. Des formalités qui se doivent d'être normalisées, donc, mais rien d'infaisable pour le compilateur.

    Dans l'exemple que tu nous donnes, ton #define est une constante symbolique : le préprocesseur remplace partout N par la valeur définie dans le code, et le compilateur qui passe derrière ne s'aperçoit même pas qu'il s'agissait d'une constante et pas d'une valeur écrite en dur; ce qui donne parfois quelques gags célèbres du style :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
     
    #define SIX 1+5
    #define NINE 8+1
     
    int main (void)
    {
        printf ("%d\n",SIX*NINE);
        return 0;
    }

    Code Shell : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ ./programme
    42

    Si tu lui passes une variable, fût-elle en réalité constante, le compilateur sait que cette valeur est définie à l'exécution et est en droit de se plaindre si tu ne compiles pas en C99.

    Seulement, dans l'exemple précis que tu nous donnes, « const int N » est déclarée et définie juste avant le tableau. Le compilateur peut donc déterminer avec certitude quel est sa valeur et affirmer qu'elle ne changera pas. Sur le plan formel, cela reste une variable et on doit quand même tomber dans le premier cas mais si on lui laisse un tout petit peu de latitude, le compilateur a le droit de construire ce tableau comme un tableau ordinaire et donc éviter une erreur.

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Dans le cas du C99, les deux expressions sont valides puisque le C99 admet la déclaration de tableaux (dits VLA : Variable Length Array) dont la dimension est une variable (const ou pas) dont la valeur peut n'être éventuellement évaluée que pendant l'exécution (Le compilateur ne sait pas alors quelle est la dimension du tableau). Il y a toutefois des restrictions à l'utilisation des VLA.

    Si le compilateur est C90 alors, l'utilisation de const int N = 50 donnera une erreur. Si le code est admis, c'est une extension apportée par le compilateur.

    A noter que le point de vue est différent entre C99 et C90 avec cette extension. Pour le C99, on définit un VLA. Pour le C90, alors dans const int N = 50, N sera considéré comme une constante (comme dans le cas de #define N 50). C'est évidemment un abus, N n'étant pas une valeur constante mais un objet constant.

    En C99, on aura :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    const int N = 50;
    struct s
    {
      int tab[N]; //erreur
    };
    int tab[N]; //erreur
    int main(void)
    {
    int i[N]; // pas d'erreur;
    ....
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  4. #4
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Merci à tous les deux!

    Je suis débutant et je peux pas encore comprendre tout les éléments de vos réponses mais je vais réfléchir aux détails.

    Pour les grandes lignes j'ai compris!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Dimensionner tableau 3d
    Par CeCherPH dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 09/09/2013, 13h27
  2. [AC-2000] Dimensionnement tableau Excel depuis Access
    Par Gabout dans le forum VBA Access
    Réponses: 2
    Dernier message: 07/10/2011, 20h17
  3. Dimensionner tableau word à l'aide d'une macro
    Par yannick113 dans le forum VBA Word
    Réponses: 4
    Dernier message: 07/12/2010, 11h14
  4. dimensionnement tableau latex
    Par l'acqua dans le forum Tableaux - Graphiques - Images - Flottants
    Réponses: 4
    Dernier message: 30/07/2008, 10h50
  5. Réponses: 7
    Dernier message: 19/01/2006, 18h57

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