Bitowe operatory

dla wielkości typu unsigned zwolnione bity zawsze s¸

a wypełnia-

logiczne

ne zerami. Natomiast dla wielkości ze znakiem spowoduje to na pewnych maszynach wypełnienie tych miejsc bitem znaku (przesuni¸

ecie arytmetyczne), a na innych zerami (przesuni¸

ecie

logiczne).

Uwaga: Nie można ich używać do danych typu float lub double.

Dopełnienie jedynkowe

&

bitowa koniunkcja

~

|

bitowa alternatywa

Zamienia każdy bit 1 na 0 i odwrotnie. Typowe użycie:

^

bitowa różnica symetryczna

y = x&~077;

«

przesuni¸

ecie w lewo

»

przesuni¸

ecie w prawo

zasłania si¸

e zerami ostatnie sześć bitów zmiennej x.

Uwaga: Ta konstrukcjanie zależyod maszyny, pod-

~

uzupełnienie jedynkowe

czas gdy:

Koniunkcja bitowa &

y = x&0177700;

zakłada 16-bitowe słowo maszynowe.

& stosuje si¸

e cz¸

esto do ”zasłaniania” pewnego zbioru bitów, np.

Przykład:

c = n&0177;

s¸

a zerowane wszystkie oprócz siedmiu najniższych bitów wartości zmiennej n.

/*

getbits: daj n bitow x od pozycji p Różnice mi¸

edzy & i &&

Zerowa pozycja bitu jest prawy koniec x; n, p sa sensownymi wielkosciami calkowitymi

*/

unsigned getbits(unsigned x, int p, int n) Np.

Jesli

x=1,

y=2

to

{

return (x >> (p+1-n)) & ~(~0 << n); x & y

ma wartosc

0

}

x && y

1

Operacje

bitowe

na

Bitowy operator alter- znakach

natywy |

Kody ASCII

Bit

7

6

5

4

3

2

1

0

Używany do ”ustawiania” bitów. Np.

0 - cyfry

0 - duże

0 - a-o

litery

x = x|M ASK;

1 - litery

1 - cyfry

cyfry

ustawia 1 na tych bitach w zmiennej x, które w M ASK s¸

a równe

/małe

/p-z

1.

litery

Bitowa różnica syme-

tryczna ^

char toupper(char c)

/*

Funkcja zamienia male litery na duze

*/

{

Ustawia jedynk¸

e na każdej pozycji bitowej tam, gdzie bity w char maska=223;

/*

223

-

11011111

*/

obu argumentach s¸

a różne, a zero tam, gdzie s¸

a takie same. Np.

return c & maska;

}

x = 011^022;

daje w rezultacie wartość 0.

char tolower(char c)

Operatory przesuni¸

ecia /* Funkcja zamienia duze litery na male */

« oraz »

{

return c | 32;

/*

32

-

00100000

*/

}

Służ¸

a do przesuwania argumentu stoj¸

acego po lewej stronie

operatora o liczb¸

e pozycji określon¸

a przez argument stoj¸

acy po

prawej stronie. Np.

y = x << 2;

char swapcase{char c)

/*

Zamiana duzych liter na male i odwrotnie

*/

przesuwa x w lewo o dwie pozycje, zwolnione bity wypełnia si¸

e

