DU CHAR* AU STRING: COMMENT LES PIÈGES DU C SONT RÉSOLUS EN C++
davwart
Messages postés855Date d'inscriptionmardi 19 novembre 2002StatutMembreDernière intervention28 juillet 2009
-
3 févr. 2003 à 11:13
spidermario
Messages postés121Date d'inscriptionmercredi 26 octobre 2005StatutMembreDernière intervention14 mars 2009
-
6 août 2006 à 20:43
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
spidermario
Messages postés121Date d'inscriptionmercredi 26 octobre 2005StatutMembreDernière intervention14 mars 20091 6 août 2006 à 20:43
Pas mal, à part quelques passages de codes dans le PDF qui sont un peu illisibles...
Du char-abia, quoi.
(Désolé, j'ai pas pu me retenir ^^);
arsinoe77
Messages postés1Date d'inscriptionlundi 7 février 2005StatutMembreDernière intervention 7 février 2005 7 févr. 2005 à 19:49
Bonjour, je suis une newbie de chez newbie. J'ai voulu télécharger les documents mais je n'ai pas réussi :(
cs_davidsm
Messages postés35Date d'inscriptionlundi 6 janvier 2003StatutMembreDernière intervention12 novembre 2004 13 févr. 2003 à 20:14
Le document pdf dans le zip est très intéressant.
La présentation est sérieuse avec de l'humour ce qui ne gâte rien. Elle incite à l'utilisation de l'objet standard du C++, STRING.
Sur Deuxième partie C++, j'ajouterais par rapport au document et aux commentaires :
- Il ya un point important sur lequel il faut mettre l'accent : Le couplage string et flux de données avec les opérateurs >> et << qui facilitent la programmation. Il est tellement naturel que dans le document cela n'a pas été suffisamment signalé, de mon point de vue.
- J'ajouterai pour être complet que string dispose de « pointeurs intelligents qui offrent à la fois de la sécurité et du service » : les itérateurs. D'ailleurs ils sont mis en ?uvre pour utiliser la fonction algorithm « replace() » et traverser la chaîne str2 à la page 12.
- On pourrait ajouter qu'il existe un flux de données « iostringstream » qui apporte de véritables services pour effectuer les conversions de type. Souvent les programmateur C++ butent sur ces problèmes alors qu'un objet est disponible en standard pour assurer la gestion des flux chaîne et les formater.
Aux programmeurs C++ ouvrez le zip lisez le pdf.
Il y a un débat entre C et C++ dans les commentaires qui, d'après moi, n'a pas lieu d'être.
Soyons positifs : Que ceux qui font du C le fassent bien et que ceux qui font de l'objet avec C++ en fassent de même.
cs_vieuxLion
Messages postés455Date d'inscriptionsamedi 26 octobre 2002StatutMembreDernière intervention 6 avril 20048 9 févr. 2003 à 17:25
y en a qui construisent ... y en a qui cherchent à casser.
je vois que tu n'a pas compris grand chose mais ce n'est pas une raison pour polluer négativement le site. (Relis les explications et teste les correctement : le code est fourni)
Etre contre les conventions standards qui consistent à préfixer par 'p' les variables de type pointeur est un choix personnel...
Attention quand tu traite d'allocation dynamique le char * p="abc"; (c'est du statique => donc tout à fait l'opposé!)
ou est donc le new? le malloc?
le problème du multi-référencement de zone mémoire, de l'optimisation (comptage de références,etc...) est très courant dans les gros logiciels... il faut donc en tenir compte (Aliassing et savoir le gérer)
Quand à mettre des 0 binaires dans une chaîne, ils y sont très souvent lorsque l'on traite des fichiers ... binaires et il faut savoir les traiter. (exemple Algorithmes de cryptage/compression/sérialisation/...)
Un char p[] est alloué sur la pile et donc libéré automatiquement en sortie de bloc... l'article ne dit pas le contraire
Merci quand même pour m'avoir fait remarqué l'emploi erroné p5 (sur 24) de char*const (j'ai modifié le pdf)
Mais contrairement à ce que tu dis un char* const EXISTE bien ! c'est un pointeur constant
alors que const char* signifie pointeur sur constante
cs_Melnofil
Messages postés71Date d'inscriptiondimanche 23 juin 2002StatutMembreDernière intervention 1 février 2008 8 févr. 2003 à 19:11
mince les slash 0 ne marchent pas ici ! Bon je vous indique où ils manquent, dans le paragraphe 1 du deuxième commentaire, en mettant un anti-slash a la place :
string s("abc/0def",7);
(quoique faut vraiment etre tordu pour mettre un /0 dans une chaine)
cs_Melnofil
Messages postés71Date d'inscriptiondimanche 23 juin 2002StatutMembreDernière intervention 1 février 2008 8 févr. 2003 à 19:06
string s("abc def",7);
cout << "s = " << s << endl;
le résultat est ..... : s = abc
Hébé tu vient d'apprendre que la le C++ est un dérivé du C et donc en possède les princpaux inconvenients (quoique faut vraiment etre tordu pour mettre un dans une chaine).
Je tient a signaler que ta solution fait apparaitre les caractères 1 à un a l'écran, ce qui suppose un balayage complet de l'ecran a chaque caractère, ce n'est pas très grave pour 10 ou 50 caractères, mais qu'en est-t-il si je veut réactualiser plusieurs lignes completes d'un coup, voir même tout écran ? ..
Réponse : Comme dans les vieux programmes, on voit l'ecran se modifier à l'oeil nu, ce qui n'est pas très estétique !
Remarque : On ne dit pas ?char *const? mais 'const char *', comme le montre les paramêtres de bien des fonctions de la lib string de C. Dans tous les cas une déclaration en "const <type> <variable>" signifie que la variable n'est pas modifié, ceci permet au compilateur de mieux simplifier votre code.
Maintenant, à mon tour de critiquer/comparer le C et le C++ (^_^)/
Désavantage numéro 1 des classes du C++ (exemple de la classe string) :
On ne sait pas ce que C++ fait avec notre chaîne, alors qu'en C on est sûr d'obtenir un code optimal. Si vous êtes doués, c donc plus long à coder mais moins long à l'execution (ou égal en temps dans le meilleur des cas)
Et c'est bien là que réside toute la difference entre ces 2 languages, le C est plus proche de la machine (du binaire), donc il permet de faire des codes plus propres, plus optimisé alors que le C++ est un language de plus haut niveau (plus loin de la machine) permettant du même coup de programmer plus facilement, mais où il faut donc encore plus avoir une confiance aveugle en le compilateur. En conclusion, le C est loin d'être une viellerie, ca serait aussi débile que de le dire a propos de l'assembleur, qui est le language incontournable de tout compilateur.
Cependant le C++ possède une qualité propre aux languages de haut niveau et absente du C : Les codes y sont très facilement portable. Ou si vous préférez, en pratique pour le codeur, il est plus facile d'importer une classe qu'une librairie désorganisée de fonctions (car il y a alors risque de conflit avec des fonctions déjà existantes, c'est pour ca que les fonctions des librairies du C s'appelent par des noms peu significatifs alors que le C++ prend les noms les plus évidents pour l'utilisateur). Il y a aussi d'autres explications sur l'importance de la portabilité tel que celles faisant intervenir la hierachie des objets, mais c plus compliqué, ca sera donc pour une prochaine fois.
Voilà j'espère que toutes mes explications, vous ont plu !
Ps: PapyLion, ca a rien à voir mais j'adore tes petits dessins ^_^
cs_Melnofil
Messages postés71Date d'inscriptiondimanche 23 juin 2002StatutMembreDernière intervention 1 février 2008 8 févr. 2003 à 18:06
Note : String est un pointeur sur char, donc l'ecriture pString signifirait un pointeur de pointeur de char (par exemple un tableau de chaine de caractères), ce qui n'est pas la cas ici ! Dans la suite, j'ai renommé tes variables en enlevant le "p" pour eviter toute confusion.
Bon j'ai pas pu aller au delà de la 6ième page, vu les énormités qu'on trouve dès le début ca craint, j'ai pu eu le courage d'aller plus loin.
La ligne suivante :
char str[] = "abc";
Déclare un tableau de taille 4 (de taille connue donc !) qui est libérée proprement a la fin (ce qui contredit ce que tu a écrit).
La différence entre "char str[];" et "char *str;" est que la première version déclare un tableau et la seconde un pointeur, ce qui n'a rien a voir !! (Par exemple on peut changer l'adresse d'un pointeur mais pas d'un tableau, essaye un "str = 0;" dans les deux cas, tu va voir la différence)
Si a un moment dans ton programme tu trouve deux pointeurs qui pointent sur la même valeur alors que tu n'y est pour rien, cela n'est pas due au C mais c'est une simplification faite par ton compilateur ! Celui ci s'etait dit : "il con celui là il me demande 2 fois la meme chose sans en modifier la valeur, je vais en mettre qu'une ca sera plus simple".
A propos de :
char *str = "abc";
str[1]='o';
Un pointeur ne peut pas être affecté directement a une zone de mémoire dynamique, pour corriger l'erreur utilise "char str[]" (ou la fonction "malloc()" suivie d'un "strcpy()" si tu veut absolument pouvoir modifier le pointeur par la suite)
En résumé, papy, le C demande une rigueur de programmation que tu n'a pas, dommage, retourne au C++ au moins, lui, comprend tes erreurs. (double cassage, Cf. Brice de Nice ;) )
Voilà, j'espère que ca remettra un peu les apprentis qui sont tombés ici, sur le droit chemin. Hé surtout, bon courage à vous tous ^_^
cs_vieuxLion
Messages postés455Date d'inscriptionsamedi 26 octobre 2002StatutMembreDernière intervention 6 avril 20048 3 févr. 2003 à 18:31
Merci pour le //
tout est alloué sur la pile. Voici l' exemple simplifié
on alloue une variable sVar (aux adresses 0x12FF24-0x12FF25)
on alloue une chaine str[4]="abc" (aux adresses 0x12FF20-0x12FF23)
on utilise strcat(str, "def") qui vient écraser sVar car elle écrit sur 0x12FF24-0x12FF28
CQFD
sur les adresses 0x12FF
davwart
Messages postés855Date d'inscriptionmardi 19 novembre 2002StatutMembreDernière intervention28 juillet 20091 3 févr. 2003 à 11:13
:))))
un premier mot: merci !
vraiment tres interessant!
j'ai cependant pas bien compris le désagrement ', avec ta variable SVar (partie I-4)... je comprends pas bien l'ecrasement.. mais je vais chercher un peu.
6 août 2006 à 20:43
Du char-abia, quoi.
(Désolé, j'ai pas pu me retenir ^^);
7 févr. 2005 à 19:49
13 févr. 2003 à 20:14
La présentation est sérieuse avec de l'humour ce qui ne gâte rien. Elle incite à l'utilisation de l'objet standard du C++, STRING.
Sur Deuxième partie C++, j'ajouterais par rapport au document et aux commentaires :
- Il ya un point important sur lequel il faut mettre l'accent : Le couplage string et flux de données avec les opérateurs >> et << qui facilitent la programmation. Il est tellement naturel que dans le document cela n'a pas été suffisamment signalé, de mon point de vue.
- J'ajouterai pour être complet que string dispose de « pointeurs intelligents qui offrent à la fois de la sécurité et du service » : les itérateurs. D'ailleurs ils sont mis en ?uvre pour utiliser la fonction algorithm « replace() » et traverser la chaîne str2 à la page 12.
- On pourrait ajouter qu'il existe un flux de données « iostringstream » qui apporte de véritables services pour effectuer les conversions de type. Souvent les programmateur C++ butent sur ces problèmes alors qu'un objet est disponible en standard pour assurer la gestion des flux chaîne et les formater.
Aux programmeurs C++ ouvrez le zip lisez le pdf.
Il y a un débat entre C et C++ dans les commentaires qui, d'après moi, n'a pas lieu d'être.
Soyons positifs : Que ceux qui font du C le fassent bien et que ceux qui font de l'objet avec C++ en fassent de même.
9 févr. 2003 à 17:25
je vois que tu n'a pas compris grand chose mais ce n'est pas une raison pour polluer négativement le site. (Relis les explications et teste les correctement : le code est fourni)
Etre contre les conventions standards qui consistent à préfixer par 'p' les variables de type pointeur est un choix personnel...
Attention quand tu traite d'allocation dynamique le char * p="abc"; (c'est du statique => donc tout à fait l'opposé!)
ou est donc le new? le malloc?
le problème du multi-référencement de zone mémoire, de l'optimisation (comptage de références,etc...) est très courant dans les gros logiciels... il faut donc en tenir compte (Aliassing et savoir le gérer)
Quand à mettre des 0 binaires dans une chaîne, ils y sont très souvent lorsque l'on traite des fichiers ... binaires et il faut savoir les traiter. (exemple Algorithmes de cryptage/compression/sérialisation/...)
Un char p[] est alloué sur la pile et donc libéré automatiquement en sortie de bloc... l'article ne dit pas le contraire
Merci quand même pour m'avoir fait remarqué l'emploi erroné p5 (sur 24) de char*const (j'ai modifié le pdf)
Mais contrairement à ce que tu dis un char* const EXISTE bien ! c'est un pointeur constant
alors que const char* signifie pointeur sur constante
8 févr. 2003 à 19:11
string s("abc/0def",7);
(quoique faut vraiment etre tordu pour mettre un /0 dans une chaine)
8 févr. 2003 à 19:06
cout << "s = " << s << endl;
le résultat est ..... : s = abc
Hébé tu vient d'apprendre que la le C++ est un dérivé du C et donc en possède les princpaux inconvenients (quoique faut vraiment etre tordu pour mettre un dans une chaine).
Je tient a signaler que ta solution fait apparaitre les caractères 1 à un a l'écran, ce qui suppose un balayage complet de l'ecran a chaque caractère, ce n'est pas très grave pour 10 ou 50 caractères, mais qu'en est-t-il si je veut réactualiser plusieurs lignes completes d'un coup, voir même tout écran ? ..
Réponse : Comme dans les vieux programmes, on voit l'ecran se modifier à l'oeil nu, ce qui n'est pas très estétique !
Remarque : On ne dit pas ?char *const? mais 'const char *', comme le montre les paramêtres de bien des fonctions de la lib string de C. Dans tous les cas une déclaration en "const <type> <variable>" signifie que la variable n'est pas modifié, ceci permet au compilateur de mieux simplifier votre code.
Maintenant, à mon tour de critiquer/comparer le C et le C++ (^_^)/
Désavantage numéro 1 des classes du C++ (exemple de la classe string) :
On ne sait pas ce que C++ fait avec notre chaîne, alors qu'en C on est sûr d'obtenir un code optimal. Si vous êtes doués, c donc plus long à coder mais moins long à l'execution (ou égal en temps dans le meilleur des cas)
Et c'est bien là que réside toute la difference entre ces 2 languages, le C est plus proche de la machine (du binaire), donc il permet de faire des codes plus propres, plus optimisé alors que le C++ est un language de plus haut niveau (plus loin de la machine) permettant du même coup de programmer plus facilement, mais où il faut donc encore plus avoir une confiance aveugle en le compilateur. En conclusion, le C est loin d'être une viellerie, ca serait aussi débile que de le dire a propos de l'assembleur, qui est le language incontournable de tout compilateur.
Cependant le C++ possède une qualité propre aux languages de haut niveau et absente du C : Les codes y sont très facilement portable. Ou si vous préférez, en pratique pour le codeur, il est plus facile d'importer une classe qu'une librairie désorganisée de fonctions (car il y a alors risque de conflit avec des fonctions déjà existantes, c'est pour ca que les fonctions des librairies du C s'appelent par des noms peu significatifs alors que le C++ prend les noms les plus évidents pour l'utilisateur). Il y a aussi d'autres explications sur l'importance de la portabilité tel que celles faisant intervenir la hierachie des objets, mais c plus compliqué, ca sera donc pour une prochaine fois.
Voilà j'espère que toutes mes explications, vous ont plu !
Ps: PapyLion, ca a rien à voir mais j'adore tes petits dessins ^_^
8 févr. 2003 à 18:06
Bon j'ai pas pu aller au delà de la 6ième page, vu les énormités qu'on trouve dès le début ca craint, j'ai pu eu le courage d'aller plus loin.
La ligne suivante :
char str[] = "abc";
Déclare un tableau de taille 4 (de taille connue donc !) qui est libérée proprement a la fin (ce qui contredit ce que tu a écrit).
La différence entre "char str[];" et "char *str;" est que la première version déclare un tableau et la seconde un pointeur, ce qui n'a rien a voir !! (Par exemple on peut changer l'adresse d'un pointeur mais pas d'un tableau, essaye un "str = 0;" dans les deux cas, tu va voir la différence)
Si a un moment dans ton programme tu trouve deux pointeurs qui pointent sur la même valeur alors que tu n'y est pour rien, cela n'est pas due au C mais c'est une simplification faite par ton compilateur ! Celui ci s'etait dit : "il con celui là il me demande 2 fois la meme chose sans en modifier la valeur, je vais en mettre qu'une ca sera plus simple".
A propos de :
char *str = "abc";
str[1]='o';
Un pointeur ne peut pas être affecté directement a une zone de mémoire dynamique, pour corriger l'erreur utilise "char str[]" (ou la fonction "malloc()" suivie d'un "strcpy()" si tu veut absolument pouvoir modifier le pointeur par la suite)
En résumé, papy, le C demande une rigueur de programmation que tu n'a pas, dommage, retourne au C++ au moins, lui, comprend tes erreurs. (double cassage, Cf. Brice de Nice ;) )
Voilà, j'espère que ca remettra un peu les apprentis qui sont tombés ici, sur le droit chemin. Hé surtout, bon courage à vous tous ^_^
3 févr. 2003 à 18:31
tout est alloué sur la pile. Voici l' exemple simplifié
on alloue une variable sVar (aux adresses 0x12FF24-0x12FF25)
on alloue une chaine str[4]="abc" (aux adresses 0x12FF20-0x12FF23)
on utilise strcat(str, "def") qui vient écraser sVar car elle écrit sur 0x12FF24-0x12FF28
CQFD
sur les adresses 0x12FF
3 févr. 2003 à 11:13
un premier mot: merci !
vraiment tres interessant!
j'ai cependant pas bien compris le désagrement ', avec ta variable SVar (partie I-4)... je comprends pas bien l'ecrasement.. mais je vais chercher un peu.