Ces 2 sont très couramment utilisés termes de programmation et c'est extrêmement important pour un programmeur de savoir. Et comme je le comprends ces 2 concepts sont étroitement liés, l'un ne peut pas faire sans l'autre quand on parle d'expressions.
Prenons un exemple simple:
int a=1; // Line 1
a = a++ + ++a; // Line 2
printf("%d",a); // Line 3
Maintenant, il est évident qu' Line 2
conduit à un Comportement Indéfini, puisque la Séquence de points en C et C++ comprennent:
Entre l'évaluation de la gauche et de la droite des opérandes de l'opérateur && (logique ET), || (OU logique), et par des virgules des opérateurs. Par exemple, dans le l'expression *p++ != 0 && *q++ != 0, tous les effets secondaires de la sous-expression *p++ != 0 avant toute tentative d'accès à q.
Entre l'évaluation de la première opérande de l'ternaire "point d'interrogation" de l'opérateur et de l' deuxième ou troisième opérande. Par exemple, dans l'expression a = (*p++) ? (*p++) : 0 il y a un point de séquence après le premier *p++, sens qu'il a déjà été incrémenté par le temps de l' la deuxième instance est exécuté.
À la fin d'une pleine expression. Cette catégorie comprend expression états (comme la cession a=b;), de retour des états, la le contrôle des expressions de if, switch, tout ou-même si des déclarations, et toutes les trois expressions dans une instruction for.
Avant qu'une fonction est entré dans un appel de fonction. L'ordre dans lequel les arguments sont évalués n'est pas spécifié, mais ce point de séquence signifie que l'ensemble de leurs effets secondaires avant la fonction est entré. Dans l'expression f(i++) + g(j++) + h(k++), f est appelée avec un paramètre de la valeur initiale de i, mais i est incrémenté avant d'entrer dans le corps de f. De même, j et k sont mis à jour avant d'entrer dans g et h respectivement. Cependant, il n'est pas spécifié dans l'ordre de f(), g(), h() sont exécutées, ni dans quel ordre i, j, k est incrémenté. Les valeurs de j et k dans le corps de f est donc undefined.3 Notez qu'une fonction appel de f(a,b,c) n'est pas une utilisation de l' opérateur virgule et de l'ordre de évaluation pour a, b, et c est non spécifié.
Au retour de la fonction, après le retour de la valeur est copiée dans le l'appel de contexte. (De ce point de séquence n'est spécifié dans la norme C++; elle n'est présente que de manière implicite dans C.)
À la fin d'un initialiseur; par exemple, après l'évaluation de 5 dans la déclaration int a = 5;.
Ainsi, en passant par le Point n ° 3:
À la fin d'une pleine expression. Cette catégorie comprend l'expression des états (comme l'affectation a=b;), de retour des états, le contrôle des expressions de if, switch, while, ou le faire-même si des déclarations, et toutes les trois expressions dans une instruction for.
Line 2
clairement conduit à un Comportement Indéfini. Cela montre à quel Comportement Indéfini est étroitement associé à la Séquence de Points.
Prenons maintenant un autre exemple:
int x=10,y=1,z=2; // Line 4
int result = x<y<z; // Line 5
Maintenant, son évident que Line 5
fera la variable result
stocker 1
.
Maintenant, l'expression x<y<z
en Line 5
peut être évalué comme suit:
x<(y<z)
ou (x<y)<z
. Dans le premier cas, la valeur de result
sera 0
et dans le second cas result
sera 1
. Mais nous savons que, lorsque l' Operator Precedence
est Equal/Same
- Associativity
entre en jeu, donc, est évaluée comme (x<y)<z
.
C'est ce qui est dit dans cet Article MSDN:
La priorité et associativité des opérateurs de C affectent le regroupement et l'évaluation des opérandes dans les expressions. Un opérateur de priorité n'a de sens que si d'autres opérateurs plus ou moins élevés de précédence sont présents. Expressions avec plus de précédence des opérateurs sont évalués en premier. La priorité peut aussi être décrit par le mot "contraignantes". Les opérateurs avec une priorité plus élevée sont dit d'avoir le resserrement de liaison.
Maintenant, à propos de l'article ci-dessus:
Il mentionne les "Expressions avec plus de précédence des opérateurs sont évalués en premier."
Il peut sembler incorrecte. Mais, je pense que l'article n'est pas de dire quelque chose de mal si l'on considère qu' ()
est également un opérateur x<y<z
est le même que (x<y)<z
. Mon raisonnement est que si l'associativité n'est en jeu, alors les expressions complètes évaluation devient ambigu car <
n'est pas un Point de Séquence.
Aussi, un autre lien que j'ai trouvé dit cela à Priorité et Associativité des opérateurs:
Cette page répertorie les opérateurs de C dans l'ordre de priorité (de la plus haute à la plus basse). Leur associativité indique dans quel ordre les opérateurs de même priorité, dans une expression sont appliquées.
Donc, en prenant, le deuxième exemple d' int result=x<y<z
, nous pouvons voir ici qu'il y a en tout 3 expressions, x
, y
et z
, depuis, la forme la plus simple d'une expression est composée d'une seule constante littérale ou d'un objet. Donc le résultat de ces expressions, en x
, y
, z
y serait rvalues, c'est à dire, 10
, 1
et 2
respectivement. Donc, maintenant nous pouvons interpréter x<y<z
comme 10<1<2
.
Maintenant, n'est-ce pas l'Associativité entrent en jeu depuis maintenant, nous avons 2 expressions à évaluer, soit 10<1
ou 1<2
, et puisque la priorité de l'opérateur est le même, ils sont évalués de gauche à droite?
La prise de ce dernier exemple que mon argument:
int myval = ( printf("Operator\n"), printf("Precedence\n"), printf("vs\n"),
printf("Order of Evaluation\n") );
Maintenant, dans l'exemple ci-dessus, depuis l' comma
opérateur a même ordre de priorité, les expressions sont évaluées left-to-right
et la valeur de retour de la dernière printf()
est stocké dans myval
.
Dans SO/IEC 9899:201x en vertu de J. 1 comportement Quelconque , il mentionne:
L'ordre dans lequel les sous-expressions sont évaluées et l'ordre dans lequel les effets secondaires prendre place, sauf tel que spécifié pour la fonction appel (), &&, ||, ?:, et la virgule les opérateurs (6.5).
Maintenant je voudrais savoir, serait-il faux de dire:
Afin de l'Évaluation dépend de la priorité des opérateurs, laissant les cas de Comportement non spécifié.
Je voudrais être corrigé si des erreurs ont été faits dans quelque chose je l'ai dit dans ma question. La raison que j'ai posté cette question est en raison de la confusion créée dans mon esprit par l'Article MSDN. Est-il dans l'Erreur ou pas?