Opérateur associativité en C préfixe spécifique et l'incrément postfix et décrément

StackOverflow https://stackoverflow.com/questions/2395423

  •  25-09-2019
  •  | 
  •  

Question

En fonctionnement C associativité est en tant que telle pour incrémentation, décrémentation et l'affectation.

  2. postfix ++ and -- 
  3. prefix ++ and -- 
  16. Direct assignment = 

La liste complète se trouve ici Wikipédia Opérateurs en C

Ma question est quand nous avons

int a, b;

b = 1;
a = b++;

printf("%d", a); // a is equal to 1

b = 1;
a = ++b;

printf("%d", a); //a is equal to 2

Pourquoi un égal à 1 avec b ++ lorsque l'opérateur incrément postfix devrait se produire avant l'affectation directe?

Et pourquoi est l'opérateur d'incrémentation de préfixe différent du postfix quand ils sont à la fois avant la cession?

Je suis assez sûr que je ne comprends pas quelque chose de très important quand il s'agit de associativité de fonctionnement.

Était-ce utile?

La solution

L'opérateur postfix a++ incrémente a puis retourner la valeur d'origine à savoir semblable à ceci:

{ temp=a; a=a+1; return temp; }

et le préfixe ++a retourne la nouvelle valeur i.e..

{ a=a+1; return a; }

Il est hors de propos à l'opérateur priorité .

(Et associativité définit si a-b-c égale à (a-b)-c ou a-(b-c).)

Autres conseils

La priorité des opérateurs et associativité ne vous dit pas ce qui se passe avant et ce qui se passe après . priorité opérateur / associativité n'a rien à voir avec elle. Dans les relations temporelles du langage C comme « avant » ou « après » sont définis par ce qu'on appelle points de séquence et uniquement par des points de séquence (et c'est une histoire totalement séparée) .

La priorité des opérateurs / associativité vous indique simplement quels opérandes appartiennent à des opérateurs qui. Par exemple, le a = b++ d'expression peut être interprétée officiellement comme (a = b)++ et comme a = (b++). La priorité des opérateurs / associativité est ce cas, vous indique simplement que cette dernière interprétation est correcte et l'ancien est incorrect (c.-à-++ applique à b et non le résultat de a = b).

, une fois encore, ne signifie pas que b doit être incrémentée en premier. La priorité des opérateurs / associativité, encore une fois, a noter à voir avec ce qui se passe « premier » et ce qui se passe « à côté ». Il vous indique simplement que le résultat de l'expression de b++ est affecté à a. Par définition, le résultat de b++ (incrément postfix) est le d'origine valeur de b. Voilà pourquoi a va obtenir le Valeur originale de b, qui est 1. Lorsque la b variable incrémentée est complètement hors de propos, tant que a obtient de affecté b d'origine valeur . Le compilateur est autorisé à évaluer cette expression dans toute b de commande et l'incrément à tout moment: tout va, aussi longtemps que a obtient en quelque sorte le Valeur originale de b (et personne ne se soucie vraiment comment que « en quelque sorte » œuvres en interne).

Par exemple, le compilateur peut évaluer a = b++ comme la séquence suivante d'opérations élémentaires

(1) a := b
(2) b := b + 1

ou peut l'évaluer comme suit

(1) b := b + 1
(2) a = b - 1

Notez que dans le premier cas b est en fait incrémenté à la fin, alors que dans le second cas b est incrémentée en premier. Mais dans les deux cas a obtient la même valeur correcte - la valeur initiale de b, qui est ce qu'il doit faire.

Mais je dois rappeler que les deux exemples ci-dessus sont ici juste pour des fins d'illustration. En réalité, des expressions comme a = ++b et a = b++ ont pas de points de séquence à l'intérieur, ce qui signifie que de votre point de vue tout dans ces expressions se simultanément . Il n'y a pas « avant », « après », « premier », « suivant » ou « dernier ». De telles expressions sont « atomique » dans un sens qu'ils ne peuvent pas être véritablement décomposées en une suite de petites étapes.

Comme AndreyT déjà souligné, la priorité et l'associativité ne vous disent pas sur l'ordre d'évaluation. Ils ne vous disent sur le groupement. Par exemple, la priorité est ce que dit l'utilisation a*b+c sont regroupées comme (a*b)+c au lieu de a*(b+c). Le compilateur est libre d'évaluer a, b et c dans l'ordre qu'il juge opportun ou l'autre de ces expressions. Associativité vous parle de regroupement lorsque vous avez les opérateurs du même ordre de priorité, le plus souvent, les mêmes opérateurs. Par exemple, il est ce que vous dit que a-b-c équivaut à (a-b)-c, non a-(b-c) (autrement dit, la soustraction reste associative).

Ordre d'évaluation est définie par des points de séquence. Il y a un point de séquence à la fin d'une expression complète (entre autres). Au point de l'ordre, toutes les évaluations précédentes doivent avoir eu lieu, et aucune des évaluations ultérieures peuvent avoir encore eu lieu.

En regardant vos exemples spécifiques, a=b++;, le résultat est le plus souvent de la définition de post-incrémentation lui-même. Un post-incrémentation donne la valeur précédente de la variable, et quelque temps avant le prochain point de la séquence, est incrémenté de la valeur de cette variable. Un pré-incrémentation donne la valeur de la variable de l'incrément appliqué. Dans les deux cas, cependant, ce que cela signifie la variable doit augmenter dans un ordre particulier par rapport à la cession. Par exemple, dans votre exemple pré-incrément, le compilateur est entièrement libre de faire quelque chose d'équivalent à:

temp = b+1;
a = temp;
b = b + 1;

De même, dans la version post-incrémentation, la variable peut être augmentée avant ou après la cession:

a = b;
b = b + 1;

ou

temp = b;
b = b + 1;
a = temp;

De toute façon, cependant, la valeur attribuée à a doit être la valeur de b avant qu'il ne soit incrémenté.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top