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 :

Chaînes de caractères et pointeurs


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut Chaînes de caractères et pointeurs
    Bonjour,

    J'ai une question à propos de l'utilisation des chaînes de caractères en C (je débute et je ne maîtrise pas encore tout aàfait les pointeurs)
    J'ai été voir dans la faq C mais ça n'a pas vraiment répondut à ma question

    Si je fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char * ptr = "Bonjour tout le monde";
    printf(ptr);
    Ca fonctionne très bien mais je ne parviens pas à comprendre pourquoi.
    Pour moi :

    déclare un pointeur ptr vers un élément de type machin mais il faut initialiser ce dernier avec l'ADRESSE d'une variable machin

    Par exemple pour un entier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int i;
    int *ptr = &i
    *ptr = 587;
    mais certainement pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int *ptr = 54;
    ptr = 10
    Dois-je en conclure que l'utilisation des pointeurs n'est pas la même avec les chaines de caractères ?

    merci bien

  2. #2
    Membre chevronné
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Par défaut
    Hello,

    Citation Envoyé par Opérateur
    Bonjour,

    J'ai une question à propos de l'utilisation des chaînes de caractères en C (je débute et je ne maîtrise pas encore tout aàfait les pointeurs)
    J'ai été voir dans la faq C mais ça n'a pas vraiment répondut à ma question

    Si je fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char * ptr = "Bonjour tout le monde";
    printf(ptr);
    Ca fonctionne très bien mais je ne parviens pas à comprendre pourquoi.
    Pour moi :

    déclare un pointeur ptr vers un élément de type machin mais il faut initialiser ce dernier avec l'ADRESSE d'une variable machin
    Pas tout à fait, le terme de pointeur fait partie du type. ptr a pour type 'pointeur vers(sur) machin'. Par contre, effectivement, la valeur que prend une variable de type pointeur sur quelquechose est une adresse. C'est tout à fait ce qui est fait dans ton premier exemple. Ce qui te gêne est d'abord syntaxique : il n'y a pas besoin d'utiliser l'opérateur de prise d'adresse & pour les chaînes de caractères. ici, quand on écrit

    char * g = "froid";

    C'est directement l'adresse de l'emplacement mémoire où sont stockés les caractères de "froid" qui est affectée à g. Et surtout, il n'y a pas de type chaine de caractères en C, donc ce n'est pas comparable avec un int.



    Citation Envoyé par Opérateur
    Par exemple pour un entier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int i;
    int *ptr = &i
    *ptr = 587;
    mais certainement pas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int *ptr = 54;
    ptr = 10;
    Hé bien si, c'est en théorie OK pour les 2 exemples (on passera les détails sur l'affectation d'un int à un pointeur pour les experts enc. de mouche). Le souci du 2nd, c'est que la valeur que tu affectes à un pointeur, comme déjà dit, est une adresse. Donc le souci n'est pas d'affecter 54 par exemple à ptr, mais d'accéder par la suite à l'emplacement mémoire correspondant à cette adresse 54, on peut tout imaginer, crash, déni d'accès, etc...

    Citation Envoyé par Opérateur

    Dois-je en conclure que l'utilisation des pointeurs n'est pas la même avec les chaines de caractères ?

    merci bien
    L'utilisation des pointeurs est la même pour tout le monde. Il faut juste garder en tête qu'il n'y a pas de type chaine de caractères en C.

    A+

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Opérateur
    Dois-je en conclure que l'utilisation des pointeurs n'est pas la même avec les chaines de caractères ?
    http://emmanuel-delahaye.developpez....aine_litterale

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,
    Citation Envoyé par Foobar1329
    Hé bien si, c'est en théorie OK pour les 2 exemples (on passera les détails sur l'affectation d'un int à un pointeur pour les experts enc. de mouche). Le souci du 2nd, c'est que la valeur que tu affectes à un pointeur, comme déjà dit, est une adresse. Donc le souci n'est pas d'affecter 54 par exemple à ptr, mais d'accéder par la suite à l'emplacement mémoire correspondant à cette adresse 54, on peut tout imaginer, crash, déni d'accès, etc...
    Faisant référence à ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int *ptr = 54;
    ptr = 10;
    Tu devrais revoir ton commentaire, qui est complètement faux.

    Ce code cherche à affecter la valeur 54 à l'entier pointé par ptr (plantage, car ptr n'est pas initialisé).

    C'est la valeur 10 qui est affectée au pointeur ptr, avec effectivement un comportement conduisant très probablement à un plantage si on utilise ensuite ce pointeur

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par thewho
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int *ptr = 54;
    ptr = 10;
    Ce code cherche à affecter la valeur 54 à l'entier pointé par ptr (plantage, car ptr n'est pas initialisé).
    Pas du tout. C'est une définition de variable initialisée classique. Ce n'est pas parce que c'est un pointeur qu'il y a déréférencement.

    C'est la valeur 10 qui est affectée au pointeur ptr, avec effectivement un comportement conduisant très probablement à un plantage si on utilise ensuite ce pointeur
    Les deux lignes sont correctes, mais non portables. En effet elles cherchent à affecter un entier à un pointeur, ce qui provoque un comportement dépendant de l'implémentation (donc du compilateur). La plupart des compilateurs signaleront une incompatibilité de type et exigeront la présence d'un cast. Lire la doc du compilateur.

    Dans tout les cas, il est de la responsabilité du programmeur de s'assurer que la valeur entière à un sens pour un pointeur. Le système peut en effet interdire ou règlementer l'accès à la zone mémoire concernée. Garder aussi en tête que sur les système avec MMU (unixoides, Windows récents), les adresses physiques ne sont généralement pas accessibles.

  6. #6
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut
    merci pour toutes vos réponses

    Je sais très bien que faire ça :

    est équivalent à :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int * ptr;
    ptr = 54;
    et est différent de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int * ptr;
    *ptr = 54;
    et qu'en théorie les trois codes sont correctes mais qu'en pratique seule le dernier l'est vu que dans les deux premiers cas le compilateur râlera (on n'a pas la moindre idée de ce qui se trouve à l'adresse 54 de la mémoire et si on essaye d'aller y lire quelque chose l'OS peut tuer le proramme car il n'en a pas l'autorisation)

    Mais je pense que ton liens répond très bien à mes interrogations Emmanuel

    merci à tous

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,
    Citation Envoyé par Emmanuel Delahaye
    Pas du tout. C'est une définition de variable initialisée classique. Ce n'est pas parce que c'est un pointeur qu'il y a déréférencement
    C'est vrai. Au temps pour moi, ça m'apprendra à fréquenter le forum à des heures indues.

  8. #8
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut
    Bon, si je comprends bien

    "salut"

    est une expression C ayant comme valeur l'adresse de la première case d'un tableau de caractères initialisé avec 's' 'a' 'l' 'u' 't' ce qui explique tout

    merci

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Opérateur
    est une expression C
    Ce très précisément une 'constante chaine de caractères' si j'en crois le K&R2. En anglais, string literal.
    ayant comme valeur l'adresse de la première case d'un tableau de caractères initialisé avec 's' 'a' 'l' 'u' 't' ce qui explique tout
    Absolument (en oubliant pas le 0 final, comme indiqué dans mon article...). Et ce tableau prend de la place en mémoire (le compilateur peut néanmoins chercher à optimiser puisque ces chaines sont réputées 'à lecture seule'.)

    Par exemple :

    "boujour" et "jour" n'occupent en réalité que

    'b','o','n','j','o','u','r',0

    "bonjour" vaut adresse de 'b' (par exemple X)
    "jour" vaut adresse de 'j' (X+3)

    Evidemment, ça ne marche qu'avec les fins de mots, et la zone ne doit pas être modifiée...

  10. #10
    Membre confirmé
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2006
    Messages
    112
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2006
    Messages : 112
    Par défaut
    Je comprends

    Notez que cette histoire ne me dérangeait pas en soit (ça fonctionnait donc pas de problème) mais je n'aime pas faire des choses que je ne comprends pas donc j'ai préféré poster la question ici

    merci

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Opérateur
    <...> mais je n'aime pas faire des choses que je ne comprends pas donc j'ai préféré poster la question ici
    Et tu as eu parfaitement raison. Il est excellent d'aller au fond des choses.

  12. #12
    Membre chevronné
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Par défaut
    Hello,

    Citation Envoyé par thewho
    Bonjour,

    Faisant référence à ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int *ptr = 54;
    ptr = 10;
    Tu devrais revoir ton commentaire, qui est complètement faux.

    Ce code cherche à affecter la valeur 54 à l'entier pointé par ptr (plantage, car ptr n'est pas initialisé).
    Elle est bien belle celle-là tiens

    A+

  13. #13
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    633
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 633
    Par défaut
    Bonjour,
    Citation Envoyé par Foobar1329
    Elle est bien belle celle-là tiens
    C'est exact, et je me demande encore comment j'ai pu écrire ça (même en tenant compte de l'heure à laquelle je l'ai fait).

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 16/05/2011, 17h58
  2. Pointeurs et chaînes de caractères
    Par yo_haha dans le forum Débuter
    Réponses: 30
    Dernier message: 28/11/2008, 21h37
  3. Pointeur & chaînes de caractéres
    Par Delnir dans le forum Débuter
    Réponses: 5
    Dernier message: 06/02/2008, 13h58
  4. Pointeur et chaîne de caractères
    Par gijode dans le forum C
    Réponses: 4
    Dernier message: 22/11/2006, 09h26
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

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