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 :

deux facons de modifier un char


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut deux facons de modifier un char
    bonjour
    on peut faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    char g[2];
    g[0]='a';
    g[1]='b';
    ensuite, si on veut modifier, on peut faire:
    par contre, si on a déclarer g comme ceci:
    puis pour modifier le deuxième élément on fait:
    car marche pas. ca bug
    Pourquoi?
    Dans les deux cas, g est bien déclaré de manière équivalentes

    merci

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 461
    Par défaut
    Bonsoir,

    Citation Envoyé par deubelte Voir le message
    car marche pas. ca bug
    Pourquoi?
    Dans les deux cas, g est bien déclaré de manière équivalentes
    Pas tout-à-fait.

    Dans le premier cas, tu déclares un tableau de caractères et obtiens par la même occasion un pointeur pour le manipuler. Un tableau est une suite de variables, qui sont faites pour être modifiées, et leur espace est réservé dans la pile ou dans une autre zone inscriptible de la mémoire.

    Dans le second cas, tu ne déclares qu'un pointeur vers un caractère ou une chaîne de caractère. Tu ne réserves pas d'espace pour cette chaîne. Cependant, tu initialises ce pointeur avec l'adresse de la chaîne que tu passes entre guillemets mais ce sont alors deux expressions distinctes.

    En façade, une chaîne de caractères entre guillemets est une expression de type const char *. En coulisses, comme cette chaîne doit exister avant l'exécution du programme, le compilateur va soit la mettre avec le code, soit dans un segment dédié mais tout aussi en lecture seule.

    Toutefois, tu peux quand même utiliser les guillemets pour initialiser le contenu d'un tableau de caractères :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char chaine [6] = "Hello";
    ... fonctionne. Le contenu de la chaîne sera bien copié à l'intérieur de ton tableau dès l'initialisation et, de là, tu pourras le modifier.

  3. #3
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    ouais, c'est compliqué quoi.

    Il y a donc bien 3 facons de déclarer une chaine de caractère, mais celle qui consiste à déclarer un tableau nen n''est pas vraiment une puisqu'on peut tout mettre dans un tableau.

    Comment alors dans le second cas, modifier le deuxieme caractère de la chaine, c'est-à-dire 'b'?

  4. #4
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    d'ailleurs, il n'y en a pas 3, mais 4, car on peut faire ca:

    char h[2]={'r','r','r'};
    même si c'est un tableau, et pas une chaine de caractère

  5. #5
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    en C++, on utile des std::string à la place des tableau de char.
    C'est bien plus pratique et sûr
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  6. #6
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Citation Envoyé par deubelte Voir le message
    d'ailleurs, il n'y en a pas 3, mais 4, car on peut faire ca:

    char h[2]={'r','r','r'};
    même si c'est un tableau, et pas une chaine de caractère
    En C, une chaîne de caractères, c'est un tableau de caractères terminé par un '\0'.

    Ensuite, pour en revenir au fait que
    ne soit pas modifiable, il faut se rappeler que C est un langage assez bas-niveau, et que donc :
    • la raison n'est pas triviale
    • elle est liée à la structure du format des exécutables


    En C++, tu peux utiliser une structure de langage haut-niveau, à savoir, std::string, qui t'affranchira de ce problème.

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    [LIST][*]la raison n'est pas triviale
    En fait, ta réponse précédente était très claire et explique le mieux:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char *ma_chaine="tutu";
    "tutu"-> est un const char *. Qui dit const, dit pas modifiable. (après, je te l'accorde, expliquer que c'est dans un segment non modifiable, c'est le niveau 2 de l'explication ).

    Pour résumer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    char chaine_1[2];
    char chaine_2[] = "tutu";
    char *chaine_3 = "tutu";
    int main()
    {
         char chaine_4[2];
         char chaine_5[]="tutu";
         char *chaine_6="tutu";
    }
    1. chaine_1 : tu déclare un tableau global non initialisé. L'espace mémoire (2 octets) est réservé sur une zone mémoire modifiable.
    2. chaine_2 : Strictement identique au précédent (modulo la taille), en plus l'espace mémoire est initialisé avec "tutu\0".
    3. chaine_3: tu déclare une chaîne de caractère ("tutu") et un pointeur sur cette chaine de caractère. Tu as deux zones mémoires réservées : une pour stocker "tutu\0" (dans une zone mémoire non modifiable) et une (dans une zone modifiable) pour stocker l'adresse vers cette chaîne (chaine_3).
    4. chaine_4 : tu déclare un tableau non initialisé. L'espace mémoire (de 2 octets) est réservé sur la pile.
    5. chaine_5 : idem que précédent : espace mémoire réservé sur la pile et initialisé avec "tutu\0"
    6. chaine_6 : presque comme chaine_3 : deux zones mémoires réservées : une pour stocker "tutu\0" (dans une zone mémoire non modifiable) et une sur la pile pour l'adresse vers cette chaîne.


    Pour t'en convaincre, tu peux faire ceci, tu verra les différentes adresse :
    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
     
    char chaine_1[2];
    char chaine_2[] = "tutu";
    char *chaine_3 = "tutu";
    int main()
    {
         char chaine_4[2];
         char chaine_5[]="tutu";
         char *chaine_6="tutu";
     
         std::cout<<"chaine_1 : "<<reinterpret_cast<int*>(chaine_1)<<" "<<&chaine_1<<std::endl;
         std::cout<<"chaine_2 : "<<reinterpret_cast<int*>(chaine_2)<<" "<<&chaine_2<<std::endl;
         std::cout<<"chaine_3 : "<<reinterpret_cast<int*>(chaine_3)<<" "<<&chaine_3<<std::endl;
         std::cout<<"chaine_4 : "<<reinterpret_cast<int*>(chaine_4)<<" "<<&chaine_4<<std::endl;
         std::cout<<"chaine_5 : "<<reinterpret_cast<int*>(chaine_5)<<" "<<&chaine_5<<std::endl;
         std::cout<<"chaine_6 : "<<reinterpret_cast<int*>(chaine_6)<<" "<<&chaine_6<<std::endl;
     
         return 0;
    }

Discussions similaires

  1. [XL-2010] Worksheet_Change si deux cellules sont modifiées
    Par Kbx59 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 05/07/2014, 13h54
  2. Parcourir et modifier un char*
    Par Molos dans le forum Débuter
    Réponses: 6
    Dernier message: 02/03/2012, 14h15
  3. Modifier une char* dans une fonction
    Par kase74 dans le forum Débuter
    Réponses: 6
    Dernier message: 20/01/2009, 21h06
  4. Trier Une requête de deux facons
    Par starr dans le forum Requêtes
    Réponses: 1
    Dernier message: 19/06/2007, 12h19
  5. Trier Une requête de deux facon
    Par starr dans le forum Langage SQL
    Réponses: 12
    Dernier message: 18/06/2007, 14h29

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