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 = == <> != AND && OR || NOT !
... rovnost ... nerovnost ... logický součin ... logický součet ... 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 #include <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 nahradzuje nahradzuje nahradzuje
a a a a
= = = =
a a a a
+ * /
b b b 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 #include <stdio.h> int main(int argc, char** argv) počet parametrů vstupu a jednotlivé parametry { (více později) int c; c = getchar(); putchar(c); putchar(‘\n’); return 0; } - 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 #include <stdio.h> 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) #include <stdio.h> 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 C WHILE boolean_vyraz DO prikaz1;
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);
vypisovaná proměnná formát výpisu
%d ... číslo typu int %c ... znak %f ... double, float \n ... odřádkování
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 <stdio.h> #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)); }
// mezera mezi slovy // prvni mezera se vypise
// je slovo // je prvni pismeno ve slove - velke
// neni prvni pismeno ve slove - male
} return 0; }
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 #include <stdio.h> 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. #include <stdio.h> 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. #include <stdio.h> 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 <stdio.h> #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 if( d > { x1 = x2 =
- 4*a*c; 0 ) ( -b + sqrt(d) ) / (2*a); ( -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 <stdio.h> #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. 2. 3. 4.
c u u u
= u * f + 2.6L; += --f / u % 3; = i + 3 + 4 + 3.1; = 3.1 + i + 3 + 4;
/* pokial je zaujem, tak aj toto ;) 5. c = (i << - --f) & 0xf; 6. i <<= u * - ++f; */