queqlues questions de bases en C

queqlues questions de bases en C - C - Programmation

Marsh Posté le 25-03-2004 à 22:16:43    

bonjour a tous,
 
je débute en C, et, pour un projet, j'ai besoin de copier le contenu d'un char * dans un buffer. Seulement je ne sais pas trop manipuler les chaines de caracteres...
 
pour commencer, comment ce fait-il que le code suivant marche :  
 

Code :
  1. #include <stdio.h>
  2. main () {
  3. char *coucou;
  4. //coucou = (char *) malloc(5);
  5. coucou = "salut";
  6. printf("%s\n",coucou);
  7. }


 
normalement, aucune place n'est allouée en mémoire pour coucou...
voila le résultat :

Code :
  1. 23:17 root@server-jerem ~travail/AS_jerem# ./test
  2. salut
  3. zsh: exit 6     ./test
  4. 23:17 root@server-jerem ~travail/AS_jerem#


 
Ca veut dire quoi ce exit 6 ?
 
merci d'avance

Reply

Marsh Posté le 25-03-2004 à 22:16:43   

Reply

Marsh Posté le 25-03-2004 à 22:50:09    

ca marche car tu fait pointer coucou vers la chaine constante "salut"; c'est correct. le code de retour est aléatoire car tu ne retourne pas de valeur (en l'occurrence c'est sans doute le code de retour de printf qui a écrit 6 caractères...).
 
Donc évite le int implicite en écirvant 'int main(void)' et fait un return 0; à la fin...

Reply

Marsh Posté le 25-03-2004 à 23:35:50    


const char *coucou="salut";  
ou
char coucou[]="salut";

Reply

Marsh Posté le 26-03-2004 à 00:06:55    

Citation :

RETURN VALUES
     The printf(), fprintf(), and sprintf() functions return  the
     number  of bytes transmitted (excluding the terminating null
     byte in the case of sprintf()).


 
printf retourne 6 car la chaine imprimée est "salut\n", et apparement cette valeur etant la derniere evaluée est retournée par la fonction.  
 
Neanmoins:
 
Si tu fais du C, ecris du C:

Code :
  1. #include <stdio.h>
  2. int main () {
  3. char *coucou = "salut"; 
  4. printf("%s\n",coucou);
  5. return 0;
  6. }

 
 
Parce que ta ligne  
coucou = "salut";  
est incorrecte en C, et la non-declaration du type de main est peut etre correcte, mais en C hyper-archaique.
(EDIT: Grilled car j'ai pas pu poster, ma connection s'etant evaporée :/)
A+,


Message édité par gilou le 26-03-2004 à 02:12:48
Reply

Marsh Posté le 26-03-2004 à 09:00:58    

Merci de vos réponses  :)  
 

gilou a écrit :


Parce que ta ligne  
coucou = "salut";  
est incorrecte en C


 
pourquoi ?  
il faut que je fasse le malloc juste avant, pour qu'elle soit valide ?


Message édité par jerem38 le 26-03-2004 à 09:01:29
Reply

Marsh Posté le 26-03-2004 à 10:19:21    

Parce que tu as le droit de faire ca uniquement a la declaration de ta variable, pour des questions d'allocation en effet.
Sinon, ailleurs, tu passes par un malloc, un strdup, etc etc, bref, par qulque chose qui controle l'allocation de ta variable.
Sinon, on pourrait tomber dans du code comme:
coucou = "salut";
coucou[0]='t';
qui est sujet a caution, puisque "salut" est une chaine constante... (Visual C++ 6 est particulierement buggé sur ce point)
Le seul endroit ou ce code est authorise, c'est a la declaration de ta variable, car le C specifie alors que une allocation et une copie est effectuée.
A+,


Message édité par gilou le 26-03-2004 à 10:25:56
Reply

Marsh Posté le 26-03-2004 à 10:56:55    

euh non, l'affectation est légale, je ne vois pas le problème... par contre une tentative de modification est illégale (mais il n'y avait pas de modification dans le post original).
 
"Salut" est une littérale chaînes (constante) et possède une addresse. L'affectation coucou = "Salut" affecte cette adresse à la variable coucou, qui est un pointeur sur char, donc c'est ok.
 
Contrairement au C++, les littérales chaînes sont de type char * et pas const char * (elles n'en restent pas moins non modifiables); il est donc peut-être préférable d'utiliser un pointeur const char * dans cette situation, afin d'éviter de tenter par mégarde une modification.

Code :
  1. char *coucou;
  2. coucou = "Salut";


est totalement équivalent à

Code :
  1. char *coucou = "Salut";


Dans les deux situations le pointeur coucou pointera sur une littérale chaîne non modifiable. Par contre

Code :
  1. char coucou[] = "Salut";


est très différent car il alloue un tableau de 6 caractères et y stocke les caractères 'S', 'a', 'l', 'u', 't', '\0'. Ce tableau est lui évidemment modifiable. L'expression 'coucou' est alors un pointeur sur le premier élément du tableau.
 
Dernière remarque par rapport au premier post, les commentaires // ne sont pas autorisés avant le C99 et le retour de malloc ne se caste pas. Si tu voulais allouer dynamiquement l'espace (ce qui est peu utile ici) tu fais :

Code :
  1. #include <stdlib.h>
  2. #include <string.h>
  3. ...
  4. char *coucou;
  5. coucou = malloc(6);
  6. strcpy(coucou, "Salut" );


Tu obtiens alors un pointeur sur un tableau modifiable de 6 caractères.


Message édité par djdie le 26-03-2004 à 11:01:16
Reply

Marsh Posté le 26-03-2004 à 13:01:53    

Ne pas oublier de virer la mémoire allouée par malloc avant la sortie du programme ;) (free)

Reply

Marsh Posté le 26-03-2004 à 14:37:37    

> euh non, l'affectation est légale, je ne vois pas le problème
 
Euh oui, c'est juste. Désolé, mais avec la perte de mon HDD, j'ai aussi subi la perte de mon Kernighan & Richie en ligne, et je n'ai pu verifier avant de poste C'était de memoirer.
 
Néanmoins, c'est dangereux pour les raisons mentionnées (et le fait que Visual C 6 modifie allegrement les literaux constants sans sourciller, et qu'il etait pas le seul autrefois).  
 
De toute facon, mieux vaut faire ca en C++ ou la notion de pointeur sur une chaine constante s'exprime de maniere naturelle.
A+,

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed