Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1571 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Subtilités entre [] et *

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

Subtilités entre [] et *

n°690133
Profil sup​primé
Posté le 01-04-2004 à 19:43:18  answer
 

Salut
 
Bien que programmeur confirmé (s'il en est) en C++, j'ai un peu de mal a vraiment saisir la subtilité entre char[] et char*, et en particulier ce qu'impliquent des cast entre ces deux types.
 
A ma connaissance, ayant un char[], on peut retrouver sa taille avec un truc template compliqué (qui a été décrit sur ce forum je crois), mais avec un char* on peut pas. Donc du point de vue de compilo il doit y avoir une différence importante.  
 
En gros quand doit on utiliser lequel ?
QQun a des infos claires la dessus ?
Merci

mood
Publicité
Posté le 01-04-2004 à 19:43:18  profilanswer
 

n°690141
Ace17
Posté le 01-04-2004 à 20:07:37  profilanswer
 

Code :
  1. char name1[20]; // tu alloues 20 cases mémoires de la taille d'un char chacune. name1 est juste un pointeur constant vers ce tableau.
  2. char* name2; // tu alloues une case mémoire, de la taille d'un pointeur, qui pointe vers.... rien du tout.
  3. char* name3 = "John Doe";
  4. /* Pas autorisé en C++ ( merci Taz! ). Tu alloues une case mémoire, de la taille d'un pointeur, qui pointe vers.... la chaine "John Doe", située dans une mémoire a l'acces en écriture indéterminé. En d'autres termes, tu n'es pas censé modifier ce qui se trouve a l'addresse pointée par name3. Par contre tu peux tout a fait faire pointer name3 vers autre chose, mais c'est pas recommandé, il vaut mieux faire et ainsi utiliser des pointeurs constants: */
  5. const char* name4 = "John Doe" :


 
Apres, il se trouve que du point de vue du compilo, tous les name sont des pointeurs vers char. Exemples :
 

Code :
  1. name3 = name1; // tu changes la valeur du pointeur name3, il pointe maintenant sur ce qu'il y a dans le tableau de 20 cases.
  2. name3[2] = 'c'; // INTERDIT. Le compilo te laissera faire, car c'est sémantiquement correct, mais ca va t'amener a des erreurs.
  3. name1[2] = 'c'; // Tout a fait légal. Tu as un tableau de 20 cases, tu mets ce que tu veux dedans.
  4. name1 = name3; // ne passera pas la compilation. name1 n'est rien d'autre qu'un pointeur constant. Donc pas question de le faire pointer vers autre chose que notre tableau de 20 cases.


 
edit1 : c'est pas une question de programmeur "confirmé" ca.  :D
edit2 : cette différence n'a rien d'une subtilité!!!


Message édité par Ace17 le 01-04-2004 à 21:07:38
n°690144
Ace17
Posté le 01-04-2004 à 20:20:09  profilanswer
 

Leur emploi :  
Le char* sert souvent pour le passage de parametres. Si tu veux une fonction qui compte le nombre de caracteres d'un tableau de char, tu es obligé d'utiliser des char*. Exemple :

Code :
  1. int string_length(char* s)
  2. {
  3. if(s == NULL)
  4.    return -1;
  5. if(s[0]==0)
  6.    return 0;
  7. else
  8.    return 1+string_length(&s[1]);
  9. }
  10. int main()
  11. {
  12.    char name1[20];
  13.    char* name2 = "john doe";
  14.    cin >> name1;
  15.    string_length(name1);
  16.    string_length(name2);
  17.    string_length("hello world" );
  18.    return 0;
  19. }


Et gare a celui qui me fera un commentaire sur l'intéret ou la fiabilité de ma fonction
 
Le char [n] c'est plutot pour stocker des chaines de caracteres que tu ne connais pas a la compilation.


Message édité par Ace17 le 01-04-2004 à 20:23:47
n°690160
Taz
bisounours-codeur
Posté le 01-04-2004 à 20:52:01  profilanswer
 

char* name3 = "John Doe";  provoque une erreur de compilation en C++

n°690166
Ace17
Posté le 01-04-2004 à 21:06:22  profilanswer
 

Ah? Au temps pour moi alors. Je corrige.

n°690167
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:07:17  profilanswer
 

donc ça aussi ça foire int string_length(char* s)

n°690169
Ace17
Posté le 01-04-2004 à 21:09:09  profilanswer
 

Taz a écrit :

donc ça aussi ça foire int string_length(char* s)  


Pourquoi?
Tu veux dire, quand j'appelle la fonction ou quand je la définis..
edit : Au fait Taz j'en profite pour te dire que t'as un peu tendance a exhiber les erreurs des autres sans les corriger. C'est dommage, avec la connaissance que t'as, de n'en faire profiter les autres qu'avec une telle parcimonie  :hello:


Message édité par Ace17 le 01-04-2004 à 21:20:20
n°690177
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:19:50  profilanswer
 

le prototyp est chiatique :o

n°690179
Ace17
Posté le 01-04-2004 à 21:20:42  profilanswer
 

Taz a écrit :

le prototyp est chiatique :o


bon, ben voila, ca confirme ce que je dis.

n°690182
Ace17
Posté le 01-04-2004 à 21:24:22  profilanswer
 

Bon, Taz, je viens de tester avec g++ le code source que j'ai donné, il n'y a ni erreur ni warning. Alors franchement je vois pas ou tu vois un probleme.


Message édité par Ace17 le 01-04-2004 à 21:25:43
mood
Publicité
Posté le 01-04-2004 à 21:24:22  profilanswer
 

n°690184
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:29:35  profilanswer
 

Ace17 a écrit :

Bon, Taz, je viens de tester avec g++ le code source que j'ai donné, il n'y a ni erreur ni warning. Alors franchement je vois pas ou tu vois un probleme.

parce qu'un compilateur n'est pas le C++ :o:o:o:o
 
compile donc en g++ -W -Wall -std=c++98 -pedantic
 
 
ton code est pourri

n°690185
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:32:16  profilanswer
 

et faites une recherche, j'ai déjà gueulé sur la différence des centaines de fois
 
 
et pas un couillon pour me dire que tab n'est pas une l-value

n°690189
Ace17
Posté le 01-04-2004 à 21:40:48  profilanswer
 

je SAIS ce qu'est une l-value. Seulement il se trouve que ce terme ne va pas tellement servir a Oualb car manifestement il n'a probablement jamais été confronté au probleme, sinon il aurait découvert par lui meme la différence * / [].
 
Qu'est-ce tu as contre moi? J'ai répondu a ta place, c'est ca que tu supportes pas?
 
Tout ce que tu sais dire, c'est des reproches. Mon code est pourri? Parce qu'il manque les const? C'est ca qui suffit a rendre un code pourri?  
 
Sérieux Taz, on est pas la pour s'engueuler, un peu de courtoisie quoi! J'ai pas été agressif, alors pourquoi réagir ainsi?


Message édité par Ace17 le 01-04-2004 à 21:41:37
n°690192
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:42:57  profilanswer
 

Ace17 a écrit :

Tout ce que tu sais dire, c'est des reproches. Mon code est pourri? Parce qu'il manque les const? C'est ca qui suffit a rendre un code pourri?

oui et je reste poli. l'absence de const est une faute grave
 
c'est pas ma faut si on vous apprends pas ce que c'est que le tableau

n°690195
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:45:57  profilanswer
 

Citation :

un tableau t est :
- une collection de taille statique N d'éléments de même type T
- ces éléments sont contigus en mémoire. Les adresses des éléments sont ordonnées dans l'ordre croissant.
- sizeof t == sizeof(T) * N
- chaque élément de t est accessible directement (en temps constant) par l'opérateur []. les éléments sont indicés sur [0; N[
- un tableau n'est pas un pointeur. la conversion est assurée de telle manière que t -> &t[0]
- ce n'est pas une l-value
- chaque couple (T, N) construit un nouveau type de tableau.


 
http://forum.hardware.fr/hardwaref [...] -43703.htm

n°690196
Ace17
Posté le 01-04-2004 à 21:46:05  profilanswer
 

Bon, je viens de compiler comme tu l'as dit :
g++ -W -Wall -std=c++98 -pedantic test.cpp
Ca ne change rien. Mingw n'est pas aux normes?

n°690197
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:47:06  profilanswer
 

non

n°690200
Ace17
Posté le 01-04-2004 à 21:48:42  profilanswer
 

Peux tu m'indiquer un compilo qui le soit?

n°690201
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:52:41  profilanswer
 

Comeau qui suit toutes les dernières modifications.
 
le problème c'est qu'en C++ les chaine littérales sont const char[n] mais pour le moment la conversion implicite passe par char *, puis const char*, donc ça sert pas à grand chose. la future révision du C++ rendra la conversion conforme à la const-ness des chaines littérales

n°690203
Ace17
Posté le 01-04-2004 à 21:56:39  profilanswer
 

Code :
  1. int string_length(char* s)
  2.   {
  3.     if(s == NULL)
  4.          return -1;
  5.     if((*s)==0)
  6.          return 0;
  7.     else
  8.          return 1+string_length(++s);
  9.   }


 
C'est mieux ca?


Message édité par Ace17 le 01-04-2004 à 21:57:02
n°690207
Taz
bisounours-codeur
Posté le 01-04-2004 à 21:58:13  profilanswer
 

t'es con ?

n°690213
Ace17
Posté le 01-04-2004 à 22:00:23  profilanswer
 

Taz a écrit :

t'es con ?


 
Je l'attendais celle la. Je sais bien qu'il manque le const dans la premiere ligne.
 
Et je sais aussi qu'il faudra modifier mon ++s en conséquence.
 
Mais je me tire de la discussion, t'es vraiment trop agressif.


Message édité par Ace17 le 01-04-2004 à 22:00:52
n°690214
Taz
bisounours-codeur
Posté le 01-04-2004 à 22:03:58  profilanswer
 

moi aussi, t'as vraiment rien compris

n°690223
xterminhat​e
Si vis pacem, para bellum.
Posté le 01-04-2004 à 22:25:50  profilanswer
 

La méthode Taz est particulièrement efficace, suffit de pas se braquer pour vraiment en profiter :)
 
