Cela correspond à la même valeur numérique : un entier qui vaut 0.
Lorsqu'on l'exprime sous la forme '\0' on le fait sous une forme suggérant qu'il s'agit du char terminateur de chaîne.
C'est un peu maladroit de mettre caractereActuel à 1, car il est faux de dire que ta chaîne comprend ce caractère.
En fait, dans ton code, tu n'as pas vraiment besoin d'une variable caractereActuel et tu peux directement mettre un test avec mot[nombreDeCaractere] dans ta condition while.
Edit :
renseigne toi aussi sur le type size_t, qui est plus approprié en C que le type int pour stocker la taille d'une chaîne. C'est, de fait, le type retourné par strlen() :
Il faut maintenant que tu apprennes à déboguer tout seul.
Ici, on va se demander si 'nombreDeCaractere' est correctement incrémenté. On peut par exemple l'afficher à l'intérieur de la boucle. Si je l'avais fait, je n'aurais obtenu aucun affichage, preuve qu'il ne va jamais dans la boucle.
Ensuite on se demande pourquoi il ne va pas dans la boucle. Pour aller dans la boucle, il y a une condition. On peut afficher la variable de la condition ('caractereActuel'). Là encore il n'affichera rien, ce qui devrait nous mettre la puce à l'oreille.
(Oui, on peut trouver l'erreur juste en regardant le listing, parce que c'est un petit exercice simple. Mais en général ce n'est pas un regardant un listing qu'on trouve les bugs, ce serait trop beau.)
La plus solide et standard utilise une variable de type size_t comme indice pour parcourir la chaîne. Et à la fin, on retourne l'indice. Et quand on débute, le type int au lieu de size_t est très bien.
Une solution bien différente consiste à utiliser un second pointeur pour parcourir la chaîne, et retourner la différence entre les pointeurs de fin et début de chaîne.
PS: Utiliser un do while causera probablement un bug.
- Edité par Marc Mongenet 12 octobre 2021 à 1:46:19
Le problème du « do while », c'est qu'on doit faire le test dans la boucle, c'est plus compliqué :
do
{
caractereActuel = mot[nombreDeCaractere];
if (caractereActuel != '\0') nombreDeCaractere++; // ou if (caractereActuel) tout court
} while(caractereActuel != '\0');
return nombreDeCaractere;
Je trouve que le plus simple est la solution de Zero.c (mais j'aurais mis « while (true) »). Je ne cache pas que j'aime bien les « while (true) » (avec un break ou un return dedans), je trouve que c'est très lisible.
@edgarjacobs: Ta solution ressemble à la mienne, je n'ai pas voulu faire l'incrémentation dans le while même si c'est plus "joli". Pas tout le monde qui comprendra pourquoi il faut soustraire 1 à la fin.
Le Tout est souvent plus grand que la somme de ses parties.
Il faudrait démontrer que la fonction strlen "astucieuse" constitue un gain de temps effectif sur un ensemble de chaînes représentatif de l'usage qui en est fait (distribution des tailles de chaînes ?)
Qui plus est, quand on en est à ce degré de recherche d'optimisation, fortement lié à une implémentation d'une architecture particulière, on écrit le truc en assembleur, pour aller chercher directement les instructions spécifiques qui vont bien, plutôt que d'espérer que le compilateur (particulier lui aussi) va deviner ce qu'on traficote et pas se prendre les pieds dans le tapis en optimisant.
(Ici: traiter les octets par paquets alignés de 4 ou de 8, avec une bidouille pour voir si un paquet contient un octet nul ou pas)
Dans la vraie vie, il vaut mieux s'abstenir de faire ce genre de code ::-)
- Edité par michelbillaud 13 octobre 2021 à 17:38:14
Le code du projet GNU pour la glibc parait inspiré du travail de Henry S. Warren dans son livre Hacker's Delight. Il est crédité dans la version FreeBSD de cette implémentation : https://cgit.freebsd.org/src/tree/lib/libc/string/strlen.c
@michelbillaud: Dans cette version d'Apple (qui base son code sur FreeBSD) il y a un commentaire sur les mesures de performances qui serait x5 sur le matériel indiqué (un Intel T7300 qui a été produit en 2007) : https://github.com/apple/darwin-libplatform/blob/main/src/string/generic/strlen.c par rapport à une version triviale dès lors que la chaîne a une taille supérieure à un word.
C'est un type d'optimisation utilisé par d'autres systèmes d'exploitation.
Ce qui est présenté dans le strlen.c posté précédemment par Gam' n'est pas ce qui tourne sur nos machines Linux habituelles, sauf architectures exotiques. Par exemple pour x86_64 c'est une version en assembleur : https://github.com/lattera/glibc/blob/master/sysdeps/x86_64/strlen.S
Ils n'utilisent le code en .c que s'il n'existe pas une version assembleur pour une architecture donnée.
@robun : je suis assez d'accord avec Michel, ce n'est pas exactement le type d'efforts que l'on fait "dans la vrai vie" par rapport à un code résultant d'un exercice. Il faut aussi comprendre que tous ces efforts pour optimiser une fonction qui est, a priori, simple, se justifient pour deux raisons :
parce qu'on est dans le contexte d'une fonction comme strlen() dont l'algorithme trivial est de complexité O(n) car le C ne connaît pas de réel type string (avec un vrai type string, la longueur de la chaîne pourrait être stockée)
mais surtout parce qu'on est dans le contexte de la libc et qu'on réalise, par définition, une implémentation de la libc pour une machine donnée, et que ce n'est pas grave si on aboutit à du code non portable
En dehors de contextes particuliers, on devrait laisser le compilateur optimiser les choses.
J'osais espérer que ce n'était que pour des raisons pédagogiques ou expérimentales. La fonction strlen() fournie par la bibliothèque standard de C est préférable et bien optimisée.
Le Tout est souvent plus grand que la somme de ses parties.
la fonction "strlen"
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Le Tout est souvent plus grand que la somme de ses parties.
On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent
Le Tout est souvent plus grand que la somme de ses parties.
Le Tout est souvent plus grand que la somme de ses parties.