2009-07-07 9 views
1

Je lis à partir d'un tableau d'octets comme suit:déréférencer et avancer le pointeur dans une déclaration?

int* i = (int*)p; 
id = *i; 
i++; 

me corriger si je me trompe, mais ++ a préséance sur *, est donc possible de combiner le * i et i ++ dans la même déclaration ? (Par exemple, * i ++)

(cela est techniquement dangereux C#, pas C++, p est un octet *)

+4

Oui, mais _please_ ne le fait pas. Votre code est parfaitement facile à lire, comprendre, modifier et déboguer. * i ++ n'est rien de ce qui précède car pour comprendre si cela signifie (* i) ++ ou * (i ++), vous devez vous souvenir correctement des règles de précédence. –

+0

assez juste, et je serais d'accord. juste parce que cela peut être fait, cela ne veut pas dire qu'il devrait :) – toasteroven

+0

Il est idiomatique en C/C++ d'écrire * i ++, mais ce n'est certainement pas le cas en C#. –

Répondre

2

Je crois que

id = *i; 
i++; 

et

id = *i++; 

sont équivalentes.

L'opérateur ++, lorsqu'il est utilisé en tant que suffixe (par exemple i++), renvoie la valeur de la variable avant l'incrément.


Je suis un peu confus par la sortie du réflecteur pour

unsafe class Test 
{ 
    static public void Test1(int p, out int id) 
    { 
     int* i = (int*)(p); 
     id = *i; 
     i++; 
    } 

    static public void Test2(int p, out int id) 
    { 
     int* i = (int*)(p); 
     id = *i++; 
    } 
} 

qui sort comme

public static unsafe void Test1(int p, out int id) 
{ 
    int* i = (int*) p; 
    id = i[0]; 
    i++; 
} 

et

public static unsafe void Test2(int p, out int id) 
{ 
    int* i = (int*) p; 
    i++; 
    id = i[0]; 
} 

qui ne sont manifestement pas équivalentes.

2

id = *i++

fera ce que vous voulez.

++ modifie le pointeur après le déréférencement.

EDIT: Comme Eric souligne, par la spécification, ++ ne se produit pas après déréférencement. i ++ incrémente i et renvoie sa valeur initiale, de sorte que le comportement défini par spécification est l'incrément qui se produit avant le déréférencement. Le comportement visible de id = * i ++ est le même que vous voyiez l'incrément qui se produit avant ou après le déréférencement.

+0

En fait, vous devez être très prudent lorsque vous faites cette déclaration. Il APPARAIT que le pointeur est modifié après le déréférencement, mais ce n'est pas vrai! Rappelez-vous, "après" implique qu'il y a une séquence d'événements dans le temps. C'est la construction de caractères pour déterminer quelle est la séquence exacte des événements dans le temps pour ce cas. Quand vous le faites, vous verrez que la modification de la variable se produit AVANT le déréférencement. –

+0

Qui plus est: MSDN, dans "Priorité et ordre d'évaluation", indique explicitement que les opérateurs ayant une priorité plus élevée sont évalués avant les opérateurs de priorité inférieure. Ainsi, l'ordre d'évaluation ne dépend pas d'un caprice du compilateur, de l'optimiseur ou d'une surcharge de l'opérateur, il est strictement défini par le langage. Incrémenter d'abord, puis déréférencer, mais en utilisant l'ancienne valeur du pointeur. Cela devient un peu plus compliqué quand vous faites quelque chose comme ça: a = * i ++ + 2 * * i ++.Cela peut être vu comme un spaghetti à une ligne, mais c'est bien défini :) – Rolf

Questions connexes