{

zerami (operacja równoważna mnożeniu przez 4.

return c ^ 32;

}

y = x >> 2;

int razy10(int n)

Priorytety i kolejność

/*

Mnozenie liczby calkowitej przez 10

przy pomocy operatorow przesuniecia

*/

obliczeń

{

int m,p;

Priorytety i ł¸

aczność operatorów

m=n<<1;

p=m<<2;

Operatory

ُ

acz-

return m+p;

ność

}

() [] -> .

L→R

! - ++ -- + - * & (type) sizeof R→L

Operatory i wyrażenia

* / %

L→R

przypisania

op=

+

-

L→R

i=i+3;

jest równoważne

i+=3;

<<

>>

L→R

< <= > >=

L→R

op

jest jednym z operator\’ ow:

==

!=

L→R

+

-

*

/

%

<<

>>

&

^

|

&

L→R

UWAGA:

Jezeli

wyr1

i

wyr2

sa wyrazeniami, to

^

L→R

wyr1 op= wyr2;

jest rownowazne z

|

L→R

wyr1=(wyr1) op (wyr2);

&&

L→R

Zatem przypisanie

||

L→R

x *= y+1;

jest odpowiednikiem

x=x*(y+1);

?:

L→R

Przykład:

= += -= *= /= %= ^= |= <<= >>=

R→L

,

L→R

/*

Zlicz bity argumentu o wartosci

1

*/

int bitcount(unsigned x)

Jednoargumentowe operatory +, -, * oraz & maj¸

a wyższy

{

priorytet, niż ich odpowiedniki dwuargumentowe.

int b;

Lewostrona ł¸

aczność operatora oznacza, że jeśli na tym sa-for (b=0; x!=0; x >> 1)

mym poziomie wyst¸

epuje kilka operatorów, to najpierw jest wy-if (x & 01)

konywany operator lewy.

b++;

return b;

W j¸

ezyku C nie określa si¸

e kolejności obliczania argumentów

}

operatora. Wyj¸

atki, to:

&&, ||, ?:

oraz

,

Np. w instrukcji

x=f()+g();

f może być

Wyrażenia warunkowe wykonana przed g lub odwrotnie.

Nie jest określona kolejność obliczania wartości argumentów Instrukcja realizuj¸

aca funkcj¸

e

z=max(a,b)

funkcji. Instrukcja

if (a>b)

printf ("%d %d\n", + + n, power(2, n)); z=a;

może generowć różne wyniki w zależności od kompilatora.

Możliwe s¸

a również inne efekty ”uboczne” (generowane przez else

wywołania funkcji, zagnieżdżone instrukcje przypisania oraz operatory zwi¸

ekszania i zmniejszania), np.

z=b;

a[i]=i++;

zależy

od

kolejności

aktualizacji

wartości

zmiennych

jest rownowazna

z=(a>b) ? a:b;

bior¸

acych udział w obliczeniach.

albo

z= a>b ? a:b;

Konkluzja: Pisanie programów zależnych od kolejności wyko-nania obliczeń należy do złej praktyki programowania w każdym Priorytet operatora ?: jest bardzo niski.

j¸

ezyku.

Wyrażenie warunkowe cz¸

esto wpływa na zwi¸

ezłość programu.

Np.

Sterowanie

1)

for (i=0; i<n; i++)

printf("%6d%c", a[i],

(i%10 == 9 || i== n-1) ? ’\n’:’ ’); Instrukcje i bloki

2)

printf("Masz %d czes%s.\n",n, n==1 ? "c":"ci"); Wyrażenie staje si¸

e instrukcj¸

a po zakończeniu średnikiem, np.

x=0;

/* szukanie x metoda bisekcji wsrod i++;

v[0]<=v[1]<=...<=v[n-1] */

printf{"Uwaga!\n");

int binsearch(int x, int v[], int n)

{

int low=0, high, mid;

Nawiasy klamrowe

high=n-1;

{

i

}

s¸

a używane do tworzenia

while (low <= high){

bloku. (Zmienne można zadeklarować wewn¸

atrz każdego bloku.)

Po nawiasie zamyka¸

acym blok nie może wyst¸

epować średnik.

mid=(low+high)/2;

if (x<v[mid])

high=mid-1;

Instrukcja

if-else

else if (x>v[mid])

low=mid+1;

else

/* znaleziono

*/

return mid;

}

if (wyrazenie)

return -1;

/*

Nie znaleziono

*/

instrukcja1

}

else

instrukcja2

Cz¸

eść else można pomin¸

ać.

Najcz¸

eściej pisze si¸

e

if (wyrazenie)

zamiast

if (wyrazenie != 0)

Każda cz¸

eść else jest przyporz¸

adkowana najbliższej z po-

przednich instrukcji if nie zawieraj¸

acej cz¸

eści else, np.

if (n>0)

if (a>b)

z=a;

else

z=b;

Dwuznaczność ta jest szczególnie szkodliwa w takich sytu-acjach, jak

if (n>0)

for (i=0; i<n; i++)

if (s[i] > 0) {

printf("...");

return i;

}

else

/*

Zle

*/

printf("Blad -- n jest ujemne); Wci¸

ecie wyraźnie pokazuje, o co chodzi programiście, ale kompilator przyporz¸

adkuje else wewn¸

etrznej funkcji if.

konstrukcja else-if

if (wyrazenie)

instrukcja

else if (wyrazenie)

instrukcja

else if (wyrazenie)

instrukcja

Przykład: