2009-07-07 1 views
1

Я читаю из массива байтов следующим образом:разыменовать и указать указатель в одном утверждении?

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

поправьте меня, если я ошибаюсь, но ++ имеет приоритет над *, так что можно совместить * I и я ++ в том же заявлении ? (Например, * я ++)

(это технически небезопасным C#, а не C++, р байт *)

+4

Да, но _please_ нет. Ваш код очень легко читать, понимать, модифицировать и отлаживать. * i ++ не является ничем из вышеизложенного, потому что для понимания того, означает ли это (* i) ++ или * (i ++), вам необходимо правильно запомнить правила приоритета. –

+0

справедливо, и я должен был бы согласиться. просто потому, что это можно сделать, это не значит, что он должен :) – toasteroven

+0

Идиоматично в C/C++ писать * i ++, но это определенно не так в C#. –

ответ

2

Я считаю, что

id = *i; 
i++; 

и

id = *i++; 

эквивалентны.

Оператор ++, используемый в качестве суффикса (например, i++), возвращает значение переменной до приращения.


Я несколько смущен выход отражателя для

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++; 
    } 
} 

который выходит в

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

и

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

, которые явно не являются эквивалентными.

2

id = *i++

будет делать то, что вы хотите.

++ изменяет указатель после разыменования.

EDIT: Как указывает Эрик, согласно спецификации, ++ не происходит после разыменования. i ++ увеличивает i и возвращает свое начальное значение, поэтому определенное поведение спецификации - это увеличение, которое происходит до разыменования. Видимое поведение id = * i ++ одинаково, независимо от того, просматриваете ли вы прирост до или после разыменования.

+0

На самом деле, вы должны быть очень осторожны при создании этого утверждения. Он ПРИНИМАЕТ, что указатель изменяется после разыменования, но это на самом деле не так! Помните, что «после» подразумевает, что во времени есть последовательность событий. Это построение персонажа, чтобы определить, какая именно последовательность событий во времени для этого случая. Когда вы это сделаете, вы увидите, что на самом деле изменение переменной происходит перед разыменованием. –

+0

Более того: MSDN в «Приоритете и порядке оценки» явно заявляет, что операторы с более высоким приоритетом оцениваются перед операторами с более низким приоритетом. Таким образом, порядок оценки зависит не от прихоти компилятора, оптимизатора или от перегрузки оператора, он строго определен языком. Сначала добавьте, затем разыщите, но используйте значение старого указателя. Это становится немного сложнее, когда вы делаете что-то вроде этого: a = * i ++ + 2 * * i ++.Это можно рассматривать как однострочные спагетти, но это хорошо определено :) – Rolf