0
votes

Confusion à propos de la longueur de la chaîne de retour

J'ai réécrit la fonction strallen () code> de la fonction code> en-tête.

appeler la fonction à l'aide du code ci-dessous produit un nombre ridiculement élevé. 6356735 P>

#include <stdio.h>
#include <string.h>

size_t my_strlen(const char *s);

int main(void) {
    const char str[] = "abcd";

    printf("length of abcd: %d\n", my_strlen(str));
}

size_t my_strlen(const char *s) {
    const char *p = s;
    while (*s)
        s++;
    return s;
}


7 commentaires

Votre compilateur vous a-t-il vraiment donné aucune erreur ni avertissement? Si c'est le cas, ne les ignorez pas. Si ce n'est pas le cas, trouvez comment obtenir votre compilateur pour vous donner plus d'aide ou de passer à un meilleur compilateur.


retour S; renvoie l'adresse non de la longueur et vous imprimez de la même manière. Compiler doit avoir averti la même chose. Retour S-P; est correct car il renvoie entier et c'est ce qui est attendu.


Je suis toujours confus: lorsque la boucle tandis que la boucle se termine, s pointe sur la place dans la chaîne où le caractère null est et p pointe des points à S (ou S [0]), donc n'est donc pas s - p La même chose que i-0 où je suis l'index de l'endroit où le caractère nul est stocké, ce qui est fondamentalement je?


@Shuster n ° Les cordes ne sont pas stockées à zéro, elles sont stockées dans un pointeur à un emplacement en mémoire (quelque part au-dessus de zéro). Au lieu de cela, prenez la différence entre les deux.


Par exemple, prenez ceci: char * p1 = "helloworld"; Char * p2 = "Au revoir"; p1 = p2 + 5; . P1 n'est pas World à la fin de cela, c'est ye .


Une chose à noter est que le résultat de s - p est de type ptrdiff_t qui est signé et le résultat n'est défini que si la valeur est représentable. Un code strictement correct n'utiliserait pas de soustraction, mais un index d'exécution Taille_T .


Notez également "my_strlen" sera nettement plus lent que la normale Strlen pour les chaînes de plus de 64 caractères. Le Strlen compare 4 octets per-itération. Vous pouvez faire quelque chose de similaire en casting à non signé et en comparant chacun des quatre octets par itération.


3 Réponses :


1
votes

p pointe vers le début de la chaîne, mais c'est un pointeur et non un index. Il ne sera jamais zéro car c'est ce qui est utilisé lorsque malloc () échoue pour allouer la mémoire.


0 commentaires

3
votes

Ici, vous retournez la chaîne (un pointeur sur char ) au lieu de la longueur de la chaîne: xxx

. Faites ceci (soustrayez le fin de la chaîne depuis le début): xxx

Les cordes ne sont pas stockées à zéro, elles sont stockées dans un endroit en mémoire (quelque part qui n'est pas zéro et dépend sur l'environnement).

Par exemple, prenez ceci: Char * P1 = "helloworld"; Char * p2 = "Au revoir"; p1 = p2 + 5; . p1 ne pointe pas sur World à la fin de cela, il pointe sur ye .


0 commentaires

0
votes

Les pointeurs sont déroutants.

L'exemple que vous avez fourni affiche la valeur de l'adresse de la mémoire à laquelle un pointeur s points. La valeur est "aléatoire".

L'opérateur ++ (préprément avant et post) d'un pointeur de caractère déplace un pointeur Tailleof (char) octets à droite (c.-à-d. Déplace le pointeur sur le Next Char).

Comme exemple, laissez char * p point sur une adresse mémoire 123. Si nous l'incrédus (c.-à-d. p ++ ), il serait indiqué à l'adresse de la mémoire 123 + taille de taille (char) (Sommation à 124).

p pointe du début de la chaîne

oui. Il pointe d'une adresse de la mémoire où un débit qui est le début de la chaîne réside.

Soustraire p à partir de s doit être identique au s

généralement non. il n'est vrai que si la taille de la chaîne est zéro (en supposant qu'un pointeur n'est pas null). Dans le code que vous avez fourni, le pointeur s est incrémenté n fois. Un incrément est l'ajout Tailleof (Char) à un pointeur de caractère. Pour cette raison, s devient p + n * taille de (caractère) . p + n * Taille de (caractère) est égal à p si n est zéro.

Comment cela fonctionne-t-il en particulier?

Nous avons découvert que s est p + n * taille de (caractère) . L'opération s - p peut être étendue comme ((P + N * Tailleofof (char)) - p) / taille de caractère de (caractère) , qui est n < / code> - la taille de la chaîne.

REMARQUE: Les chaînes de style C sont \ 0 terminés. \ 0 est interprété comme false , et il termine le pendant en boucle à la fin d'une chaîne.

Vous pouvez jouer un peu avec http://pythontutor.com/c.html#mode = Modifier afin de mieux comprendre les pointeurs.


1 commentaires

La valeur n'est pas "aléatoire", elle n'est pas spécifiée, c'est-à-dire n'existe pas. Vous pensez peut-être que vous pouvez l'observer, mais toute tentative de le faire a un comportement indéfini, alors non vous ne pouvez pas! Ne vous inquiétez pas: c'est une idée fausse commune.