2 TYPY, OPERATORY I WYRAŻENIA
unsigned long int next = 1;
I* rand: daj pseudo-losowo liczbę całkowitą z przedziału 0..32767 */ int rand(void)
next = next * 1103515245 + 12345; return (unsigned int) (next/65536) % 32768;
I* srand: ustal zarodek dla funkcji rand() */ void srand(unsigned int seed)
next = seed;
A
Ćwiczenie 2.3. Napisz funkcję htoi(s), która zamieni ciąg cyfr szesnastkowych na równoważną mu liczbę całkowitą. W funkcji należy uwzględnić, że ciąg może zaczynać się od 0x lub 0X. Dozwolonymi cyframi szesnastkowymi są: cyfry od 0 do 9 i litery od a do f oraz od A do F. V
Operatory zwiększania i zmniejszania
Język C oferuje dwa niezwykłe operatory zwiększania i zmniejszania wartości zmiennych. Operator zwiększania ++ dodaje 1 do swojego argumentu, podczas gdy opera-tor zmniejszania — odejmuje 1. Już przedtem często używaliśmy operatora ++ dt zwiększania wartości zmiennych, np. H
if (c == ’\n’) 1
++nl;
Niezwykłe jest to, że operatory ++ i — mogą być używane zarówno jako przedrostkowe (przed zmienną: ++n), jak i przyrostkowe (po zmiennej: n++). W obu przypadkac wynikiem jest zmiana wartości zmiennej n, ale wyrażenie ++n zwiększa n przed u i)
ciem jej wartości, natomiast wyrażenie n-H- zwiększa zmienną n po użyciu jej poprzek
•
niej wartości. Oznacza to, że w kontekście, w którym jest istotna także wartość (a fl!': tylko efekt) zwiększenia, wyrażenia ++n oraz n-H- są różne. Jeśli n równa się 5, to
x = n-H-; j
nadaje x wartość 5, ale
x = -H-n;
2.8 operatory zwiększania i zmniejszania ___
nadaje x wartość 6. W obu przypadkach wartością zmiennej n zwiększania i zmniejszania można stosować tylko do zmiennych. Takie wyrażenia, jak (i+j)++, są błędne.
W kontekście, w którym nie jest potrzebna wartość, a tylko sam efekt zwiększenia, np.
if (c == ’\n’) nl++;
użycie operatora przedrostkowego i przyrostkowego jest równoważne. Istnieją jednak sytuacje, w których specjalnie stosuje się jeden z tych operatorów. Dla przykładu rozważmy funkcję squeeze(s,c) usuwającą wszystkie wystąpienia znaku c z tekstu zawartego w s.
I* squeeze: usuń wszystkie znaki c z s */ void squeeze(char s[], int c)
int i, j;
for (i = j = 0; s[i] != ’\0’; i++) if (s[i] != c) s(j++] = 8(i]; s[j] = ’\0’;
Każde pojawienie się znaku różnego od c spowoduje przepisanie go na bieżącą j-tą pozycję ciągu s, a następnie - i tylko wtedy - zwiększenie zmiennej j, by wskazywała bieżącą pozycję dla następnego znaku. Jest to dokładnie równoważne z konstrukcją
if (SD] != c) {
sffl = sfi];
j-H-;
Podobny przykład znajdziemy w funkcji getline, którą napisaliśmy już w rozdz. 1. Konstrukcję
if (c == ’\n’) { s[i] = c;
++i;
75