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 :

Déclaration et initialisation de variables en C


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 66
    Points : 62
    Points
    62
    Par défaut Déclaration et initialisation de variables en C
    Bonjour,

    juste une question qu'on se pose avec un collègue (j'ai parié un café).

    d'après la norme ANSI C, peut-on initialiser une variable automatique lors de sa déclaration ? comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int c = 1;
    char *p = NULL;
    etc.

    Mon collègue me dit que seule la dernière variable déclarée peut-être initialisée.

    je ne trouve pas la norme sur google... donc à l'aide s'il vous plait !

  2. #2
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    je ne retrouve plus le site sur lequel on pouvais telecharger le dernier draft de la norme C99
    cependant j'ai ça en stock : http://www.lysator.liu.se/c/rat/title.html

    ça devrais pouvoir repondre a ta question.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2005
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2005
    Messages : 66
    Points : 62
    Points
    62
    Par défaut
    j'avais trouvé la norme en fait, mais merci beaucoup.

    la norme dit qu'on peut déclarer (je résume) une variable des façons suivantes :

    déclarateur
    déclarateur = initialiseur

    elle n'interdit pas que les déclarations autres que la dernière soient de la forme

    déclarateur = initialiseur

    donc pour moi c'est bon.

    Par contre, j'ai deux témoignages (indépendants) me confirmant que des compilateurs n'acceptent que seule la dernière variable déclarée soit initialisée.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2003
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2003
    Messages : 15
    Points : 11
    Points
    11
    Par défaut
    Je pense que tes sources ont tort

    La preuve suffit de regarder les sources du noyau linux, il n'est pas rare que des variables soient initialisées dès leur déclaration.

    Après je ne connais pas tout les compilateurs mais je vois pas pourquoi certains n'accepteraient pas ça ...

  5. #5
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Un simple test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
    int main(void)
    {
       int i = 0;
       int j = 2;
       printf("i : %d j : %d\n", i, j);
       return 0;
    }
    Et le problème est réglé
    Maintenant, si les compilos ne respectent pas la norme...

  6. #6
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    C'est par pour rien qu'on insiste souvent sur le fait d'initialiser à une valeur par défaut les variables lors de leur déclaration ... c'est quelque chose de conseillé donc c'est possible. Après si vous utilisez des compilateurs exotiques là rien n'est garantit !

  7. #7
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Salut,

    Selon la norme, il est possible d'initialiser n'importe quelle variable lors de sa déclarartion. L'interdire serait une abération puisque c'est une sécurité. Ainsi tu peut écrire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    {
        /* Je n'initialise en général pas les indices de boucle de cette manière 
            et préfère en général définir une variable par ligne sauf pour les 
            indices de boucle justement */
        int i = 0, j = 0, k = 0; 
        int x = 10;
        char s_buffer[50] = {0};
     
        /* ... */
    }
    Thierry

  8. #8
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par benhoeil
    Bonjour,

    juste une question qu'on se pose avec un collègue (j'ai parié un café).

    d'après la norme ANSI C, peut-on initialiser une variable automatique lors de sa déclaration ? comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int c = 1;
    char *p = NULL;
    etc.

    Mon collègue me dit que seule la dernière variable déclarée peut-être initialisée.

    je ne trouve pas la norme sur google... donc à l'aide s'il vous plait !

    Avec tous les compilateurs récents, il est possible d'initialiser les variables locales au moment de leur déclaration. Donc tu as raison.
    Par contre, il fut un temps, où les compilateurs C ne tolérait pas que l’on mélange du code lors des déclarations des variables automatiques (l’initialisation d’une variable automatique lors de sa déclaration génère du code). Donc tes collègues avaient également raison, mais c'était il ya fort longtemps. Il va falloir qu’ils se mettent vite au goût du jour car la norme a beaucoup évolué.

  9. #9
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par crocodilex
    Avec tous les compilateurs récents, il est possible d'initialiser les variables locales au moment de leur déclaration. Donc tu as raison.
    Par contre, il fut un temps, où les compilateurs C ne tolérait pas que l’on mélange du code lors des déclarations des variables automatiques (l’initialisation d’une variable automatique lors de sa déclaration génère du code). Donc tes collègues avaient également raison. Mais par contre il va falloir qu’ils se mettent vite au goût du jour car la norme a beaucoup évolué.
    Le mélange code/déclaration a été ajouté à la dernière norme qui est moins utilisée que le C90 qui ne permet pas se genre de fantaisie

  10. #10
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par gege2061
    Le mélange code/déclaration a été ajouté à la dernière norme qui est moins utilisée que le C90 qui ne permet pas se genre de fantaisie
    Merci de ces précisions gege2061, pourquoi pourquoi gcc avec -ansi -std=c89 -pedantic ne me donne aucune erreur si potentiellement cela peut poser des problèmes de portabilité?

    Thierry

  11. #11
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par mujigka
    Merci de ces précisions gege2061, pourquoi pourquoi gcc avec -ansi -std=c89 -pedantic ne me donne aucune erreur si potentiellement cela peut poser des problèmes de portabilité?
    -ansi c'est la même chose que -std=c89 mais normalement il devrait te signaler une erreur

    Peut être avec -Wall (voir -W) ?

  12. #12
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    Citation Envoyé par Trap D
    Un simple test
    un test (ou plusieurs) ne peux pas repondre a une question commençant par:"est-ce que la norme ..."

  13. #13
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par gege2061
    -ansi c'est la même chose que -std=c89 mais normalement il devrait te signaler une erreur

    Peut être avec -Wall (voir -W) ?
    Je n'ai pas d'exemplaire de la norme C90. Alors je vais citer le manuel de référence de K&R 2ème édition annexe A8.7:
    Citation Envoyé par K&R2

    L'initialisation:

    Au moment de la déclaration d'un objet, son déclarateur-init peut spécifier une valeur initiale pour l'identificateur déclaré. L'initialisateur est précédé de =, et il est constitué soit d'une expression, soit d'une liste d'initialisateurs imbriqués entre accolade...
    [EDIT]
    Je n'obtient aucune erreur de compilation de ce micro-code:
    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
     
    /* Programme test.c: test validité de l'initialisation lors de
        déclaration en C90 strict */
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(void)
    {
        int i = 0, j = 0, k = 0;
        int x = 10;
        char s_buffer[50] = {0};
     
        /* Pour éviter le Warning: unused variable */
        x = i + j + k;
        (void) s_buffer[0];
     
        printf("FIN du test!\n");
     
        return EXIT_SUCCESS;
    }
    en compilant avec gcc comme je le fais d'habitude:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -Wall -Wextra -Werror -ansi -pedantic -Wwrite-strings -Wstrict-prototypes -Wmain test.c
    [/EDIT]

    Thierry

  14. #14
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par mujigka
    Je n'ai pas d'exemplaire de la norme C90. Alors je vais citer le manuel de référence de K&R 2ème édition annexe A8.7:
    On doit pas parler de la même chose

    Je parle de ça : Mélange déclaration/code

  15. #15
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    Citation Envoyé par gege2061
    On doit pas parler de la même chose

    Je parle de ça : Mélange déclaration/code
    On ne parle effectivement pas de la même chose, mais la question du PO était:
    Citation Envoyé par benhoeil
    d'après la norme ANSI C, peut-on initialiser une variable automatique lors de sa déclaration ? comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int c = 1; char *p = NULL;
    Pour le reste, on est d'accord qu'en C90, les variables automatiques doivent être déclarées en début de bloc.

    Thierry

  16. #16
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Citation Envoyé par Dark_Ebola
    un test (ou plusieurs) ne peux pas repondre a une question commençant par:"est-ce que la norme ..."
    Je donnais cet exemple pour savoir si le compilo acceptait l'initialisation des variables locales, c'est tout, celà ne va pas plus loins, et c'est vrai que même dans ce cas, on ne peut rien en déduire d'absolu quant au compilo si l'initialisation semble réussir.

  17. #17
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 923
    Points
    17 923
    Billets dans le blog
    2
    Par défaut
    Non seulement cela existe depuis le début (voir réponse sur K&R) sauf à l'intérieur du code, mais c'est même fortement recommandé, surtout si vous faites affaire à des pointeurs, avec des allocations dynamiques à plusieurs niveaux.

    Il y a 15 ans, notre équipe à passé plus de 3 semaines à tenter de trouver pourquoi on avait un crash.. Réponse : les pointeurs servant aux allocations n'étaient pas initilialisés, et lorsqu'on écrivait par exemple dans un tableau alloué au 5 ième sous-niveau, les données d'un tableau alloué au premier niveau étaient modifiées...

    Explication :

    Tant qu'une variable n'est pas initialisée, dans une routine, le compilateur ne génére qu'une adresse sur la pile, donc relative... Si par contre elle est initialisée, il lui attribue une adresse comme étant adresse physique de la fonction + placement dans la liste de déclaration, qui dans ce cas est alors une adresse absolue (relative uniquement à l'adresse du début de fonction).
    (et donc est chargée par le loader au runtime).

    C'est particulièrement sensible pour des pointeurs servant à faire de l'allocation dynamique :

    une suite de 7 niveaux de profondeur dont chaque niveau contient par exemple 10 variables dépasse les 64 (ou 128, ou ... taille de la pile).. et
    donc lorsqu'on atteint le dernier niveau et qu'on alloue quelque chose, la zone mémoire où un pointeur du premier niveau aurait alloué n'est plus connue.... D'où possibilité de recouvrement éventuel...

    Conclusion :

    Chaque fois que dans une routine vous déclarez un pointeur, initialisez-le dans TOUS les cas, même à NULL.

    Pour des variables non pointeurs, cela ne change rien (la place est réservée et la variable n'a plus de sens une fois sorti de la routine).

  18. #18
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par benhoeil
    d'après la norme ANSI C, peut-on initialiser une variable automatique lors de sa déclaration ? comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int c = 1;
    char *p = NULL;
    Oui.
    Mon collègue me dit que seule la dernière variable déclarée peut-être initialisée.
    C'est faux. N'importe quelle variable peut être initialisée. La seul contrainte pour les variables statiques est que l'initialisateur doit être une expression constante.

    Sinon, une variable locale peut être initialisée par une expression quelconque, le retour d'un fonction etc.

  19. #19
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par PsyKroPack
    La preuve suffit de regarder les sources du noyau linux,<...>
    Ca ne prouve rien. Le noyau GNU/linux est écrit en GNUC et non en C. Ce sont deux langages différents.

Discussions similaires

  1. Déclaration et initialisation d'une variable
    Par micjal dans le forum Visual C++
    Réponses: 6
    Dernier message: 23/04/2014, 18h42
  2. Réponses: 2
    Dernier message: 06/11/2007, 20h50
  3. [VB.Net]Déclaration et initialisation d'une variable
    Par DonF dans le forum Windows Forms
    Réponses: 6
    Dernier message: 14/11/2006, 20h05
  4. [VB6]Initialiser une variable Static dans un évenement
    Par loverdose dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 20/01/2005, 14h57
  5. Réponses: 9
    Dernier message: 29/06/2004, 08h40

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