Ca prend du temps de manger sans mettre les coudes sur la table et en se tenant droit. J'ai encore bcp de mal pour ma part.
 
Courage Ace17, dis toi que c'est pour ton bien...
 
Juste pour le fun (et me faire humilier des fois que ce soit pourri encore  :pt1cable: ).
 

Code :
  1. const int string_length( const char * const s )
  2. {
  3. if( s == NULL )
  4.   return -1;
  5. else
  6. {
  7.   int compteur = 0;
  8.   while( *(s+compteur) != 0 ) compteur++;
  9.   return compteur;
  10. }
  11. };


Cordialement,
   xter.


Message édité par xterminhate le 01-04-2004 à 22:26:44
n°690363
Slayne
Yaouchhh
Posté le 02-04-2004 à 00:10:06  profilanswer
 

Au fait, rien à voir, mais il est vrai qu'en C++, contrairement au C, la norme veut que l'on utilise 0 et non NULL ?  
 
Je trouve ça bizarre, est ce vrai ? (un lien serait bienvenue :D)

n°690367
Taz
bisounours-codeur
Posté le 02-04-2004 à 00:13:25  profilanswer
 

oui. ça n'est pas bizarre. le c++ fait juste que 0 est une valeur spéciale affactable à un pointeru sans cast (un peut comme un mot clef, d'ailleurs, certains en parle)
 
