4
votes

Compréhension de la fonction strlen - Affectation de const char * s à const char * sc

Vous trouverez ci-dessous l'implémentation de strlen.c selon "La bibliothèque C standard,

size_t strlen(const char *s){
   const char *sc;
   for(sc = s; *sc != '\0'; ++sc)

   return (sc-s);  }

Ma compréhension de la légalité de sc = s est-elle correcte?

sc = s est une affectation légale car comme les deux variables sont déclarées comme const , toutes deux protègent l'objet pointé par s. Dans ce cas , il est légal de changer l'endroit où sc ou s pointent tous les deux mais toute attribution (ou référence?) à * s ou sc serait illégale.

p>


1 commentaires

sc et s ne sont pas const. Ils indiquent des choses qui pourraient être const.


3 Réponses :


2
votes

Vous avez raison.

const char * sc déclare un pointeur vers un const char . En gros, cela signifie que sc pointe vers une variable de type char (ou dans ce cas, un tableau contigu de char s) et que vous ne pouvez pas utiliser sc pour modifier la variable pointée. Regardez-le en direct ici .

Notez que sc lui-même n'est pas une variable const . Le const s'applique à la variable pointée, et non au pointeur. Vous pouvez ainsi modifier la valeur du pointeur , c'est-à-dire la variable vers laquelle il pointe.

Suivez cette réponse pour avoir plus d'informations sur les différentes utilisations de const et des pointeurs: Quelle est la différence entre const int *, const int * const et int const *?


2 commentaires

"Le const s'applique à la variable pointée ...", donc dans le cas de sc = s , le const de const char sc s'applique-t-il aux s < / code> ou la valeur de s . Dans ma réponse, j'ai supposé que les deux déclarations const s'appliquent à la valeur ultime des pointeurs, mais maintenant je n'en suis pas si sûr. C'est-à-dire que si cela s'appliquait à s, alors après avoir déclaré sc = s , il deviendrait illégal de changer ce vers quoi s pointe.


@ M.O. La mission ne devrait rien changer. Les deux variables sont déclarées comme des pointeurs vers des caractères constants, donc la valeur vers laquelle elles pointent est constante, contrairement aux pointeurs eux-mêmes. Puisque l'affectation assigne les pointeurs et non la mémoire vers laquelle ils pointent, le code est légal. Pour rendre les pointeurs constants, vous mettriez const après le * .



5
votes

Je pense que ce que vous demandez, c'est ce que signifie le mot-clé const . Si ce n'est pas le cas, veuillez clarifier votre question.

La façon dont j'aime penser est que toute variable const peut être stockée dans la ROM (mémoire morte) et les variables qui ne sont pas déclarées const peuvent être stockées dans la RAM (mémoire vive). Cela dépend du type d'ordinateur avec lequel vous travaillez, donc les données const peuvent ne pas être stockées dans la ROM, mais cela pourrait l'être.

Vous pouvez donc faire tout ce que vous voulez avec le pointeur lui-même, mais vous pouvez ne changez pas les données de la mémoire vers laquelle il pointe.

Cela signifie que vous pouvez référencer le pointeur et le faire circuler autant que vous le souhaitez. Vous pouvez également attribuer une valeur différente au pointeur.

Disons que vous avez ce code

foo[0] = 'J';

Il est parfaitement légal de le faire

const char *myPtr = bar;
myPtr = foo;

Les deux pointent maintenant "monde"

Il est également légal de faire

foo = bar;

Ce que vous n'êtes pas autorisé à faire, c'est de changer la mémoire de données réelle donc vous n'êtes pas autorisé à faire

const char* foo = "hello";
const char* bar = "world";


0 commentaires

2
votes

Ma compréhension de la légalité des sc = s est-elle correcte?

Oui, seuls quelques détails sur la dernière partie sont nécessaires.

... mais toute attribution (ou référence?) à * s ou sc serait illégale.

(Je suppose que OP signifie "... ou * sc serait illégal.")

Faire référence à ce vers quoi pointe s ou sc est OK comme dans char ch = * sc;

Tenter de modifier la valeur de * s ou * sc est un comportement indéfini (UB), pas "illégal" comme dans * sc = 'x';
(Voir bon détail supplémentaire de @rici )

Avec UB, l'affectation peut fonctionner, elle peut ne pas fonctionner les mardis, le code peut planter, etc. Ce n'est pas défini par C ce qui se passe. Le code de certitude ne doit pas essayer.


1 commentaires

* sc = 'x'; est une violation de contrainte (6.5.16 / 2) sans égard au point de quai sc . Un diagnostic doit être produit. * (char *) sc = 'x'; est UB si tout ce que sc pointe vers a été initialement défini avec un modificateur const ; sinon c'est parfaitement légal. (6.7.3 / 6) (Je sais que vous le savez. Et peut-être que la distinction n'est pas nécessaire pour cette question, mais cela pourrait ne pas faire de mal.)