Ah je n'étais pas loin
En effet la fonction compte le nombre de mots dans la chaine qu'on lui envoie, ce qui revient à compter le nombre d'espace + 1:
int compte_mots(const char *c)
{
int i=0;
while(*c != 0) /* boucle tant que c n'est pas à la fin de la chaine */
{
for(; isspace(*c); c++) /* Boucle qui dit commence par rien faire (il n'y a rien avant le premier point virgule), */
{ /* puis tant que c ne pointe pas sur un espace dans la chaine,(isspace renvoie 0 s'il *c n'est pas un espace),
on déplace c d'un caractère sur la droite (c++).
*/
; /* Et dans la boucle on ne fait rien, le point-virgule seul, indique "FAIRE : aucune action". (comme dans le for)*/
}
if(*c == 0) /* Si *c est à la fin de la chaine, on quitte le while, */
break; /* grace au break. */
i++; /* Sinon, i s'incrémente de 1. */
for(; !(*c == 0 || isspace(*c)); c++) /* Et puis on refait un boucle qui commence par "ne rien faire", comme la précédente, */
{ /* et qui tant que *c n'est pas à la fin de la chaine (0), ou n'est pas un espace (isspace),
/* alors c se déplace d'un caractère sur la droite. */
; /* Et encore une action vide. */
}
}
return i; /* Enfin on retourne i qui vaut le nombre de mots dans la chaine. (nombre d'espaces + 1) */
}
Ce qu'il faut bien comprendre c'est qu'au départ, le paramètre "c" de compte_mots est un pointeur char, il contient l'adresse de la première lettre d'une chaine (celle passée en argument).
Ensuite, les boucles servent à décaler de 1 l'adresse sur laquelle pointe "c", jusqu'à la fin de la chaine.
Exemple:
Si on fait compte_mots("AB C DEF");
La chaine passée est "AB C DEF\0" le '\0' est rajouté automatiquement de façon à pouvoir trouver la fin de la chaine.
La fin de chaine vaut 0, son code hexadécimal est 0, donc la chaine passée est en réalité (en héxa) : 0x41 0x42 0x20 0x43 0x20 0x44 0x45 0x46 0x00.
Il y a un caractère supplémentaire, que l'on ne voit pas lors de l'affichage.
Au début de la fonction, c pointe sur le premier élément de la chaine, donc A (0x41).
puis on le déplace de 1 sur la droite jusqu'à ce que isspace() soit vrai.
Autrement dit c commence sur A (0x41), puis B(0x42), puis "ESPACE"(0x20). Or à cet instant, isspace renvoit quelque chose différent de 0 car il tombe sur un espace, et on sort donc de la première boucle.
On incrémente i de 1 (donc i 1), puis on regarde si "c" est à la fin de la chaine: if (*c 0) revient à if (*c == 0x00).
Ensuite, on passe au 2ème for, ç'est la même boucle que la précédente, à la différence près que cette fois-ci, si "c" est à la fin de la chaine, on sort également du for.
Donc c va passer de "ESPACE" (0x00) à C(0x43), puis de C à "ESPACE"(0x20), ce qui va provoquer la fin de la boucle, augmenter i de 1(donc i vaut maintenant 2) et ramener au début du while,
On en arrive au premier for une seconde fois, qui va déplacer c de "ESPACE" à D (0x44), puis de D à E (0x45), puis de E à F (0x46), et enfin de F à "fin de chaine"(0x00), c qui stoppe le for et le while.
Et sinon, le if (*c == 0) ne sert strictement à rien, comme au moment où il est appelé, *c vaut forcément un espace, il ne peut pas valloir fin de chaine.
On peut carrément supprimer avec le break, réessaye sans et tu verras qu'il n'y a aucune différence.
Autre chose, isspace ne se contente pas d'être vrai quand il croise un espace: 0x20, il renvoie également vrai s'il tombe sur une tabulation(0x09), un saut de ligne(0x0A), une tabulation verticale (0x0B), un feed (0x0C), et un retour chariot (0x0D).
Voilà, j'espère que c'est un peu plus clair pour toi.
C++dialement,
Pop70