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++

  1. #1
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    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
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 360
    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 360
    Points : 23 600
    Points
    23 600
    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
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    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
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    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 : 32
    Localisation : Suisse

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

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    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 émérite
    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
    Points : 2 799
    Points
    2 799
    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
    Points : 13 017
    Points
    13 017
    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;
    }

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Sous gcc, pour éviter ce genre de problèmes, il y a l'option -Wwrite-strings.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Débutant  
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Points : 217
    Points
    217
    Par défaut
    Tu as oublié la déclaration de ce type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char g[3]={'r','r','r'};
    mais a mon avis, c'est la pire de toute les déclaration


    by the way, quel est le langage qui est a un niveau encore plus bas que le C?

  10. #10
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par deubelte Voir le message
    by the way, quel est le langage qui est a un niveau encore plus bas que le C?
    L'assembleur et encore en dessous le langage machine ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  11. #11
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par deubelte Voir le message
    quel est le langage qui est a un niveau encore plus bas que le C?
    forth, bliss, bcpl sont ceux qui me viennent a l'esprit.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  12. #12
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par deubelte Voir le message
    Tu as oublié la déclaration de ce type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char g[3]={'r','r','r'};
    mais a mon avis, c'est la pire de toute les déclaration
    C'est plus que pire, puisque tu ne mets pas de \0. Donc tu as bien un tableau de char, mais ne pense pas à utiliser g comme une chaîne de caractère !
    Du point de vue de la façon dont ça se retrouve en mémoire, c'est équivalent à char g[3]="rr"; ou char g[]="rr"; (une zone mémoire de 3 octets modifiable)

    Citation Envoyé par deubelte Voir le message
    by the way, quel est le langage qui est a un niveau encore plus bas que le C?
    Attention, en dessus/en dessous, ça n'a pas de sens.
    Le C est compilé vers du code machine.
    Le C++ est compilé vers du code machine.
    L'assembleur est compilé vers du code machine.
    Dans les 3 cas on passe de texte -> code machine.

  13. #13
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Le C est compilé vers du code machine.
    Le C++ est compilé vers du code machine.
    Ha bon ?
    Je croyais qu'on avait toujours droit à une phase assembleur
    D'ailleurs, il est possible de dire au compilateur qu'il s'arrete à cette phase là (juste histoire de voir le code assembleur généré).

    C/C++ => Assembleur => Language Machine => Micro-Code
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  14. #14
    Membre émérite
    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
    Points : 2 799
    Points
    2 799
    Par défaut
    La notion de niveau est hautement subjective

    Cela dit, le passage assembleur <-> code machine est pratiquement bijectif et réversible (aux labels près), donc on peut dire que c'est très bas-niveau.

    On peut compiler du C++ en C, du C en CLI ou en bytecode java, du C++ directement en assembleur, bref...

    La notion de niveau de langage s'apprécie plus par rapport aux structures abstraites de données qu'il propose (donc, C++ est haut-niveau), et par la manière dont il masque la réalité du matériel sur lequel il va s'exécuter (donc, C++ est aussi bas-niveau ).

  15. #15
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par nicroman Voir le message
    Ha bon ?
    Je croyais qu'on avait toujours droit à une phase assembleur
    D'ailleurs, il est possible de dire au compilateur qu'il s'arrete à cette phase là (juste histoire de voir le code assembleur généré).

    C/C++ => Assembleur => Language Machine => Micro-Code
    Je me trompe peut être, mais j'ai cru comprendre que le code généré est le code machine.
    Après tu as une correspondance directe entre le code machine et le code assembleur. Donc, j'ai plus compris comme un désassemblage du code produit, plutôt qu'une compilation en 2 phases? Enfin, je ne sais pas trop si ça a du sens puisque tu as une correspondance directe entre un code machine et une instruction asm. Ce que j'ai voulu dire c'est que je ne pense pas que le compilateur produise d'abord un fichier texte asm qui ensuite est compilé avec un compilateur assembleur.

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Ce que j'ai voulu dire c'est que je ne pense pas que le compilateur produise d'abord un fichier texte asm qui ensuite est compilé avec un compilateur assembleur.
    Pareil. Je pense qu'il ne touche jamais au texte asm à moins qu'on lui demande, auquel cas il produit le texte asm en même temps que le code assembleur.
    Du moins, un compilateur moderne et peu modulaire. Pour les anciens ou les plus modulaires, il y a peut-être toujours un passage obligatoire par l'assembleur.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par white_tentacle Voir le message
    Cela dit, le passage assembleur <-> code machine est pratiquement bijectif et réversible (aux labels près), donc on peut dire que c'est très bas-niveau.
    Aux labels et aux macros prets. Les macros ne sont pas a negliger si on parle de programmer directement en assembleur: les programmeurs en assembleurs ne s'en passent que sur des petits projets. (Et ce qu'il est possible de faire avec des macros-assembleurs concu pour la programmation de gros projets en assembleur est etonnant).

    La notion de niveau de langage s'apprécie plus par rapport aux structures abstraites de données qu'il propose (donc, C++ est haut-niveau), et par la manière dont il masque la réalité du matériel sur lequel il va s'exécuter (donc, C++ est aussi bas-niveau ).
    +1

    Citation Envoyé par nicroman Voir le message
    Je croyais qu'on avait toujours droit à une phase assembleur
    D'ailleurs, il est possible de dire au compilateur qu'il s'arrete à cette phase là (juste histoire de voir le code assembleur généré).

    C/C++ => Assembleur => Language Machine => Micro-Code
    Comme deja ecrit par d'autre, une representation assembleur n'est la que dans les outils fortement modulaires.

    Quant a la notion classique de micro-code, c'est quelque chose de purement interne au processeur (et en fait le langage machine n'est pas transforme en micro-code, il est interprete par un programme ecrit en micro-code; c'est une machine virtuelle pour prendre un vocabulaire moderne -- la techno transmetra est interessante, c'est un compilateur JIT implemente en micro code plutot qu'un interpreteur), et ensuite c'est passe de mode durant les annees 80 (une partie de l'utilite a ete reprise par les caches, l'autre par une logique beaucoup plus repartie).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

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, 14h54
  2. Parcourir et modifier un char*
    Par Molos dans le forum Débuter
    Réponses: 6
    Dernier message: 02/03/2012, 15h15
  3. Modifier une char* dans une fonction
    Par kase74 dans le forum Débuter
    Réponses: 6
    Dernier message: 20/01/2009, 22h06
  4. Trier Une requête de deux facons
    Par starr dans le forum Requêtes
    Réponses: 1
    Dernier message: 19/06/2007, 13h19
  5. Trier Une requête de deux facon
    Par starr dans le forum Langage SQL
    Réponses: 12
    Dernier message: 18/06/2007, 15h29

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