CVIČENIE 2/13 (S7) Programovanie v jazyku C - ti to zratam... PrednaskaB: Datové typy PrednaskaZ: Výrazy a příkazy, programové konstrukce, operátory About aritmeticke operacie TODO: Declaration vs. definition deklaracia definicia Input and output nasleduje kratky vypis prikazov na pracu so vstupom a vystupom. na ich podprobnejsi popis kliknite na linku za prikazom, ktora vam ho zobrazi. putchar (popis) getchar (popis) printf (popis) scanft (popis)
- definice proměnných Pascal C VAR i: INTEGER; int i; ch: CHAR; char ch; f: REAL; double f; - přiřazení X porování Pascal C := =... přiřazení = ==... porovnání <>!= i=5 je celočíselný výraz s hodnotou 5, kterou také přiřazuje do proměnné i změní se původní hodnotu proměnné i i==5 je celočíselný výraz poskytující 1 (true), jestliže má proměnná i hodnotu 5 nebo poskytující hodnotu 0 (false), jestliže má i jinou hodnotou než 5 nezmění se původní hodnota proměnné i - booleovské výrazy Pascal C = ==... rovnost <>!=... nerovnost AND &&... logický součin OR... logický součet NOT!... negace - terminálový vstup a výstup C nedefinuje žádnou I/O operaci jako část jazyka (na rozdíl od Pascalu) nezbytné I/O jsou ve standardních knihovnách (ekvivalent unity v Pascalu) důvod: I/O jsou dosti strojově závislé a tímto se důsledně oddělují strojově závislé a nezávislé části jazyka základní I/O funkce jsou v hlavičkovém souboru stdio.h vstup a výstup znaku: getchar()... vstup znaku putchar()... výstup znaku obě funkce pracují s int a ne char (vysvětlení později)!! - při volání funkce getchar je nutné uvést závorky i když nemá žádné paramatry!! getchar;... pointer na funkci (nic neprovede) getchar();... zavolání funkce - při volání getchar() můžeme psát znaky z klávesnice tak dlouho, dokud nestisknete ENTER getchar() pak přečte první ze zadaných znaků a ostatní ignoruje
Basic knowledge operator - znak reprezentujuci operaciu operand - udajovy objekt vstupujuci do operacie vyraz - zlucenie operatorov a operandov, vysledkom je hodnota Znazornenie na priklade: y = a + b; + je operator, a a b su operandy a a+b popripade y=a+b je vyraz operatory: unarne, binarne, ternarne o unarne: s jednym operandom; + a -, specialny: ++ a -- (pred a po) priklad pouzitia: int i = 5, j = 1, k; i++; j = ++i; j = i++; k = --j + 2; o binarne: operacia s dvoma operandmi; + (scitanie), - (odcitanie), * (sucin), / (realny a celociselny podiel), % (delenie modulo - zvysok po deleni) priklad pouzitia: int i = 5, j = 13; j = j / 4; j = i % 3; o ternarny: podmieneny vyraz: podmieneny_vyraz? vyraz_1 : vyraz_2 ma vyznam: if podmieneny_vyraz then vyraz_1 else vyraz_2 priklady pouzitia: int i, k, j = 2; i = (j == 2)? 1 : 3; k = (i > j)? i : j;
Priorita vo vykonavanych operacii (vid podklady) Priradzovaci prikaz a jeho skratene tvary: a+=b a-=b a*=b a/=b a %= b a >>= b a <<= b a &= b a ^= b a = b nahradzuje a = a + b nahradzuje a = a - b nahradzuje a = a * b nahradzuje a = a / b priklad pouzitia: int i = 4, j = 3; j += i; j /= --i; j *= i - 2; Priklad: napište program, co přečte znak z klávesnice, vypíše ho a odřádkuje int main(int argc, char** argv) int c; c = getchar(); putchar(c); putchar( \n ); return 0; počet parametrů vstupu a jednotlivé parametry (více později) - hlavní program se vždy jmenuje main a musí být vždy v programu uveden - main by měl vracet typ int a tedy na konci main musí být návratová hodnota - main je obyčejná funkce a jedinou specifikou této funkce je, že se po spuštění programu volá jako první - sestává-li se program z více modulů main smí být pouze v jednom z modulů a jen jednou - základní řídící struktury IF PASCAL IF boolean_vyraz THEN prikaz1 ELSE prikaz2; C if (vyraz) prikaz1; else prikaz2; nutné závorky nutný středník
- pokud je do sebe zanořeno více if-ů, pak se else vztahuje vždy k nejbližšímu if Priklad: napište program, co přečte znak z klávesnice a pokud je to velké písmeno, vypíše ho int main(int argc, char** argv) int c; c = getchar(); if (c >= A && c<= Z ) putchar(c); return 0; - jiný zápis (využijeme skutečnost, že přiřazení je výraz) int main(int argc, char** argv) int c; if ((c = getchar()) >= A && c<= Z ) putchar(c); nutné závorky return 0; - pokud nebudou závorky if (c = getchar() >= A && c<= Z ) bude fungovat jinak, protože operátor = má nižčí prioritu než >= getchar přečte znak a porovná ho s A je-li výsledek testu logická 0 test končí a logická 0 (NE znak A ) je přiřazena do c je-li výsledek testu 1, porovnává se stále ještě nedefinovaná proměnné c se znakem Z výsledkem porovnání je opět 0 nebo 1, která se nakonec logickým součinem vynásobí s logickou hodnotou z předchozího testu podle výsledku tohoto součinu se do c dá 0 nebo 1 - C se píše často if (výraz == 0) if (!výraz) if (výraz!= 0) if (výraz) WHILE-cyklus PASCAL WHILE boolean_vyraz DO prikaz1; C while (vyraz) prikaz1; nutné závorky
- speciální unární operátory inkrement ++ dekrement -- 1. ++výraz inkremetování před použitím výraz je zvětšen o 1 a pak je nová hodnota vrácena jako hodnota výrazu 2. výraz++ inkremetování po použití je vrácena původní hodnota výrazu a pak je výraz zvětšen o 1 Priklad: zjistěte obsah proměnných i,j, k po provedení následujícího kódu int i=5; int j=1; int k; i++; // i=6 j=++i; // i=7, j=7 j=i++; // i=8, j=7 k=--j+2; // i=8, j=6, k=8 - tisk řetězce printf( %d \n,i); %d... číslo typu int %c... znak %f... double, float \n... odřádkování vypisovaná proměnná formát výpisu
Př. Vypsat text tak, aby první písmeno každého slova bylo velké a místo více mezer mezi slovy vypsat jen jednu mezeru - pomocí funkcí putchar a getchar #include <stdlib.h> int main(int argc, char** argv) char c; int je_slovo = 1; int je_prvni_pismeno = 1; while ((c=getchar())!=eof) if (c=='\n' c==' ') if (je_slovo) putchar (c); je_slovo = 0; je_prvni_pismeno = 1; else je_slovo = 1; if (je_prvni_pismeno) putchar(toupper(c)); je_prvni_pismeno = 0; else putchar(tolower(c)); return 0; // mezera mezi slovy // prvni mezera se vypise // je slovo // je prvni pismeno ve slove - velke // neni prvni pismeno ve slove - male Conversions of the different types typova konverzia - prevod premennej jedneho typu na typ iny (int->float) implicitna implicitna ma tieto pravidla: 1. ak sa objavi typ char alebo short int -> int; vsetky operandy unsigned char a unsigned short ->int (ak int ich moze reprezentovat, inac unsigned int)
2. ak maju dva operandy jednej operacie rozny typ, tak typ s nizsou prioritou sa konvertuje na typ s vyssou prioritou podla nasledujucej hierarchie (int ma najnizsiu prioritu): int => unsigned int unsigned int => long long => unsigned long unsigned long => float float => double double => long double 3. v priradzovacich vyrazoch sa typ pravej strany konvertuje na typ lavej strany, co je aj typ vysledku priklady pouzitia: char c; int i; double g; c = 1; // 1 => char (znak Ctrl A); c = chr(1); c++; // (znak Ctrl B) c = c + '1'; // hodnota '1' = 49, tak c = 2 + 49; c = ord(c) + ord('1'); i = 'A'; // A = 65 i = 'A' + 2; // 65 + 2 i = 3.8; // i = 3 g = 5; // g = 5.0 i = g * c; // najprv c => int (pravidlo 1) a potom c => double (pravidlo 2). //vysledok g * c je double, ale podla 3 sa vysledok skonvertuje na int explicitna -> explicitnu konverziu mozeme ovplyvnit - cast operator - pretypovanie - format: (typ)vyraz co znamena, ze vysledok vyrazu bude mat vysledny typ typu typ priklad pouzitia: int i = 10; double f; f = sqrt( (double)i );
Examples konverzie - z realnej matematiky do C, pri praci s matematickymi funkciami je nutne prekladat s prepinacom -lm: gcc -lm program.c Ex. 1: vycislenie vyrazu: x =7 + 3*4/6. (8+2)/-5 int main( void ) printf( "%f\n", 7.0 + 3.0*4.0/6.0*(8.0+2.0)/5.0 ); getchar(); return(0); Ex. 2: vypocitat sumu: 1 + 1/2 + 1/4 +... + 1/2^n. parameter n bude zadany zo vstupu od pouzivatela. int main( void ) int n, i; float suma=0; printf( "zadaj n: " ); scanf( "%d", &n ); for( i = 0; i <= n; i++ ) suma += 1.0/pow(2.0, (float)i); printf( "vysledok sumy je: %f\n", suma ); getchar();getchar(); return( 0 ); Ex. 3: vyjadrite priebeh funkcie: y = x^2 + 6-3/x. vypisat 10 hodnot s krokom zadanym zo vstupu. tabelovany vystup. int main( void ) int krok, i; float x; printf( "zadaj krok: " ); scanf( "%d", &krok );
x = 1.0; for( i = 1; i <= 10; i++ ) printf( "%d\t%4.3f\n", i, (float)(x*x + 6.0-3.0/x) ); x += krok; getchar();getchar(); return( 0 ); Ex. 4: vytvorte program na vypocet kvadratickej funkcie. #include <math.h> int main( void ) float a, b, c, d, x1, x2, x; printf( "zadaj A, B, C: " ); scanf( "%f%f%f", &a, &b, &c ); d = b*b - 4*a*c; if( d > 0 ) x1 = ( -b + sqrt(d) ) / (2*a); x2 = ( -b - sqrt(d) ) / (2*a); printf( "koren x1=%f\nkoren x2=%f\n", x1, x2 ); else if( d == 0 ) x = -b / (2*a); printf( "existuje jeden koren rovnice x=%f\n", x ); else printf( "neexistuje realny koren tejto rovnice\n" ); getchar();getchar(); return(0); Ex. 5: zobrazte priebeh funkcie sinus C na intervale <0, p/2> s krokom 0.1 #include <math.h> int main( void ) const float PI=3.1415; double x = 0, step = 0.1; printf( "x\ty\n" ); while( x <= PI/2 )
printf( "%1.1f\t%1.3f\n", x, sin(x) ); x += step; getchar(); return( 0 ); Homework akeho typu a co bude vysledkom nasledujucich operacii. rozpisat na drobne ako vyraz, teda: u * f = unsigned * float = float; char c = 'A'; int i = 100; unsigned u = 10; float f = 13.45; 1. c = u * f + 2.6L; 2. u += --f / u % 3; 3. u = i + 3 + 4 + 3.1; 4. u = 3.1 + i + 3 + 4; /* pokial je zaujem, tak aj toto ;) 5. c = (i << - --f) & 0xf; 6. i <<= u * - ++f; */