le C ne permets pas ça
NULL ((void*)0)
 
certains pensent que NULL cai mieux, on sait qu'on manipule des pointeurs. mais le compilateur le sait il ? non. alros j'aime bien le 0;

n°690369
Taz
bisounours-codeur
Posté le 02-04-2004 à 00:17:34  profilanswer
 

là t'as abuser
 

Code :
  1. //voilà comment est souvent écrit strlen
  2. size_t strlen(const char *str)
  3. {
  4.   size_t len = 0;
  5.   while( *str++ ) { ++len; }
  6.   return len;
  7. }


 
faut y aller molo sur les const
 
le const de retour ne rime à rien
le const sur le pointeur, comprends bien qu'ici, c'est un garde fou que tu te mets pour t'empecher de modifier sa valeur.

n°690423
matafan
Posté le 02-04-2004 à 05:42:42  profilanswer
 

Puis typiquement, un tableau sera sur la stack alors qu'un pointeur pointera dans le heap.

n°690424
Taz
bisounours-codeur
Posté le 02-04-2004 à 05:46:11  profilanswer
 

alors là, le typiquement ... moi je te mets des tableaux dans le tas et je te fais pointer tout ce que tu veux sur la pile... sans parler des tableaux statiques (ben oui la taille est fixe, ça reflète souvent un usage statique)
 
merci pour la version anglaise, le français est tellement plus long à écrire

n°690430
matafan
Posté le 02-04-2004 à 06:13:59  profilanswer
 

