660 likes | 861 Views
Programování v C. Jan Kordas jan.kordas@vsb.cz D400 9. 2. 2010. Obsah cvičení. Základy algoritmizace - rozvoj "algoritmického" myšlení. Kompilátor jazyka C. Seznámení s vývojovým prostředím. První programy v jazyce C. Základní terminálový I/O.
E N D
Programování v C Jan Kordas jan.kordas@vsb.cz D400 9. 2. 2010
Obsah cvičení Základy algoritmizace - rozvoj "algoritmického" myšlení. Kompilátor jazyka C. Seznámení s vývojovým prostředím. První programy v jazyce C. Základní terminálový I/O. Terminálový vstup/výstup. Základní datové typy a konstanty. Operátory. Konverze typů. Větvení (if, ternární operátor, switch). Cykly. Příkazy break, continue. Pole. Funkce. Prototyp funkce. Hlavičkový soubor. Práce s periferiemi. Komunikace s okolním světem. Ukazatele. Struktury. Výčtový datový typ. Union. Bitová pole. Soubory. Knihovny standardních funkcí
Materiály Webové stránky ke cvičení • http://homel.vsb.cz/~kor206 Doporučená literatura • HEROUT, P.: Učebnice jazyka C • ŠALOUN, P.: Programovací jazyk C pro zelenáče • BABUŠIAK, B., GÁLA, M.: Programovací jazyk C v príkladoch pre biomedicínskych technikov
Hodnocení cvičení Miniprojekt 3x5 ............ 15 bodů (minimum 7 bodů) Písemka ...................... 10 bodů (minimum 5 bodů) Závěrečný projekt ........ 20 bodů (minimum 10 bodů) ------------------------------------------------------------------------ Celkem za zápočet ...... 45 bodů (minimum 22 bodů)
Seznámení s vývojovým prostředím • Vytvoření nového projektu • Modifikace zdrojového souboru • Uložení zdrojového souboru • Kompilace zdrojových souborů • Spuštění vytvořené aplikace • Kompilace a spuštění v jednom kroku • Ladění
Základní struktura programu v jazyce C // vložení standardního hlavičkového souboru #include <stdio.h> // vložení vlastního hlavičkového souboru #include "main.h" // vstupní bod aplikace int main(int argc, char *argv[]) { // příkazy } Komentáře // jednořádkový komentář není definová v normě ANSI C /* Víceřádkový komentář */
Proměnné Deklarace typ_proměnné identifikátor_proměnné; Globální vs. lokální proměnná int i; // globální proměnná funkce() { int j; // lokální proměnná } Počáteční inicializace int i = 5; // deklarace proměnné i a jejíinicializace na hodnotu 5 // totéž složitěji int i; // deklarace proměnné i i = 5; // nastavení proměnné i na hodnotu 5
Datové typy v jazyce C Celočíselné char (8 bitů) short (16 bitů) int (32 bitů) long (32 bitů) Reálné float (32 bitů) double (64 bitů) Výčtový enum Ukazatel pointer (32 bitů) Velikost některých datových typů je platformě závislá.
unsigned vs. signed unsigned neznaménkový datový typ unsigned char (0..255) unsigned short (0..65535) unsigned int (0..2^32-1) unsigned long(0..2^32-1) signed znaménokový datový typ signed char (-128..127) signed short (-32768..32767) signed int (-2^31..2^31-1) signed long(-2^31..2^31-1)
Konstanty Celočíselné desítkové 1, 10, 129 long 12L, -35l unsigned 33U, 12u oktálové 01, 010, 0127 hexadecimální 0x1, 0x1F, 0x12A Reálné double 1E10, 15e-1, 3.14 , .2 float 1E5F, 123ef long double 15e3L Znakové (velikost int!) 'a', '/', \007, \x1f, \n, \r, \t, \0 klíčové slovo const const int i = 15;
Operace Operátor přiřazení = Aritemetické operace +,-, *, /, % Složené operátory přiřazení +=, -=, +=, /=, %=, >>=, <<=, &=, |=, ^= Operátory inkremenace/dekrementace o jedničku ++, -- Relační operátory >, >=, <, <=, ==, != Logické operátory !, &&, || Bitové operace &, |, ^, ~, <<, >>
Priority a postup vyhodnocování výrazů http://msdn.microsoft.com/en-us/library/2bxt6kc4(VS.71).aspx
Konverze datových typů Implicitní Prováděna automaticky. Vždy se konvertuje z "nižšího" typu na "vyšší".Pořadí typů pro konverzi: int -> unsigned int -> long -> unsigned long -> double -> long double double x; int i = 5; x = i; double r; r = i * x;// hodnota proměnné i je konvertována na double Explicitní Prováděna na žádost programátora. double x = 5; int i; i = (int) x; // jedná se v podstatě o „ořezání“ desetinné části
Klíčová slova 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 Mají předem daný význam => nelze použít jako indentifikátor!
Terminálový vstup/výstup Hlavičkový soubor stdio.h #include <stdio.h> Funkce pro vstup getchar() // čte první znak, čtení se ukončístiskem Enter scanf() // formátovaný vstup Funkce pro výstup putchar() // zapíše znak printf() // formátovaný výstup
Formátovaný vstup Funkce scanf() Příklad int i; scanf("%d", &i); %d určuje formát vstupu (v tomto případě celé číslo). &i adresa proměnné, do které se má vstup uložit Pozor!!! Nazapomenout na & před názvem proměnné!!!
Formátovaný výstup Funkce printf() Příklad int i = 5; printf("i = %d", i); i = text, který se vypíše %d určuje formát výpisu (v tomto případě dekadický celočíselný) i proměnná, která se vytiskne na terminál tam, kde je %d
Formátové specifikace %c znak (je lepší použít funkci getchar() nebo putchar()) %d celé číslo typu signed int %ld celé číslo typu signed long %u celé číslo typu unsigned int %lu celé číslo typu unsigned long %f reálné číslo typu float %lf reálné číslo typu double %Lf reálné číslo typu long double (L musí být velké) %x číslo v hexadecimálním tvaru s malými písmeny - 5b8f %X číslo v hexadecimálním tvaru s velkými písmeny - 5B8F %o číslo v osmičkovém tvaru %s řetězec
Escape sekvence \0 Nula, ukončení řetězce (má být na konci každého řetězce) \a Pípnutí \b Návrat o jeden znak zpět \f Nová stránka nebo obrazovka \n Přesun na začátek nového řádku \r Přesun na začátek aktuálního řádku \t Přesun na následující tabelační pozici \v Stanovený přesun dolů \\ Obrácené lomítko \' Apostrof \" Uvozovky \? Otazník
Větvení - příkaz if Úplná podmínka if (výraz) { // příkazy, které se provedou, když je výraz <> 0 } else { // příkazy, které se provedou, když je výraz == 0 } Neúplná podmínka if (výraz) { // příkazy, které se provedou, když je výraz <> 0 }
Ternární operátor Syntaxe výraz_podmínka ? výraz1 : výraz2 Příklad x = (a < b) ? a : b; Totéž pomocí if if (a < b) x = a; else x = b;
Výběr z více alternativ - příkaz switch Syntaxe switch (výraz) { case x : // příkazy, které se provedou, když výraz == x break; case y : break; case l: case k: // příkazy, které se provedou, když výraz ==l || výraz == k break; ... default : /* příkazy, které se provedeou, pokud neodpovídá anijedna z předchozích variat */ }
Cyklus - příkaz for Syntaxe for ( inicializace; podmínka; přízak(y)) { // tělo cyklu } Příklad int i; for (i = 0; i < 10; i++) { printf("Ahoj svete %d\n", i); }
Cyklus - příkaz do Syntaxe do { // tělo cyklu } while (podmínka); Příkazy v těle cyklu jsou prováděny, když je splněna podmínka na konci (za tělem). => Tělo cyklu je provedeno minimálně 1x!
Cyklus - příkaz while Syntaxe while (podmínka) { // tělo cyklu } Příkazy v těle cyklu jsou prováděny, když je splněna podmínka nazačátku. => Tělo cyklu se nemusí provést vůbec!
Příkaz continue Příklad int i = 0; while (i < 5) { i++; if ((i % 2) == 0) printf("%d je sude", i); else continue; // skok na začátek cyklu printf("\n"); }
Příkaz break Příklad int i = 0; while (i < 5) { i++; if ((i % 2) == 0) printf("%d je sude", i); else break; // skok z cyklu ven printf("\n"); }
Příkaz goto for (i = 0; i < 10; i++) { for (j = 0; j < 10; j++) { if (d[j] == 0) goto chyba; else r[i]+= 1 / d[j]; } } goto bez_chyby; chyba: printf("Deleni nulou\n"); bez_chyby: Pokud možno nepoužívat! Problém je vždy možné vyřešit bez tohotopříkazu!!!
Bloky { // začátek bloku // tělo bloku = příkazy, definice proměnných } // konec bloku Nutnost použití bloků u if, do, while, pokud tělo bloku obsahuje více než jeden příkaz. if (i == 1) printf("jen jeden příkaz") if (i == 10) { printf("první příkaz"); printf("druhý příkaz"); }
Viditelnost proměnných int a = 4; // globální proměnná void main() { printf("a = %d\n", a);/* lokální proměnná, překrývá dříve deklarovanou proměnnou se stejným názvem */ int a = 5; printf("a = %d\n", a); { int j; // proměnná je "vidět" jen v rámcibloku } }
Deklarace proměnných - chyba int a = 4; // globální proměnná void main() { printf("a = %d\n", a);/* lokální proměnná, překrývá proměnné se stejným názvem deklarované v nadřazených úrovních */ int a = 5; printf("a = %d\n", a); // opětovná deklarace v rámci stejného bloku!!! int a = 6; printf("a = %d\n", a); }
Funkce návratový_typ identifikátor_funkce(parametry_funkce) { // tělo funkce return výraz; // výraz je typu návratový_typ } Příkaz return ukončí provádění funkce. Nemusí být až na jejím konci. Když je návratový typ funkce void, příkaz return neobsahuje žádnývýraz.
Volání funkcí Volání funkce hodnotou // funkce se volá secti (5, 3); int secti(int a, int b) { return (a+b); } Volání funkce odkazem // funkce se vola prohod(&x, &y); void prohod(int *a, int *b) { int pom = *b; *b = *a; *a = pom; }
Prototyp funkce Příklad int soucet(int a, int b); // prototyp funkce int main() { int a, b; scanf("%d%d", &a, &b); printf("%d + %d = %d\n", a, b, soucet(a, b)); } int soucet(int a, int b) { return a + b; }
Operátor čárka Nejprve je vyhodnocen výraz vlevo od čárky, následně je vyhodnecenvýraz vpravo od čárky. Syntaxe výraz: výraz1, výraz2 Příklad 1 (nejčastější použití) for (i = 0, j = 0; i < 5; i++, j++) { //... } Příklad 2 int a, b = 1, c = 2; a = (b++, b + c);
Pole – statická – jednorozměrná Syntaxe datovy_typ identifikator_pole[pocet_prvku_pole]; datovy_typ identifikator_pole[pocet_prvku_pole] = {p0, p1, ...}; Příklad 1 (práce s polem) int pole[3]; int i; for (i = 0; i < 3; i++) { printf(“zadej %d. cislo: “, i); scanf(“%d”, &pole[i]); } for (i = 0; i < 3; i++) { printf(“%d. cislo: %d\n”, i, pole[i]); } Příklad 2 (pole jako argument funkce) int minimum(int pole[], int pocet) { // vypocet minima... }
Pole – statická – vícerozměrná Syntaxe datovy_typ identifikator[pocet_prvku1][pocet_prvku2] datovy_typ identifikator[pocet_prvku1][pocet_prvku2] = {{p00},{},...} Příklad 1 (inicializace) int matice[3][2] = {{1,2}, {3,4}, {5,6}}; Příklad 2 (přístup k prvkům pole) int matice[3][2]; matice[0][0] = 1; matice[0][1] = 2; matice[1][0] = 3; matice[1][1] = 4; matice[2][0] = 5; matice[2][1] = 6;
Řetězce Jednorozměrné pole typu char[] ukončené znakem '\0'! Deklarace char retezec[10]; Inicializace char retezec[10] = "ahoj"; char retezec2[] = "ahoj"; Příklad 1 char retezec[10] = "ahoj", retezec2; printf("%d", retezec[0]); printf("%d", retezec[1]); printf("%d", retezec[2]); printf("%d", retezec[3]); printf("%d", retezec[4]); printf("%s", retezec); scanf("%s", retezec2); printf("%s", retezec2);
Standardní funkce pro práci s řetězci Hlavičkový soubror <string.h> Délka řetězce strlen(); Kopírování řetězce strcpy(); Spojení řetězců strcat(); Nalezení znaku v řetězci strchr(); Porovnání dvou řetězců strcmp(); Nalezení pořetězce v řetězci strstr();
Ukazatele (Pointery) Příklad int i = 5; int *p_i; p_i = &i; printf("adr. &i=%p, &p_i=%p,p_i=%p\n",&i,&p_i,p_i); printf("hodnoty i=%d, p_i=%d\n", i, *p_i); i++; printf("hodnoty i=%d, p_i=%d\n", i, *p_i); (*p_i)++; printf("hodnoty i=%d, p_i=%d\n", i, *p_i); *p_i = 11; printf("hodnoty i=%d, p_i=%d\n", i, *p_i);
Pointerová aritmetika Příklad int a[5] = {1,2,3,4,5}; int *p = a; // totez co int *p = &a a int *p = &a[0] printf("adr. &a=%p, a=%p, &p=%p, p=%p\n", &a, a, &p, p); printf("hodnoty a[0]=%d, *p=%d\n", a[0], *p); printf("hodnoty a[1]=%d, *(p+1)=%d\n", a[1], *(p+1)); printf("hodnoty a[4]=%d, *(p+4)=%d\n", a[4], *(p+4)); p = p + 3; printf("adr. &a[3]=%p, &p=%p, p=%p\n", &a[3], &p, p); printf("hodnoty *p=%d\n", *p); p--; printf("hodnoty a[2]=%d, *p=%d\n", a[2], *p); *p = 50; printf("hodnoty a[2]=%d, *p=%d\n", a[2], *p); *(p+1) = 44; printf("hodnoty a[3]=%d, *(p+1)=%d\n", a[3], *(p+1));
Pointery jako argumenty funkcí Příklad na prohození dvou čísel int prohod(int *a, int *b) { int pom = *a; *a = *b; *b = pom; }
Ukazatel na funkce Příklad int soucet(int a, int b) { return a + b; } int rozdil(int a, int b) { return a - b; } void main() { int (*p_f)(int a, int b); p_f = soucet; printf("%d\n", p_f(1, 2)); p_f = rozdil; printf("%d\n", p_f(1, 2)); }
Argumenty programu Vstupní bod aplikace: int main(int argc, char *argv[]) argc– počet argumentů (název programu je taky argument) arg[] –ukazatelna pole argumentů arg[0]– název programu arg[1] – 1. argument programu Příklad int main(int argc, char *argv[]) { int i; printf(“Pocet argumentu: %d”, argc); for (i = 0; i < argc; i++) printf(“Argument %d: %s”, i, argv[i]); return 0; }
Definice typů - typedef • Pro definici/pojmenování nových typů – pointery typedef int *P_INT; P_INT p_int; • Pro definici/pojmenování nových typů – struktury (viz dále) Přiklad (pointer na pointer) typedef int *P_INT; typedef P_INT *P_P_INT; P_P_INT p_p_i; //totez znamym zpusobem int **p_p_int;
Struktury • Definice struktury a proměnných jirka, alois struct { char jmeno[10]; char prijmeni[20]; int vek; } jirka, alois; • Definice pojmenované struktury a proměnných jirka, alois struct osoba{ char jmeno[10]; char prijmeni[20]; int vek; } jirka, alois;
Struktury • Definice struktury a následná deklarace proměnných jirka, alois struct osoba { char jmeno[10]; char prijmeni[20]; int vek; }; struct osoba jirka, alois; • Definice nového typu a proměnných jirka, alois tohoto typu typedef struct { char jmeno[10]; char prijmeni[20]; int vek; } OSOBA; OSOBA jirka, alois;
Struktury – příklad Příklad typedef struct { char jmeno[10]; char prijmeni[20]; int vek; } OSOBA; OSOBA osoby[10]; void main() { printf(“Zadejete jmeno 1. osoby: ”); scanf(“%s”, &osoby[0].jmeno); printf(“Zadejete prijmeni 1. osoby: ”); scanf(“%s”, &osoby[0].prijmeni); printf(“Zadejete vek 1. osoby: ”); scanf(“%d”, &osoby[0].vek); printf(“Osoba 1: %s %s (%d)”, osoby[0].jmeno, osoby[0].prijmeni, osoby[0].vek); }
Výčtový datový typ – enum Příklad typedef enum { MODRA, BILA, ZLUTA, CERVENA, HNEDA } BARVY; BARVY barva = MODRA; char *nazvy[] = {”Modra”, ”Bila”, ”Zluta”, ”Cervena”, ”Hneda” }; printf(”Vybrana barva %s\n”, nazvy[barva]); Přiřazení hodnot konstantám typedef enum { MODRA = 5, BILA = 2, ZLUTA = 7, } BARVY;