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 :

const char* et char*const


Sujet :

C

  1. #1
    Futur Membre du Club
    Inscrit en
    Septembre 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 13
    Points : 9
    Points
    9
    Par défaut const char* et char*const
    Bonjour tout le monde,

    S'il-vous-plaît, tout d'abord, est-ce que quelqu'un pourrait m'expliquer pourquoi toutes les adresses de variables contiennent le même nombre de chiffres, sauf les chaines de caractères, qui sont dans une adresse qui manque un chiffre, et qui semble localisée loin des autres variables ?

    Je croyais que toutes les variables locales étaient empilées lors de l'appel à la fonction, donc très proches les unes des autres de point de vue adresse!! alors pourquoi j'obtiens un résultat de ce type:

    exemple d'adresse d'un entier, d'un float ou d'un pointeur vers un caractère initialisé à l'adresse d'un caractère unique (variables ou constants):
    0xbf9557e4

    exemple d'adresse d'une chaîne de caractères variable ou constante:
    0x80484d0

    Autre remarque intéressante?: lorsque je répète l'exécution du programme, l'adresse imprimée par printf diffère à chaque exécution pour toute les variables(ce qui est normal), mais reste la même des vingtaines de fois pour les chaines de caractères (0x80484hh avec hh(hexadecimal) qui ne change qu'après une vingtaine d'exécutions).

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 921
    Points : 220 495
    Points
    220 495
    Billets dans le blog
    127
    Par défaut
    Bonjour,

    Déjà, je me demande pourquoi vous regardez l'emplacement mémoire de vos variables, mais passons (il n'y a pas de mal)
    Maintenant, la première différence que vous citez, c'est que les variables passé par paramètres, sont des copies de celles qui viennent de la fonctionne appelante. Du coup, ces variables sont crée lors de l'appel à la fonction ... du coup, il y a de très forte chance qu'elle se suivent.
    La différence pour la chaine de caractère, c'est que c'est déjà un pointeur que vous passez (bah oui, une chaine de caractère c'est un char*). Celui là, il vient de la fonction appelante, et n'est pas crée lors de l'appel de la fonction, donc il est probable qu'il n'est pas le même emplacement mémoire (et qu'il soit "loin").

    Deuxième point ... les constantes (variables dont les valeurs sont directement écrite dans le programme (variable littérales, je crois que l'on dit) sont dans le programme en lui même (le binaire), et donc l'adresse indique un espace bien précis du programme, qui est celui réservé pour les données constantes.
    Les variables (non littérales), qui sont donc crée à l'exécution, sont placé autre part dans le programme. Du coup vous avez une différence "grande" (même si tout ceci est relatif).

    Je vous invite à voir une explication sur la structure des programmes (avec explication du tas / de la pile / ...)

    Finalement, sur un système 32 bits, les adresses sont représentés sur 8 caractères (0x est là pour dire que c'est de l'hexa). Limite absolue: 16^8 ou 2^32
    Les systèmes 64bits (qui se font de plus en plus présent) ont des adresses écrite sur 64bits -> 16 caractères hexadécimal. Limite absolue 16^16 ou 2^64

  3. #3
    Futur Membre du Club
    Inscrit en
    Septembre 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 13
    Points : 9
    Points
    9
    Par défaut du nouveau
    Bonjour, merci pour la réponse très riche, je viens aussi de découvrir quelques faits, après quelques essais, et j'ai besoin de confirmation si possible:

    un pointeur de type char* est le seul type de pointeurs pouvant recevoir l'adresse d'une constante, dans ce cas une chaîne de caractères; Cette dernière est placée dans une zone à part dont l'adresse est composée de 7 chiffres hexadécimaux !!!exemple: 0x80484e5 Alors que le pointeur lui-même contenant l'adresse est empilé, comme toute variable locale.

    toutes les variables globales sont aussi placées dans une zone de la mémoire identifiée par seulement 7 chiffres hexadécimaux !!!exemple:0x80495c6

    Je pense que je dois commencer une nouvelle discussion plus orientée vers ce sujet ("adresse mémoire composée de 7 chiffres") ? car j'ai cherché sur google en vain

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 921
    Points : 220 495
    Points
    220 495
    Billets dans le blog
    127
    Par défaut
    Je ne pense pas que l'adresse soit composé de 7 chiffres.
    Je pense que celle ci en a bien huit, mais que le tout premier est un 0 et il est implicite...

    Tout pointeur peut recevoir l'adresse d'une constante, mais ce pointeur doit être déclaré comme pointant une constante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    const int val = 42;
    const int* i = &val;
    Qui est valide.

  5. #5
    Futur Membre du Club
    Inscrit en
    Septembre 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    J'entends par constante: une constante numérique ou chaine de caractères, qui n'est pas associée à un identifiant, à la différence d'une variable définie avec le terme const; est-ce que le premier point devient dans ce cas valide ?
    merci LittleWhite

  6. #6
    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
    un pointeur de type char* est le seul type de pointeurs pouvant recevoir l'adresse d'une constante, dans ce cas une chaîne de caractères;
    En fait, on n'a pas dans ce cas l'adresse d'une constante, mais l'adresse d'un objet (non modifiable) de type char[] : le tableau qui contient la chaîne de caractères.
    En C99, ce principe a été étendu à d'autres choses que les chaines de caractères (et pour des objets modifiables). Par exemple :

    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
       int * p ;
       int * q ;
       char * s1;
       char * s2;
     
       p  =  (int[]){3,4,5};
    // q  =  &7; illégal
       q  =  &(int){7};
       s1 =  "abcde";    // s1 devrait être const char*
       s2 =  (char[]){"xyz"};
     
       printf("%d %d %s %s\n",p[1],*q,s1,s2);
    // Sortie : 4 7 abcde xyz
       p[1]   =  8;
       *q     = -1;
    // s1[1] =  '0'; interdit
       s2[1] =  't';
       printf("%d %d %s %s\n",p[1],*q,s1,s2);
    // Sortie : 8 -1 abcde xtz
    En fait, dans tous ces cas, il s'agit d'objets (modifiables ou non) non nommés.

  7. #7
    Futur Membre du Club
    Inscrit en
    Septembre 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup pour cette réponse, diogene, je ne savais pas qu'il y avait le type char[], car je croyais que les tableaux de caractères avaient le type char*, et encore moins toutes ces nouveautés du C99.

  8. #8
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 921
    Points : 220 495
    Points
    220 495
    Billets dans le blog
    127
    Par défaut
    char[] et char* signifie exactement la meme chose.

  9. #9
    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
    @yessine66 :
    je ne savais pas qu'il y avait le type char[],
    Si tu le savais, tu as déjà sans doute écrit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char tab[8];
    // ou
    typedef char Ttab[8];
    Il s'agit simplement du type tableau de char.
    je croyais que les tableaux de caractères avaient le type char*
    Absolument pas, char * est le type "adresse de char", pas tableau de char. C'est une confusion fréquente et source de nombreuses incompréhensions de ce langage.

    @LittleWhite :
    char[] et char* signifie exactement la meme chose.
    Absolument pas.
    Il n'y a qu'un seul cas où la syntaxe du langage permet d'écrire indifféremment l'un ou l'autre, c'est dans la définition du type d'un paramètre d'une fonction (et ce n'est pas une bonne chose à mon avis). Dans ce cas la déclaration de type char[] est interprétée par le compilateur comme char*.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int fonc(int * t)
    {....}
    //ou
    int fonc(int t[]) // ici t est en fait un int*
    {....}

  10. #10
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 921
    Points : 220 495
    Points
    220 495
    Billets dans le blog
    127
    Par défaut
    Oh oui ... :red: (vas se cacher)
    Mais vous auriez pu expliquer la difference du coup ... J'espere que cette fois, je ne dirai pas trop de betise (cela commence a bien faire )

    Donc char[] c'est pour un tableau de char statique (la taille ne changera pas)
    char* c'est pour un pointeur sur un char (un tableau dynamique)

  11. #11
    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
    Citation Envoyé par LittleWhite Voir le message
    ...
    Donc char[] c'est pour un tableau de char statique (la taille ne changera pas)
    ou pour un tableau en allocation automatique (l'allocation statique couvre les globales et les variables déclarées static).
    char* c'est pour un pointeur sur un char (un tableau dynamique)
    En fait, un objet créé par allocation dynamique est un objet non nommé, accessible donc uniquement via son adresse (comme dans les exemples cités dans une précédente réponse). D'où le pointeur.

  12. #12
    Futur Membre du Club
    Inscrit en
    Septembre 2010
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 13
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup pour cette clarification, c'est précisément ce que j'essayais de savoir:

    Absolument pas, char * est le type "adresse de char", pas tableau de char. C'est une confusion fréquente et source de nombreuses incompréhensions de ce langage.
    En fait, un objet créé par allocation dynamique est un objet non nommé, accessible donc uniquement via son adresse (comme dans les exemples cités dans une précédente réponse). D'où le pointeur.
    Merci diogene.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 03/03/2010, 11h35
  2. const char* et unsigned const char*
    Par vandamme dans le forum C
    Réponses: 2
    Dernier message: 18/11/2009, 01h16
  3. Réponses: 7
    Dernier message: 16/02/2008, 08h30
  4. Réponses: 13
    Dernier message: 02/04/2007, 12h04
  5. error: invalid conversion from `const wxChar*' to `CHAR*'
    Par barbarello dans le forum wxWidgets
    Réponses: 16
    Dernier message: 31/01/2006, 12h28

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