[C] ersatz de la fonction strlen

Fermé
KBS - 26 oct. 2009 à 21:20
mamiemando Messages postés 33344 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 7 novembre 2024 - 27 oct. 2009 à 13:55
Bonjour,

j'ai trouvé ce code sur un site mais je ne suis pas sur de tout comprendre


size_t strlen( const char * str){
for(;*(str2);str2++)
taille++;
return str2 - str;
}

si je crée un 'const char * str' mais que je ne l'initialise pas, la fonction me retourne 0, est ce par chance (etant donné l'etat de la memoire) ou est ce correcte ?
si c'est correct pourriez m'expliquer ce que signifie la conclusion

4 réponses

Pacorabanix
26 oct. 2009 à 22:30
c'est par chance, et tu ne dois pas compter dessus. (note : ça ne dépend pas que de l'état de la mémoire mais aussi du compilateur). NE JAMAIS UTILISER de pointeur non-initialisé ;)

Le code est pas mal condensé.

L'incrémentation du pointeur retourne false si la chaîne arrive au bout (car toute chaine se termine en C par le caractère "NUL", c-à-d 0, qui est false.).

La dernière valeur est *l'adresse mémoire de la fin de la chaine* on enlève *l'adresse mémoire du début de la chaine* (=la variable de la chaine, le const char * !) et ça donne la longueur de la chaine car tous les caractères d'un tableau en c++ ont mis à la suite dans la mémoire.

Voilà je crois que ça répond à ta question, bonne soirée
0
merci pour ta reponse

mais j'ai encore quelque petite questions:

- est-il possible de faire un test qui renverrais, si la chaine a bien été initialisée?

- en ce qui concerne le caractere de fin de la chaine, doit on l'ecrire a l'initialisation ? que ce passe-t-il, si du coup il n y a pas de caractere de fin?
0
1) mmm... a priori non en C. Un pointeur, prend l'ahabitude de la mettre à NULL dès que tu le crées. Comme ça c'est clair et propre.

2)en fait, lorsque tu écris const char* truc = "Salut" (je ne suis plus sûr parfaitement de ma syntaxe), le C crée un tableau de char (et un tableau est représenté par un pointeur constant vers son premier élément) et le rempli comme suit : truc[0] = 'S' truc[1]='a' ... truc[4]='t' truc[5]=0.

C'est la représentation interne, tous les compilateurs font comme ça, c'est bien dans le standard C ;)

Je crois que ça répond à ta question, sinon fais-le moi savoir!
0
mamiemando Messages postés 33344 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 7 novembre 2024 7 803
27 oct. 2009 à 13:55
En fait la fonction que tu récupères est juste malgré ce qui a été dit plus haut. Elle est d'ailleurs implémentée à peu de chose près comme ça dans la libc sous linux (ils utilisent une boucle while encore plus synthétisée au lieu du for).

Petite explications :

- si ton pointeur est initilalisé à NULL ou non initialisé, la boucle plantera et fera une erreur de segmentation. En soi ce n'est pas déconnant car quand on parcourt la chaîne, on incrémente un compteur jusqu'à tomber sur un '\0' qui va interrompre la boucle for. Si le pointeur passé est NULL ou n'est pas inialisé, l'évaluation du char contenu à l'adresse str2 provoquera une erreur.

- si ton pointeur contient l'adresse d'une chaîne, la boucle avance jusqu'à rencontrer un '\0'. Ceci présuppose que la chaîne finit évidemment bien par un \0, ce qui est le cas quand tu écris :

const char *s = "plop";


En réalité cette écriture signifie tu alloues un bloc de 5 chars initialisés respectivement à 'p', 'l', 'o', 'p', '\0'.

En pratique il faut effectivement utiliser l'opérateur * ou -> seulement sur des pointeurs initialisés. C'est une perte de temps et (minime certes) de performance que d'initialiser un pointeur à NULL si c'est pour l'initialiser juste derrière avec une autre valeur.

Par rapport à ton autre question, il n'y a bien sûr aucun moyen de vérifier que l'utilisateur va bien passer une chaine avec un \0 au bout. S'il se trompe tant pis pour lui. Quand on y regarde de près, quand tu passes n'importe quoi à des fonctions comme strlen, étonnamment... elles plantent.

Bonne chance
0