2010-09-07 8 views
6
int val = 5; 

printf("%d",++val++); //gives compilation error : '++' needs l-value 

int *p = &val; 
printf("%d",++*p++); //no error 

Quelqu'un pourrait-il expliquer ces 2 cas? Merci.Explication de ++ val ++ et ++ * p ++ dans C

+0

Dans les cas comme celui-ci, il est souvent utile d'afficher également les messages d'erreur que vous voyez et le compilateur (version) que vous êtes en utilisant. – sbi

+7

Personne ne devrait jamais écrire du code comme celui-ci. – duffymo

+0

Votez pour fermer comme une vraie question. Un code comme celui-ci ne se trouve pas dans la vraie vie. Tout ce qui est juste un accident de syntaxe comme celle-ci devrait être pointé vers une FAQ qui dit juste ne soyez pas stupide. –

Répondre

27

++val++ est la même que ++(val++). Puisque le résultat de val++ n'est pas une valeur, ceci est illégal. Et comme l'a souligné Stephen Canon, si le résultat de val++ était une lvalue, ++(val++) serait un comportement indéfini car il n'y a pas de point de séquence entre les ++ s.

++*p++ est la même que ++(*(p++)). Depuis le résultat de *(p++)est une lvalue, c'est légal.

+1

Excellente réponse, bien que je note que même si 'val ++' était une lvalue, le comportement serait toujours indéfini. '(++ val) ++' en C++, par exemple, invoquerait un comportement indéfini. –

+0

@Stephen: Très bon point, je vais ajouter cela à la réponse. – sepp2k

+1

L'opérateur post-incrément renvoie toujours un 'rvalue' (en C comme en C++). En C++, '(++ val) ++' invoque un comportement indéterminé car l'opérateur de pré-incrémentation ('++') renvoie une valeur l (en C++) et la valeur de 'val' est modifiée plus d'une fois entre deux points de séquence . –

0

int j = ++val++; //gives compilation error

Cela parce que vous ne pouvez pas pré-incrément d'un rvalue. ++val++ est interprété comme ++(val++) parce que l'opérateur de post-incrément a une priorité plus élevée que l'opérateur de pré-incrémentation. val++ renvoie rvalue et l'opérateur de pré-incrémentation requiert que son opérande soit lvalue. :)

int k = ++*p++; //no error

++*p++ est interprété comme ++(*(p++)), ce qui est tout à fait valable.

4

L'expression ++val++ est la même que (++val)++ (ou peut-être ++(val++), de toute façon ce n'est pas très pertinent). Le résultat de l'opérateur ++ n'est pas la variable, mais la valeur et vous ne pouvez pas appliquer l'opérateur à une valeur.

L'expression ++*p++ est la même que ++(*(p++)). Le résultat de p++ est la valeur, mais le résultat de *(p++) est un emplacement de mémoire auquel l'opérateur ++ peut être appliqué.

+0

'++ val ++' est la même chose que '++ (val ++)', qui n'est pas ** identique à '(++ val) ++'. (Bien que dans C, les deux sont syntaxiquement invalides) –

+0

@Stephen Canon: Oui, ce n'est pas évident à laquelle il évalue. Comme l'expression est invalide, je n'ai jamais pris la peine d'apprendre laquelle de ces deux variantes est invalide.:) – Guffa

+0

ah, mais en C++, l'un d'entre eux est invalide alors que l'autre est syntaxiquement valide mais sémantiquement indéfini. (C++ est farfelu!) –

1

Notez également que vous modifiez l'adresse du pointeur par

int k = ++*p++; 
+0

oui je le sais. Je l'ai utilisé pour la simplicité. Au lieu de int val, j'aurais pu utiliser int array. – understack