optimisation de ma fonction strlen
Bonjour à tous,
Je débute en C et j'ai bien du mal avec les pointeurs.
J'ai créé une fonction qui trouve la longueur d'une chaine. Mon problème est que je passe à ma fonction un pointeur longueur initialisé dans la fonction main.
Pourtant, la longueur de la chaine est indépendante de ce pointeur. Suis-je obligé de passer ce pointeur ?
Ma fonction est elle optimisée ? J'ai en effet vu d'autre programmes beaucoup plus longs et plus complexes.
Merci pour vos réponses
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
#include <stdio.h>
#include <stdlib.h>
int longueurChaine(char*chaine,int*ptLongueur);
int main()
{
char chaine[1000]={0};
int longueur=0;
int *ptLongueur=NULL;
ptLongueur=&longueur;
printf("Ce programme permet de calculer la longueur d'une chaine de caracteres\n\n");
printf("Entrez une chaine de caracteres : ");
gets(chaine);
rewind(stdin);
longueurChaine(chaine,ptLongueur);
printf("\n\nLa longueur de la chaine \"%s\" est de %d caracteres\n\n",chaine,*ptLongueur);
return 0;
}
int longueurChaine(char*chaine,int*ptLongueur)
{
int i=0;
while (chaine[i]!='\0')
{
i++;
}
*ptLongueur=i;
return *ptLongueur;
} |
Chaîne nulle en paramètre de la fonction
Citation:
Envoyé par
gangsoleil
C'est drole, dans la plupart des codes presentes ici (je ne les ai pas tous lus attentivement), il y a le meme bug que dans (la plupart des implementations de) strlen : un magnifique plantage sur une chaine NULL.
Alors oui, je sais, on peut concevoir que demander la longueur de NULL est une connerie, mais de la a ce que la fonction plante le programme, il y a un monde.
Un simple test :
Code:
1 2
| if (chaine == NULL)
return -1; |
ou equivalent permet de se premunir de l'erreur.
Je ne suis pas tout à fait d'accord. Déjà, je ne pense pas qu'on puisse parler de bogue, puisque la fonction strlen de la bibliothèque standard de C est généralement optimisée à la main afin de passer correctement sur toutes les implémentations, et notamment dans le cas où les contraintes de performances seraient élevées (et, sur certaines architectures, un branchement conditionnel peut se révéler conséquent...). De plus, ce code n'obéit pas aux contraintes qui aboutissent à l'élaboration d'un seul point de sortie, et il agrandit le domaine de définition de la fonction, ce qui peut se révéler problématique pour l'appelant (beaucoup de codes différents à traiter au cas par cas). C'est un thème subjectif, mais je reste persuadé que, pour une fonction de la bibliothèque standard de C (qui se doit d'être une bibliothèque « générique »), il serait préjudiciable de privilégier la sécurité aux dépens des performances, alors que l'appelant peut très bien faire la vérification à sa place (et d'ailleurs, peut-être l'a-t-il déjà fait, ce qui, dans ce cas, ferait une vérification redondante). Après, on peut toujours faire cette vérification sur une implémentation maison (et notamment lorsqu'on fait un semblant d'orienté objet) parce que l'utilisateur n'a pas les clés en main pour faire les tests nécessaires. Mais ça ne me semble pas être le cas ici. Pour moi, ce « bogue » est par conséquent à nuancer (même si, pour « débuter », c'est peut-être mieux). Enfin, pour être à cheval sur le vocabulaire : strlen calcule la longueur d'une chaîne, or, NULL n'est pas une chaîne.
Voilà, je retourne dans ma caverne.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <stdio.h>
#include <stdlib.h>
static size_t
my_strlen(const char *s)
{
/*
* Si on fait une vérification ici, on se heurte à une vérification
* redondante inutile, puisque `s' a déjà été testée dans la fonction
* `f'. Dès qu'il y a une redondance, c'est qu'il y a un problème
* quelque part.
*/
size_t i;
for (i = 0UL; s[i] != '\0'; ++i)
;
return i;
}
size_t
f(size_t nMax)
{
size_t nSize = -1;
char *const s = malloc(nMax);
if (s != NULL) {
fgets(s, nMax, stdin);
nSize = my_strlen(s);
free(s);
}
return nSize;
} |
Quant à l'utilisation de la fonction gets, elle n'est même plus dans la norme C11. Il faut donc la bannir définitivement.