J ZYK C: STAŁE I ZMIENNE, TYPY DANYCH, OPERATORY I WYRA ENIA ARYTMETYCZNE Przykład (program zamieniaj cy temperatur podan w skali Fahrenheita na temperatur w skali Celsjusza) Jak ma działa program? 1. U ytkownik podaje temperatur w skali Fahrenheita. 2. Program oblicza temperatur w skali Celsjusza według wzoru: c = (5/9)(f-32). 3. Program wy wietla obliczon temperatur w skali Celsjusza. W programie b d wyst powały dwie warto ci (temperatura w skali Fahrenheita i temperatura w skali Celsjusza) zatem musimy wprowadzi dwie zmienne. 1 #include <stdio.h> int main() { float tempf; /* temp. w skali Fahrenheita */ 2 float tempc; /* temp. w skali Celsjusza */ 3 4 5 6 printf( Podaj temperature w skali Fahrenheita: ); scanf( %f,&tempf); tempc=5*(tempf-32)/9; printf( Temperatura w skali Celsjusza to %f\n,tempc); } return (0); 1 - Doł czenie pliku nagłówkowego stdio.h zawieraj cego opis funkcji printf i scanf. 2 - Deklaracja dwóch zmiennych: tempf i tempc b d cych liczbami rzeczywistymi (typ float). 3 - Wy wietlenie napisu: Podaj temperature... bez znaku \n na ko cu. 4 - Wczytanie temperatury w skali Fahrenheita: tempf &tempf - nazwa zmiennej, - adres zmiennej (funkcja scanf wymaga podania adresu zmiennej, a nie jej nazwy), %f - okre la typ wczytywanej zmiennej (%f - typ float). 5 - Obliczenie warto ci wyra enia arytmetycznego. 6 - Wy wietlenie wyniku, ła cucha znaków Temperatura w skali... i warto ci zmiennej tempc. W miejscu, w którym ma by wy wietlona warto zmiennej podajemy specyfikator formatu - %f, b dzie on zast piony podczas wy wietlania warto ci zmiennej, której nazw podajemy po cudzysłowie ko cz cym ła cuch znaków i po przecinku. Strona 1 z 10
Zmienne Zmienne słu do reprezentacji (przechowywania) warto ci danych. Zbiór warto ci jakie mog przyjmowa zmienne nazywa si typem (np. liczby całkowite, rzeczywiste). Zmienne przechowywane s w pami ci komputera wi c ka da z nich poza nazw ma adres (komputer nie posługuje si nazwami tylko adresami zmiennych). Przed wykorzystaniem zmiennej w programie trzeba j wcze niej zadeklarowa czyli poda jej nazw i typ. Zmienne najcz ciej deklaruje si na pocz tku funkcji, w której wyst puj (s to tzw. zmienne lokalne). Deklaracje zmiennych int a; rednik nazwa zmiennej nazwa typu int a; float b,c; float d; /* zmienna d */ float e; /* zmienna e */ Deklaracja zmiennej składa si z typu zmiennej i jej nazwy. Na ko cu deklaracji stawia si rednik. Gdy jest kilka zmiennych tego samego typu, to mo na je deklarowa po przecinku (np. float b,c;). Umieszczenie deklaracji ka dej zmiennej w oddzielnej linii jest wygodne, gdy przy ka dej deklaracji dodajemy komentarz: /* tekst komentarza */. Podstawowe typy zmiennych Nazwa typu Zakres warto ci danych Rozmiar (bajty) Uwagi char -128... 127 1 małe liczby całkowite, znaki ASCII int -32768 32767 * -2147483648... 2147483647 ** 2 * / 4 ** liczby całkowite float -3,4 10-38 3,4 10 38 4 liczby rzeczywiste, 7 cyfr znacz cych double -1,7 10-308 1,7 10 308 8 liczby rzeczywiste, 15 cyfr znacz cych void - - oznacza brak warto ci Dodatkowo istniej cztery słowa kluczowe modyfikuj ce powy sze typy. Dla liczb całkowitych: signed, unsigned - okre la czy zmienna ma by ze znakiem czy bez, short, long - dla typu int oznacza krótk lub długa liczb całkowit. Dla liczb rzeczywistych: long - dla typu double pozwala zwi kszy precyzj (liczb miejsc po przecinku). Strona 2 z 10
Wszystkie typy zmiennych Nazwa typu Zakres warto ci danych Rozmiar (bajty) Uwagi signed char = char -128... 127 1 liczby całkowite unsigned char 0 255 1 liczby całkowite signed int = int -32768 32767 2 * liczby całkowite unsigned = unsigned int 0 65535 2 * liczby całkowite short = signed short int -32768 32767 2 liczby całkowite short unsigned = unsigned short int 0 65535 2 liczby całkowite long = signed long int -2147483648 2147483647 4 liczby całkowite long unsigned = unsigned long int 0 4294967295 4 liczby całkowite float -3,4 10-38 3,4 10 38 4 7 cyfr znacz cych double -1,7 10-308 1,7 10 308 8 15 cyfr znacz cych long double 3,4 10-4932 1,1 10 4932 10 * 19 cyfr znacz cych Powy sze zakresy i rozmiary podane s dla kompilatora Borland C++ 3.1. Zale nie od kompilatora mog wyst pi ró nice w rozmiarze zmiennych typu int i long double: Kompilator int long double Borland C++ 3.1 2 10 Dev-C++ 4 12 Microsoft Visual C++ 6.0 4 8 Borland C++ Builder 6 4 10 Rozmiar poszczególnych typów mo na sprawdzi wykorzystuj c operator sizeof: sizeof(nazwa_typu) zwraca liczb bajtów zajmowanych przez pojedyncz zmienn podanego typu. Zamiast nazwy typu mo na poda nazw zmiennej i wtedy operator ten zwróci liczb bajtów zajmowanych przez zmienn. Nazwy zmiennych Nazwa zmiennej mo e składa si z liter i cyfr (A-Z, a-z, 0-9). Pierwszym znakiem nazwy musi by litera. Znak podkre lenia traktowany jest jak litera. Nie zaleca si rozpoczynania nazwy zmiennej od znaku podkre lenia, gdy takie nazwy cz sto wyst puj w programach bibliotecznych. W nazwach zmiennych nie stosuje si znaków spacji. Przyj ło si, e nazwy zmiennych pisze si małymi literami, a nazwy stałych - du ymi. Strona 3 z 10
Nazwa zmiennej powinna by zwi zana z jej zawarto ci. Długo nazwy nie jest ograniczona, ale rozró nialne jest 31 pierwszych znaków. Jako nazw zmiennych nie mo na stosowa słów kluczowych j zyka C (32 słowa): auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while Stałe liczbowe Typ liczby zale ny jest od formy zapisu i warto ci liczby. Liczby całkowite 1 25000 39000 4100000000 - stała całkowita typu int - stała całkowita typu int - stała całkowita typu int (4 bajty) lub long - stała typu unsigned long int (bo przekracza typ long) u lub U dodane na ko cu liczby zmienia typ na unsigned (int lub long), l lub L dodane na ko cu liczby zmienia typ na long (int lub unsigned int), 5U 5L 10ul - stała całkowita typu unsigned int - stała całkowita typu long - stała całkowita typu unsigned long liczby w systemie ósemkowym zaczynaj si od 0 (zera), liczby w systemie szesnastkowym zaczynaj si od 0x lub 0X 011 0x11-11 w systemie ósemkowym to 9 w systemie dziesi tnym - 11 w systemie szesnastkowym to 17 w systemie dziesi tnym Liczby rzeczywiste 1.0 - stała rzeczywista typu double 1.312e2 - stała rzeczywista typu double (1,312 10 2 ) -2.124E-1 - stała rzeczywista typu double (-2,124 10-1 ) l lub L dodane na ko cu liczby zmienia typ na long double, f lub F dodane na ko cu liczby zmienia typ na float, 2.5L 4.52 4.52f - stała rzeczywista typu long double - stała rzeczywista typu double - stała rzeczywista typu float Strona 4 z 10
Operatory arytmetyczne jednoargumentowe: + (plus) - (minus) dwuargumentowe: * / % + - - jako znak liczby (zazwyczaj jest pomijany) - jako znak liczby - mno enie - dzielenie (dla liczb całkowitych obcina cz ułamkow ) - dzielenie modulo (reszta z dzielenia, stosowane tylko dla typów całkowitych) - dodawanie - odejmowanie Operator przypisania Operator przypisania = (znak równo ci) stosowany jest do nadania warto ci zmiennej. Wyra enie: a = 10; powinno by interpretowane jako: we warto numeryczn 10 i umie j w pami ci w miejscu skojarzonym ze zmienn a. Operatora przypisania nie nale y kojarzy ze znakiem równo ci. Zapis: a = a + 10; matematycznie nie jest poprawny. W programie w j zyku C nale y interpretowa go jako: we warto znajduj c si w pami ci w miejscu skojarzonym ze zmienn a, dodaj do tej warto ci liczb 10 i otrzymany wynik umie z powrotem w pami ci w miejscu skojarzonym ze zmienn a. W j zyku C prawidłowy jest tak e poni szy zapis: a = b = c = d + 10; oznacza on: we warto zmiennej d dodaj do niej 10, otrzyman warto przypisz zmiennej c, nast pnie zmiennej b przypisz warto zmiennej c, a zmiennej a przypisz warto zmiennej b. Priorytet operatorów arytmetycznych Priorytet operatorów okre la kolejno wykonywania działa. Zastosowanie nawiasów zmienia priorytet operatorów. Wszystkie poni sze operatory s lewostronnie ł czne. Oznacza to, e je li obok siebie wyst puj dwa operatory o takim samym priorytecie, to jako pierwsze działanie wykonywane jest to znajduj ce si po lewej stronie, np.: z = a * b * c; - jako pierwsze zostanie wykonane mno enie a * b. Najwy szy + - (jednoargumentowe) Najni szy * / % + - (dwuargumentowe) UWAGA: Je li nie jeste my pewni kolejno ci wykonywania działa zawsze u ywajmy dodatkowych nawiasów. Strona 5 z 10
Wyra enia arytmetyczne Ka de wyra enie arytmetyczne ma warto i typ. Przykład: Rozpatrzmy obliczanie warto ci wyra enia arytmetycznego w przykładzie z poprzedniego wykładu. tempc = 5 * (tempf - 32) / 9; tempc - zmienna typu float, tempf - zmienna typu float, 5 - liczba typu int, 32 - liczba typu int, 9 - liczba typu int, Czy wszystko b dzie w porz dku skoro mamy zmienne typu float i stałe liczbowe typu int? TAK, gdy podczas obliczania warto ci tego wyra enia nast puje konwersja typów. Je li podczas obliczania warto ci wyra enia: x operator y wyst puje niezgodno typów, to nast puje automatyczna ich konwersja. Jest ona niezauwa alna dla programisty, ale trzeba mie wiadomo, e wyst puje. Konwersja typów przebiega w nast puj cy sposób: 1. Typy char, short, signed char, unsigned char zamieniane s na int. 2. Je li po powy szej konwersji dalej wyst puje niezgodno typów, to typ ni szy zamienia si na typ wy szy zgodnie z hierarchi typów: int < unsigned < long < unsigned long < float < double < long double Kolejno wykonywania operacji w powy szym przykładzie: tempc = 5 * (tempf - 32) / 9; A = tempf - 32 B = 5 * A C = B / 9 tempc = C Rozpatrzmy poni szy zapis: tempc = (5 / 9) * (tempf - 32); A1 = (5 / 9) A2 = (tempf - 32) B = A1 * A2 tempc = B typ wyniku: int (!!!!) W powy szym przykładzie nie mo na okre li kolejno ci obliczenia wyra e A1 i A2 - jest ona zale na od zastosowanego kompilatora. Dzielenie: 5 / 9 jest wykonywane na liczbach całkowitych, zatem i wynik jest całkowity (w tym przypadku b dzie to 0). Taki zapis wyra enia arytmetycznego jest niepoprawny, gdy w wyniku zawsze otrzymamy tempc = 0. Wyra enie to mo na zapisa w inny sposób: tempc = (5.0 / 9) * (tempf - 32); lub tempc = (5 / 9.0) * (tempf - 32); Strona 6 z 10
W ten sposób liczba zapisana z kropk i zerem b dzie traktowana jako stała liczbowa typu double i wynik wyra enia b dzie prawidłowy. Rzutowanie Jeszcze inna mo liwo prawidłowego zapisu wyra enia polega na wykorzystaniu tzw. rzutowania czyli zmiany typu wyra enia: (typ) wyra enie np. tempc = ((float) 5 / 9) * (tempf - 32); - stała liczbowa 5 b dzie traktowana jako typ float. Przykład (przelicznik walut) #include <stdio.h> #define USD 2.3028 #define EUR 3.5458 int main() { float pln,usd,eur; } printf("podaj kwote w PLN: "); scanf("%f",&pln); usd=pln/usd; eur=pln/eur; printf("%.2f PLN to %.2f USD\n",pln,usd); printf("%.2f PLN to %.2f EUR\n",pln,eur); return 0; #define - dyrektywa preprocesora okre laj ca wyra enie stałe. Jest to wyra enie, w którym wyst puj wył cznie stałe (USD - nazwa wyra enia, 3.3922 - warto wyra enia). Wyra enia stałe s obliczane na etapie kompilacji programu, a nie podczas jego wykonania. Wsz dzie w programie, gdzie wyst puj stała USD, podczas kompilacji zostanie wstawiona liczba 3.3922. Wyra enia stałe pisze si zazwyczaj du ymi literami. UWAGA: wszystkie dyrektywy preprocesora rozpoczynaj si od znaku #, który musi by umieszczony w pierwszej kolumnie (nie mog wyst powa przed nim adne spacje ani inne znaki). Strona 7 z 10
Funkcja printf printf( tekst opcjonalny + specyfikator,argumenty); Funkcja printf wyprowadza tekst. Gdy w tek cie wyst puje specyfikator (specyfikator formatu) zaczynaj cy si od %, to nast puje przekształcenie - w miejsce specyfikatora wstawiana jest warto argumentu. Specyfikator formatu okre la typ oraz sposób wy wietlania zmiennej na ekranie. Liczba specyfikatorów formatu musi by zgodna z liczb argumentów. Je li typ argumentu zostanie bł dnie okre lony to na ekranie wy wietlona zostanie nieprawidłowa warto. specyfikator = %[znacznik][szeroko [znacznik] ][.precyzja][modyfikator]typ - + - przed liczb stawiany jest znak (plus lub minus), - - wyrównanie wy wietlanych znaków do lewej strony, [szeroko ] - okre la minimaln liczb wyprowadzanych znaków, je li znaków jest mniej to pole jest z lewej strony uzupełniane spacjami, je li wi cej - podana szeroko jest ignorowana, [.precyzja] typ [modyfikator] - liczba znaków po kropce dziesi tnej, - okre la rodzaj i typ argumentu: d, i - liczba całkowita ze znakiem, dziesi tna, u - liczba całkowita bez znaku, dziesi tna, x, X - liczba całkowita bez znaku, szesnastkowa, o - liczba całkowita bez znaku, ósemkowa, f - liczba rzeczywista w postaci [-]ddd.ddd, e, E - liczba rzeczywista w formacie naukowym (z u yciem e lub E), g - liczba rzeczywista (format f lub e), s - ci g znaków, c - pojedynczy znak. - słu y do zmodyfikowania podstawowego typu podawanego przez znak typu: l L - stosowany tylko do liczb całkowitych do wy wietlania warto ci typu long (mo e sta przed d, i, o, u, x, X, o, np. %ld, %li), - stosowany do wy wietlania warto ci rzeczywistych long double. Przykłady: (Uwaga: Symbolem oznaczone s spacje) int i=15, j=-30; float x=15.1234567; double y=1.456e-2; char text[10]="napis"; printf("%d %d %f %e",i,j,x,y); printf("%f %e",x,x); printf("%f %e",y,y); Strona 8 z 10 15 30 15.123457 1.456000e-002 15.123457 1.512346e+001 0.014560 1.456000e-002 printf("%5d %+5d %-5d",i,i,i); 15 +15 15 printf("%.2f %1.5f",x,x); 15.12 15.12346 printf("x = %1.3f, y = 1.3f",x,y); x = 15.123, y = 1.3f printf( %10.3f,x); 15.123 printf("tekst: %s",text); Tekst: Napis printf("\\ \' \" \? %%\n"); \ ' "? %
Funkcja scanf scanf( specyfikator,argumenty); Funkcja scanf wczytuje znaki ze standardowego wej cia (klawiatura), interpretuje je zgodnie z zadanym specyfikatorem (specyfikatorem formatu) i przypisuje wyniki argumentom w odpowiedniej kolejno ci. specyfikator = %[szeroko ][modyfikator]typ [szeroko ] - okre la ile znaków zostanie przeczytanych, typ [modyfikator] - okre la rodzaj i typ argumentu: d - liczba całkowita dziesi tna, typ int, D - liczba całkowita dziesi tna, typ long, o - liczba całkowita ósemkowa, typ int, O - liczba całkowita ósemkowa, typ long, x - liczba całkowita szesnastkowa, typ int, X - liczba całkowita szesnastkowa, typ long, i - liczba całkowita dziesi tna, ósemkowa lub szesnastkowa, typ int, I - liczba całkowita dziesi tna, ósemkowa lub szesnastkowa, typ long, u - liczba całkowita dziesi tna bez znaku, typ unsigned, U - liczba całkowita dziesi tna bez znaku, typ unsigned long, f, e, E - liczba rzeczywista, typ float, g, G - liczba rzeczywista, typ float, s - ci g znaków, c - pojedynczy znak, typ char. - słu y do zmodyfikowania podstawowego typu podawanego przez znak typu: l L h - zmienia wszystkie typy całkowitoliczbowe na ich długie wersje; zastosowany do znaków typu f, e, E, g, G spowoduje interpretacj zawarto ci pól wej ciowych jako liczb typ double, - zastosowany do znaków typu f, e, E, g, G spowoduje interpretacj zawarto ci pól wej ciowych jako liczb typ long double, - typy całkowitoliczbowe b d traktowane jako short. Argumenty funkcji scanf s adresami obszarów w pami ci, dlatego te musz by poprzedzone znakiem & (nie dotyczy ci gu znaków). Przykłady: int a,b,c; float x,z; double y; char text[10]; scanf( %d %d %d,&a,&b,&c); Strona 9 z 10 15 20-30<enter> lub 15 20-30 <enter> lub 15<enter> 20<enter> -30<enter>
scanf( %d %f %lf,&a,&x,&y); scanf( %f %e %le,&x,&z,&y); scanf( %s,text); 15 1.51-12.467<enter> 12.1 1.45e-2 1.34e5<enter> napis<enter> Funkcje matematyczne (moduł <math.h>) Funkcja Prototyp Opis abs() int abs(int x); x - warto bezwzgl dna (liczby całkowitej) acos() double acos(double x); arcus cosinus, zwraca k t w radianach asin() double asin(double x); arcus sinus, zwraca k t w radianach atan() double atan(double x); arcus tangens, zwraca k t w radianach ceil() double ceil(double x); zaokr glenie argumentu w gór cos() double cos(double x); cosinus k ta podanego w radianach cosh() double cosh(double x); cosinus hiperboliczny k ta podanego w radianach exp() double exp(double x); e x - udost pnia liczb e do pot gi x fabs() double fabs(double x); x - warto bezwzgl dna (liczby rzeczywistej) floor() double floor(double x); zaokr glenie argumentu w dół log() double log(double x); ln x - oblicza logarytm naturalny argumentu x log10() double log10(double x); log x - oblicza logarytm dziesi tny argumentu x pow() double pow(double x, double y); x y - oblicza x do pot gi y sin() double sin(double x); sinus k ta podanego w radianach sinh() double sinh(double x); sinus hiperboliczny k ta podanego w radianach sqrt() double sqrt(double x); x - pierwiastek kwadratowy argumentu x tan() double tan(double x); tangens kata podanego w radianach tanh() double tanh(double x); tangens hiperboliczny kata podanego w radianach Stałe w module <math.h>: M_E 2.7182818284590452354 M_PI 3.14159265358979323846 M_SQRT2 1.41421356237309504880 Strona 10 z 10