2 TYPY, OPERATORY I WYRAŻENIA________
-077 jest wyrażeniem stałym, które może być obliczone podczas fazy tłumaczenia programu.
Aby pokazać kilka operatorów bitowych, rozważmy funkcję getbits(x,p,n), która zwraca n-bitowe pole wycięte z x od pozycji p, dosunięte do prawej strony wyniku. Przyjmujemy tu, że zerową pozycją bitu jest prawy koniec x oraz że n i p są sensownymi wartościami całkowitymi. Na przykład getbits(x,4,3) zwraca trzy bity - z pozycji 4, 3 i 2 - dosunięte do prawej strony wyniku.
/* getbits: daj n bitów x od pozycji p */ unsigned getbits(unsigned x, int p, int n)
return (x » (p+1-n)) & ~(~0 « n);
Wyrażenie x » (p+1-n) dosuwa wybrane pole do prawego końca słowa. Zapis -0 oznacza same jedynki; przesunięcie ich w lewo o n pozycji bitowych (~0«n) tworzy maskę z zerami na prawych skrajnych n bitach. Dopełnienie jedynkowe tej maski za pomocą operatora ~ tworzy maskę zbudowaną z jedynek na prawych skrajnych n bitach.
Ćwiczenie 2.6. Napisz funkcję setbits(xłp,n,y) zwracającą wartość x, w której n bitów - poczynając od pozycji p - zastąpiono przez n skrajnych bitów z prawej strony y. Pozostałe bity x nie powinny ulec zmianie.
Ćwiczenie 2.7. Napisz funkcję inwert(x,p,n) zwracającą wartość x, w której n bitów - poczynając od pozycji p - zamieniono z 1 na 0 i odwrotnie. Pozostałe bity x nie powinny ulec zmianie. ^
Ćwiczenie 2.8. Napisz funkcję rightrot(x,n), która zwraca wartość całkowitego argumentu X przesuniętą cyklicznie w prawo o n pozycji bitowych.
Wyrażenia podobne do i = i + 2
w których zmienna występująca po lewej stronie operatora przypisania = powtarza^ natychmiast po prawej stronie, można zapisać w bardziej zwartej postaci
i += 2
Operator += jest nazywany operatorem przypisania.
DJa większości operatorów dwuargumentowych (jak +, który ma lew ment) występuje odpowiedni operator przypisania op=, gdzie op jest jednym z operatorów
+ -*/%«»& ~ \
Jeśli wyrl i wyr2 są wyrażeniami, to wyr] op= wyr2 jest równoważne z
wyr] = (wyrl) op (wyr2)
przy czym wyrażenie wyrl oblicza się tylko raz. Zwróć uwagę na nawiasy otaczające wyrażenie wyr2\ przypisanie
x *= y + 1
jest odpowiednikiem x = x * (y + 1)
a nie
x = x * y + 1
Na przykład funkcja bitcount zlicza bitowe jedynki swojego całkowitego argumentu.
/* bitcount: policz bity 1 w x */ int bitcount(unsigned x)
int b;
for (b = 0; x != 0; x »= 1) if (x & 01) b++; return b;
Zadeklarowanie argumentu x jako unsigned daje pewność, że podczas przesuwania w prawo - niezależnie od maszyny, na której działa program - zwolnione bity zostaną "Spełnione zerami, a nie bitami znaku liczby.
Oprócz zwięzłości operatory przypisania mają jeszcze tę zaletę, że odpowiadają spodowi myślenia człowieka. Mówimy „dodaj 2 do i” albo „zwiększ i o 2”, nie zaś
79