Úvod do předmětu Cíle předmětu: programování v C na vyšší úrovni základy objektově orientovaného programovaní v (C++, C#) Náplň předmětu 1. Bitové operace, rekuze, paměťové třídy a typové modifikátory 2. Pointery, pole a pointery, pointerová aritmetika, funkce pro práci s řetězci, pointery na funkce 3. Struktury, uniony principy, použití, zapouzdření dat 4. Velké projekty v C překlad programů z více souborů, hlavičkové soubory, ochrana dat, knihovny funkcí 5. Dynamická alokace paměti, program v paměti počítače heap, zásobník 6. Datové struktury spojový seznam, zásobník, fronta. Principy, využití, různé způsoby implementace. Další datové struktury hash tabulky, binární stromy 7. Přechod k OOP od C k C++, úvod do tříd, tvorba vlastních objektů, konstruktory a destruktory úvod 8. Neobjektové C++ I/O systém, odlišnosti od C. Dynamická alokace paměti (new, delete). Přetěžování funkcí. 9. Dědičnost, kopírovací konstruktory, přetěžování operátorů. 10. Ošetřování chyb programech, techniky ladění, výjimky v C++. 11. Dynamická identifikace typů, operátory přetypování, prostory jmen 12. Virtuální funkce, přetěžování operátorů 13. Šablony, Knihovna STL vektory, řetězce, datové struktury 14. Jazyk C# úvod do platformy.net, odlišnost od C++ Literatura doporučená Záznamy přednášek Herout P.: Učebnice jazyka C, Nakladatelství KOPP, 2004, IV. přepracované vydání Archem, T.: Myslíme v jazyku C#, Grada Publishing, Praha 2000, ISBN 80-247-0301-7 Literatura doplňková Schildt, H.:Nauč se sám C++, SoftPress, 2001, ISBN: 80-86497-13-5 Prata, S.: Mistrovství v C++, 2. aktualizované vydání, Computer Press, Praha 2004, ISBN 80-251-0098-7 Eckel, B.: Myslíme v jazyku C++, Grada Publishing, Praha 2000, ISBN 80-247-9009-2 Eckel, B.: Myslíme v jazyku C++ 2.díl - knihovna zkušeného programátora, Grada Publishing, Praha 2005, 80-247-1015-3 Robinson, S.: C# Programujeme profesionálně, Computer Press, 2004, ISBN 80-251- 0085-5 1
Změny a novinky Deklarace vs. definice Minulý semestr int Promenna; int Funkce(int Argument); int Funkce(int Argument) return 2*Argument; // deklarace promenne // deklarace funkce // definice funkce Nově sjednocení terminologie proměnná záměna definice a deklarace int Promenna; // definice promenne int Funkce(int Argument); // deklarace funkce int Funkce(int Argument) // definice funkce return 2*Argument; Pravidla pro vytváření identifikátorů možnosti o jak nás napadne o systém vlastní tovární Maďarská notace, Pascal and Camel casing Maďarská notace o podrobně na http://msdn.microsoft.com/library/default.asp?url=/library/enus/dnvs600/html/hunganotat.asp o Dnes relativně zastaralé, použito např. v Microsoft Win32 SDK o Princip: před název proměnné údaj o jejím typu o příklady: f Flag (Boolean, logical). If qualifier is used, it should describe the true state of the flag. w Word with arbitrary contents. ch Character, usually in ASCII text. p Pointer sz Pointer to first character of a zero terminated string. st Pointer to a string. First byte is the count of characters cch. h pp (in heap). #include "sy.h" extern int *rgwdic; extern int bsymac; struct SY *PsySz(char sz[]); char *pch; int cch; struct SY *psy, *PsyCreate(); int *pbsy; int cwsz; unsigned whash=0; pch=sz; while (*pch!=0 2
whash=(whash<>11+*pch++; cch=pch-sz; pbsy=&rgbsyhash[(whash&077777)%cwhash]; for (; *pbsy!=0; pbsy = &psy->bsynext) Pascal a Camel casing o podrobně na http://msdn.microsoft.com/library/default.asp?url=/library/enus/vsent7/html/vxconcodingtechniques.asp o Moderní použito Java, C# o Pascal casing složeniny, první písmena slov velká NejakyDlouhyIdentifikator o Camel casing jako pascal, ale malé první pípmeno nejakydlouhyidentifikator o V C# knihovnách: funkce pascal casing proměnné camel casing Ideální v C, C++ = kombinace o prefixy proměnných f logická proměnná p pointer sz řetězec ( zero terminated ) o dále identifikátory jako v C# knihovnách Řešené příklady na přednáškách příklady označené # budou přednášejícím celé řešeny přímo během přednášky. Bitové operace práce s informací na nejnižší úrovni po bitech nutné znát vnitřní reprezentaci datových typů!!! použití jen na celá čísla použití zhušťování informace, logika CPU, OS o na PC u velkých aplikací dnes omezeně o často při programování MCU (málo paměti, bitový procesor) a komunikačních úloh PC periférie (např. zařízení připojené přes COM) Bitové operátory jen na celočíselné dat. typy definovány pro int Binární AND, OR, XOR bitový součet bitový součin & bitový součet modulo 2 (XOR) ^ Pravdivostní tabulka A B A B A & B A ^ B 0 0 0 0 0 3
0 1 1 0 1 1 0 1 0 1 1 1 1 1 0 Příklad unsigned char A = 189; // 1011 1101 unsigned char B = 90; // 0101 1010 unsigned char C,D,E; C = A B; // C = 1111 1111 = 255 D = A & B; // D = 0001 1000 = 24 E = A ^ B; // E = 1110 0111 = 231 Binární posuvy posun vlevo << o syntaxe: Operand << n o sémantika: bitově posune Operand o n pozic vlevo, zprava jsou doplňovány 0 o příklad: unsigned char A = 5, X; X = A << 2; // X = 20 // 5 = 00000101 // 20 = 00010100 o posun u 1 pozici vlevo = násobení operandu 2 logický posun vpravo >> o syntaxe: Operand >> n o sémantika: bitově posune Operand o n pozic vpravo, zleva jsou doplňovány 0 o příklad: unsigned char A = 5, X; X = A >> 1; // X = 2 // 5 = 00000101 // 2 = 00000010 o posun u 1 pozici vlevo = celočíselné dělení operandu 2 Poznámky sdružené varianty ke všem binárním logickým operátorům o X = Y // X = X Y o X &= Y // X = X & Y o X ^= Y // X = X ^ Y o X >>= n // X = X >> n o X <<= n // X = X << n pozor na rozdíl logické bitové operátory!!! unsigned char A = 189; // 1011 1101 unsigned char B = 90; // 0101 1010 unsigned char C, D; C = A B; // C = 255 C = A B; // C = 1 D = A & B; // D = 24 D = A && B; // D = 1 4
Unární bitová negace ~ o převrátí hodnoty všech bitů v operandu (0 za 1 a naopak) o příklad: C = ~0x0F; // C = 0xF0 opět pozor na rozdíl! a ~ Využití bitových operací Maskování = postup pro cílenou manipulaci s bity v čísle prostřednictvím tzv. masky, např.: o vynulování horních tří bytů v čísle typu int (32 b) o negace prvního, třetího a sedmého bitu v čísle unsigned char maska = (obvykle) konstanta s vhodně nastavenými bity využívá se vlastností logických funkcí: X maska X maska X & maska X ^ maska 0 0 0 0 0 1 0 1 0 1 0 1 1 0 1 1 1 1 1 0 o OR: maska = 1 bit do 1, maska = 0 bit ponechán beze změny o AND: maska = 0 bit do 0, maska = 1 bit ponechán beze změny o XOR: maska = 1 bit negován, maska = 0 bit ponechán beze změny Příklad: Vynulujte v 8b čísle X horní půlbyte (nibble) X &= 0x0F; # Příklad: Napište dvě funkce pro kódování a dekódování čtyř 8b čísel do jednoho čísla 32 #include <stdio.h> unsigned int Koduj(unsigned char b1, unsigned char b2, unsigned char b3, unsigned char b4) unsigned int temp; temp = b1; temp = (unsigned int)b2 << 8; temp = (unsigned int)b3 << 16; temp = (unsigned int)b4 << 24; return temp; void Dekoduj(unsigned int co, unsigned char *b1, unsigned char *b2, unsigned char *b3, unsigned char *b4) *b1 = (unsigned char)((0x000000ff & co)); *b2 = (unsigned char)((0x0000ff00 & co) >> 8); 5
*b3 = (unsigned char)((0x00ff0000 & co) >> 16); *b4 = (unsigned char)((0xff000000 & co) >> 24); int main(void) unsigned char a = 1, b = 2, c = 3, d = 4; unsigned char aa, bb, cc, dd; unsigned int cislo; cislo = Koduj(a, b, c, d); // cislo bude 0x04030201 Dekoduj(cislo, &aa, &bb, &cc, &dd); return 0; Programování mikroprocesorů manipulace s bity #define PA7 7 #define PA6 6 #define PA5 5 #define PA4 4 #define PA3 3 #define PA2 2 #define PA1 1 #define PA0 0 o PORTA = registr ( proměnná ) o nahození bitů do 1 (zbytek do 0) PORTA = (1<<PA0) (1<<PA3); o nahození bitů do 1 (zbytek ponechán) PORTA = (1<<PA0) (1<<PA3); o shození bitů do 0 (zbytek do 1) PORTA = ~((1<<PA0) (1<<PA3)); o shození bitů do 0 (zbytek ponechán) PORTA &= ~((1<<PA0) (1<<PA3)); větvení dle bitu v registru X #define BIT 0x40 if (X & (1 << BIT)) // if (BIT == 1) // akce if (!(X & (1 << BIT)) // if (BIT == 0) // akce Definice uživatelských datových typů I pouze náhrada jmen vestavěných (základních) typů syntaxe: typedef StaryTyp JmenoNovehoTypu; použití: struktury (později), prefixy dat. typů zatím typicky: typedef unsigned int uint; uint Prom; void Funkce(uint Arg1, double Arg2) 6
Příkaz goto příkaz nepodmíněného skoku (řídící struktura) syntaxe: prikaz1; goto label; prikaz2; label: prikazn; o label = návěští, označuje místo skoku skok pouze uvnitř téže funkce o v praxi pouze dopředu málo využívaný, lze se mu vyhnout znak špatné konstrukce kódu příklad dobrého využítí vnořené cykly: prikaz1; for(i=0; i<10; i++) for(j=0; j<10; j++) if(funkce(i,j) == ERROR) goto konecoboucyklu; konecoboucyklu: prikaz2; prikaz3; o složitější řešení: break + podmínka Ternární operátor podmíněný operátor syntaxe: bvyraz? vyraz1 : vyraz2; sémantika if (bvyraz) vyraz1; else vyraz2; typické použití: vyraz1 i vyraz2 přiřazují do stejné proměnné Př.: převod čísla na absolutní hodnotu int prom = 10; prom = (prom >= 0)? prom : -prom; další příklady (Herout): int a,b,c; a = (b == 2)? 1 : 3; c = (a > b)? a : b; (i == 1)? a++ : b++; Otázky jaké znáte bitové operátory (slovně) a jak pracují? jaký je rozdíl mezi logickým a bitovým operátorem (funkce + zápis)? 7
syntaxe a sémantika goto, k čemu je to dobré? syntaxe a sémantika typedef, k čemu je to dobré? syntaxe a sémantika ternárního operátoru, k čemu je to dobré? 8