Monsieur Taz : j'avais commencé à écrire pile puis en arrivant à « tas » je me suis dit que ce n'était pas assez usité. Donc j'ai tout passé en anglais. Je trouve assez déplacé de critiquer l'emploi de termes anglais consacrés par l'usage, sur un forum technique, dans un domaine où la litérature est en majorité anglaise. Par ailleurs je suis plus géné par les « t'es con » et autres politesses dont tu nous gratifies régulièrement que par les anglicismes.
 
Ensuite par typiquement j'entendais variables locales dans une fonction, ce qui me semble effectivement être un emploi « typique ». Et je disais justement ça pour souligner la le contraste statique/dynamique et la différence de nature entre les deux notions.

n°690432
Taz
bisounours-codeur
Posté le 02-04-2004 à 06:24:32  profilanswer
 

forum technique : si le terme existe en français, a suffisemment de sens et est tout aussi compréhensible, je ne vois aucune raison de s'en passer.
 
pile/tas n'ont rien à voir avec allocation statique/dynamique.

n°690443
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-04-2004 à 07:51:17  profilanswer
 

Avec mon bout de code, j'etais qd même pas si loin de la vérité :)
 
Xter.


Message édité par xterminhate le 02-04-2004 à 08:22:04
n°690445
Taz
bisounours-codeur
Posté le 02-04-2004 à 08:08:05  profilanswer
 

avoue que la version que j'ai donnée est bien sympa quand même ?

n°690449
xterminhat​e
Si vis pacem, para bellum.
Posté le 02-04-2004 à 08:21:43  profilanswer
 

En effet, j'avoue : ta version est plus séduisante.
 
En plus, je viens de comprendre qqchose de fondamental sur la gestion des pointeurs que je n'oserai repeter par peur du ridicule ! ;)
 
Cordialement,  
   xter.

n°690520
lecoyote
Posté le 02-04-2004 à 09:54:45  profilanswer
 

toujours aussi agressif Taz

n°690745
docmaboul
Posté le 02-04-2004 à 13:04:46  profilanswer
 

Taz a écrit :

avoue que la version que j'ai donnée est bien sympa quand même ?


 
Faut avouer qu'elle est à chier, oui. Dans un strlen correct, on ne s'amuse pas à incrémenter deux variables lors du parcours de la chaîne mais une seule et du coup, son code en C ressemble à quelque chose comme ça:
 

Code :
  1. type_prout_entier mon_strlen(const char * prout_prout)
  2. {
  3.   register char * prout=(char*)prout_prout;
  4.   while ( *prout++) {}
  5.   return (type_prout_entier)(prout-prout_prout-1);
  6. }

n°690818
Taz
bisounours-codeur
Posté le 02-04-2004 à 14:07:08  profilanswer
 

mais on en a rien à faire, personne cherche à faire un strlen ici :o on illustre juste
d'ailleurs, aucun intéret ton cast à la con ... et puis je connais pas de strlen qui ne soit pas écrit directement en assembleur ... alors je sais pas ce que tu viens chercher... t'as gagné t'es content ...

n°691209
docmaboul
Posté le 02-04-2004 à 18:43:18  profilanswer
 

Taz a écrit :

mais on en a rien à faire, personne cherche à faire un strlen ici :o


 
Encore heureux...
 

Citation :

on illustre juste


 
Comment faire ça avec les pieds? C'est réussi...
 

Citation :

d'ailleurs, aucun intéret ton cast à la con ...


 
Si mais tu es trop jeune pour le comprendre, petit scarabée.
 

Citation :

et puis je connais pas de strlen qui ne soit pas écrit directement en assembleur ...


 
Même remarque.
 

Citation :

alors je sais pas ce que tu viens chercher...


 
Moi non plus. On se fait un strlen en assembleur avec 36 variables incrémentales dont on pourrait se passer?
 

Citation :

t'as gagné t'es content ...


 
Oui, je suis content :D mais c'est un peu facile avec toi.

n°691231
Joel F
Real men use unique_ptr
Posté le 02-04-2004 à 18:52:42  profilanswer
 


 
T'as pas l'impression de brasser du vent et de te faire mousser ? :o

n°691241
docmaboul
Posté le 02-04-2004 à 19:01:50  profilanswer
 

joel f a écrit :


T'as pas l'impression de brasser du vent


 
Vanité des vanités, tout n'est que vanité et poursuite du vent, disait Qoheleth.
 

Citation :

et de te faire mousser ?


 
Ca non et d'autant plus que j'ai une femme pour le faire à ma place :D

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Subtilités entre [] et *

 

Sujets relatifs
[C+++] les subtilités. pièges 
Plus de sujets relatifs à : Subtilités entre [] et *


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR