Je viens de commencer à apprendre c, et je reçois que
*a++ = *b++
3 Réponses :
1)
a = a+1; b = b+1 *a = *b;
Est-ce que c'est vrai que x = * a ++ code> est requis i> pour être équivalent à
x = * A; a = A + 1; code>? Un compilateur conforme pourrait-il la mettre en œuvre comme
temp = a; A = A + 1; x = * TEMP; code>?
La séquence exacte dans laquelle les expressions sont évaluées et les effets secondaires appliqués sont laissés non spécifiés em>; Tout ce qui est garanti est que le résultat de Si vous voulez savoir comment votre plate-forme EM> les gère, vous pouvez consulter le code machine généré, mais sachez qu'il peut toujours varier en fonction des paramètres du compilateur ou du code environnant. P> * b ++ code> (la valeur que
B code> Pointe actuellement sur) est attribuée au résultat de
* A ++ code> ( la valeur que
a code> pointe actuellement) et que les deux pointeurs sont avancés. L'ordre exact des opérations variera. P>
Vous avez dit que vous croyez que:
var_a = a; a = a + 1; // must pointer check var_a here var_b = b; b = b + 1; val = *var_b; // pointer checks var_b *var_a = val;
Donc l'expression a = * p ++; code> effectuée en 2 manières (1) b> premier
p attribué dans certains var puis parce que code> ++ `a une priorité supérieure Donc,
p code> mis à jour en points à l'emplacement suivant, puis dans deuxième étape i> valeur ancienne de
p code> = var attribué à
A code > comme
a = * var code>. (2) b> premier
* p code> Attribuer à
A code> car
++ code> est l'opérateur postfix puis
p Code> Mises à jour du point suivant.
@Grijeshchaauhan: correct; Soit le commandement est légal dans C. En C #, la spécification nécessite d'abord les effets secondaires du côté gauche, le cas échéant, sont produits. Puis effet latéral de l'incrément de p code>, puis l'effet latéral de la déséroférance de l'ancienne valeur de
p code> se produit (rappelez-vous, la déséroférance produit un effet secondaire en C # si le pointeur est invalide), puis l'effet secondaire de l'affectation se produit. C'est-à-dire que dans les effets secondaires de C # "I> laissés à droite i> pour les subexpressions et en ordre précédent i> pour les opérateurs.
Jamais connu avant de lire cette réponse que l'expression a = * p ++ code> peut être évaluée comme
var = p; code>
p = p + 1; code>
A = * var code>!
@HACCKS: pareil pour toi. Je croyais aussi que malgré la nommée, cela ne signifie pas que le pré-augmentation de la pré-augmentation sera d'abord en mémoire, puis de retourner, et cela ne signifie pas que la post-incrétation reviendra d'abord puis écrivez en mémoire. Mais cette idée fausse a été supprimée maintenant.
@ERIFLIPPERT: VAR = A; est faux que je pense en génération de code dans le deuxième cas. Il devrait être var = * a; Corrigez-moi si je me trompe.
Le compilateur est libre de faire tout ce qu'il aime tant que le programme se comporte correctement, il n'ya donc pas grand chose à dire sur la manière dont cela sera traduit en général. Tout ce que vous pouvez faire est de le compiler avec le compilateur que vous utilisez et examinez le code généré - cela vous dira simplement de votre compilateur particulier dans ce cas particulier.
Essayez d'observer et de comprendre un code ASM généré par
GCC -S code>.
Dans
* a ++ = * b ++; code>,
++ code> est postfix si d'abord
* b code> attribué à
* A code> * Code> B ++ code> et
A ++ code> effectué.
Vous faites une erreur commune de débutant de confusion la précédente i> avec ordre des effets secondaires i>. Ils ont en fait très peu à faire les uns avec les autres. Lorsque vous dites
a () + b () * c () code> in c, il n'y a aucune obligation que
b () code> et
c () code> c () code> être appelé avant
a () code> juste parce que
* code> est une priorité supérieure à celle
+ code>. Les fonctions peuvent être appelées dans n'importe quel ordre i>, tant que
b () code> et
c () code> sont appelés avant
* code >,
a () code> est appelé avant
+ code> et
* code> est appelé avant
+ code>. Le compilateur peut choisir n'importe quel ordre des appels i> satisfaisant à ces contraintes.
@Grijeshchauhaan: Vous faites une erreur commune de débutant pour supposer que l'opération Postfix a un point défini sur lequel se produisent les incréments. Ce ne est pas. Un compilateur conforme est autorisé à effectuer les incréments à tout moment. Si vous ne comprenez pas pourquoi c'est, lisez ma réponse avec soin.