BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

Podobné dokumenty
BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky

Ukazatele. Paměť počítače Víte, jak velkou paměť má váš počítač? Ovládací panely/systém Víte, kolik je 1KiB,1kB, 1MB, 1GiB(ČSN IEC , 1998)?

Funkce, intuitivní chápání složitosti

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

Více o konstruktorech a destruktorech

Př. další použití pointerů

Mělká a hluboká kopie

Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include <stdio.h>

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

Pointery II. Jan Hnilica Počítačové modelování 17

Ukazatele, dynamická alokace

Operační systémy. Cvičení 4: Programování v C pod Unixem

Jazyk C++, některá rozšíření oproti C

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Racionální čísla, operátory, výrazy, knihovní funkce

Programování v C++, 2. cvičení

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

Ukazatele #1, struktury

Paměť počítače. alg2 1

Algoritmizace a programování

Ukazatele #2, dynamická alokace paměti

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

Řídící struktury, if, while, switch

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

Racionální čísla, operátory, výrazy, knihovní funkce

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

- jak udělat konstantu long int: L long velka = 78L;

Úvod do programovacích jazyků (Java)

Algoritmizace a programování

Abstraktní třídy, polymorfní struktury

Rozklad problému na podproblémy, rekurze

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE REALIZACE PŘEKLADAČE I

Ukazatele a pole. Chceme-li vyplnit celé pole nulami, použijeme prázdný inicializátor: 207 Čárka na konci seznamu inicializátorů

Jazyk C Program v jazyku C má následující strukturu: konstanty nebo proměnné musí Jednoduché datové typy: Strukturované datové typy Výrazy operátory

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

IUJCE 07/08 Přednáška č. 4. v paměti neexistuje. v paměti existuje

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole

IUJCE 07/08 Přednáška č. 6

Formátové specifikace formátovací řetězce

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Struktura programu v době běhu

6. lekce Úvod do jazyka C knihovny datové typy, definice proměnných základní struktura programu a jeho editace Miroslav Jílek

Úvod do programovacích jazyků (Java)

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

Rozklad problému na podproblémy, rekurze

4. Typ ukazatel, strukturované datové typy

Řídící struktury, if, while, switch

Základy programování (IZP)

Operační systémy. Cvičení 3: Programování v C pod Unixem

Základy C++ I. Jan Hnilica Počítačové modelování 18

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Lineární spojový seznam (úvod do dynamických datových struktur)

Např.: // v hlavičkovém souboru nebo na začátku // programu (pod include): typedef struct { char jmeno[20]; char prijmeni[20]; int rok_nar; } CLOVEK;

Algoritmizace a programování

Algoritmizace a programování. Ak. rok 2012/2013 vbp 1. ze 44

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Úvod do programování - Java. Cvičení č.4

Algoritmizace a programování

Konstruktory a destruktory

IMPLEMENTACE OPERAČNÍHO SYSTÉMU LINUX DO VÝUKY INFORMAČNÍCH TECHNOLOGIÍ JAZYK C

Strukturu lze funkci předat: (pole[i])+j. switch(výraz) velikost ukazatele

1. D Y N A M I C K É DAT O V É STRUKTUR Y

Algoritmizace, základy programování, VY_32_INOVACE_PRG_ALGO_01

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Pole a kolekce. v C#, Javě a C++

Programovací jazyk Pascal

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro:

9. přednáška - třídy, objekty

3. přednáška. Obsah: Řídící struktury sekvence, if-else, switch, for, while, do-while. Zpracování posloupnosti

Úvod do programování. Lekce 1

Přetěžování operátorů

Strukturované typy a ukazatele. Úvod do programování 1 Tomáš Kühr

ALGORITMIZACE A DATOVÉ STRUKTURY (14ASD) 1. cvičení

ZÁKLADY INFORMATIKY 14ZINF. Číselné soustavy

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

dovolují dělení velkých úloh na menší = dekompozice

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce.

Základy programování (IZP)

11a Dynamické dvourozměrné pole (obdobně vícerozměrné)

Základy algoritmizace a programování

Základy programování (IZP)

Práce s polem a pamětí

Dynamicky vázané metody. Pozdní vazba, virtuální metody

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Úvod do programování 7. hodina

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

type Obdelnik = array [1..3, 1..4] of integer; var M: Obdelnik;

Základy algoritmizace a programování

Dynamická alokace paměti

Řídicí struktury. alg3 1

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Výrazy, operace, příkazy

ZÁPOČTOVÝ TEST. Zpracoval Vilém Závodný, #include "stdafx.h" #include "stdio.h"

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

9. lekce Úvod do jazyka C 4. část Funkce, rekurze Editace, kompilace, spuštění Miroslav Jílek

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; }

Transkript:

Příprava studijního programu Informatika je podporována projektem financovaným z Evropského sociálního fondu a rozpočtu hlavního města Prahy. Praha & EU: Investujeme do vaší budoucnosti Ukazatele BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky Miroslav Balík Fakulta informačních technologií České vysoké učení technické

Evropský sociální fond Praha & EU: Investujeme do vaší budoucnosti Ukazatele BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky Miroslav Balík Fakulta informačních technologií České vysoké učení technické v Praze

Ukazatele proměnná typu ukazatel operace reference operace dereference kompatibilita ukazatelů ukazatelová aritmetika pole a ukazatele dynamické proměnné dealokace dynamických proměnných 3/26

Paměť počítače Víte, jak velkou paměť má váš počítač? Ovládací panely/systém Víte, kolik je 1KiB,1kB, 1MB, 1GiB(ČSN IEC 60027-2, 1998)? Jednotka Značka B kb KiB Kilobyte kb 1000 1 ~0,9766 Kibibyte KiB 1024 1,024 1 Megabyte MB 1 000 000 1000 ~976,6 Mebibyte MiB 1 048 576 ~1048,6 1024 Gigabyte GB 10 9 1 000 000 976 562,5 Gibibyte GiB 2 30 bytů ~1 073 742 1 048 576 prog8-mocniny2.c Jak vypsat adresy proměnných? prog8-adresy.c 4/26

Ukazatele Obsah proměnné typu ukazatel na T se chápe jako adresa proměnné typu T (známe již parametry typu ukazatel) Proměnnou p typu ukazatel na T zavedeme deklarací T *p; Tuto proměnnou můžeme inicializovat ukazatelem na proměnnou x typu int (adresou proměnné x) T *p = &x; nebo ji přiřadit ukazatel na proměnnou x typu int (adresu proměnné x) p = &x; Unární prefixový operátor & označuje operaci reference Je-li X proměnná typu T, pak výsledkem operace &X je ukazatel na proměnnou X (adresa proměnné X) a je typu T*, tzn. ukazatel na T Příklad (prog8-ukazatele1.c) int i, *pi = &i; char c, *pc; pc = &c; 5/26

Ukazatele Nebudeme se zabývat číselnými adresami Skutečnost, že proměnná p typu ukazatel obsahuje adresu proměnné x vyjádříme šipkou z p na x Předchozí příklad ještě jednou: int i, *pi = &i; char c, *pc; pc = &c; i pi c pc int i, *pi = &i;?? *pc = &c;?? 6/26

Dereference Chceme-li použít proměnnou, na kterou ukazuje ukazatel, vyjádříme to pomocí unárního operátoru dereference * Je-li X ukazatel typu T*, pak *X označuje proměnnou typu T, na kterou ukazuje ukazatel X Příklad (prog8-ukazatele2.c) int i, *pi = &i; char c, *pc; pc = &c; *pi = 10; *pc = a ; i pi c pc a 10 *pc *pi 7/26

Přiřazení ukazatelů Pro typ ukazatel na T (T*) typ T nazýváme doménovým typem ukazatele Kompatibilními typy ukazatel jsou takové, které mají stejný doménový typ Proměnné typu ukazatel je třeba přiřadit kompatibilní ukazatel int i, *pi; char c, *pc; int* char* pi = &i; /* kompatibilni typy */ int* pi = &c; /* nekompatibilni typy */ Přiřazení nekompatibilního ukazatele je v C pouze varovné hlášení 8/26

Přiřazení ukazatelů Co může způsobit, přiřadíme-li proměnné nekompatibilní ukazatel int i, *pi; char c, *pc; pi = &c; /* promenna typu int* ukazuje na promennou typu char */ pc = &i; /* promenna typu char* ukazuje na promennou typu int */ *pi = 0; /* vynuluji se 4 byty pocinaje adresou ulozenou v pi */ *pc = 0; /* vynuluje se byte na adrese ulozene v pc */ viz příklad prog8-ukazatele3.c 9/26

Přiřazení ukazatelů, poznámka Uložení čísla int 0x4A 3B 2C 1D v paměti počítače: Little endian (Intel) 1D 2C 3B 4A (adresy rostou doprava) Big endian (Motorola, SPARC, IBM) Middle-endian (Mixed endian) Bi-endian (umí přepínat) 4A 3B 2C 1D 3B 4A 1D 2C nebo 2C 1D 4A 3B ARM, PowerPC, Alpha, SPARC V9, MIPS, PA-RISC and IA64) 10/26

NULL ukazatel Jako prázdný, neplatný ukazatel, který neukazuje na žádnou proměnnou, slouží v jazyku C hodnota 0 Symbolickým označením tohoto ukazatele je NULL Dereference prázdného ukazatele způsobí chybu při běhu programu Příklad prog8-ukazatele4.c: int main(void) { int *p = NULL; *p = 10; system("pause"); return 0; } 11/26

Ukazatelová aritmetika Ukazatelé mohou být operandy sčítání, odčítání a všech relačních operátorů Dovolené kombinace a typ výsledku: T* + int -> T* T* - int -> T* T* - T* -> int T* relop T* -> int Přičtení n k ukazateli typu T* znamená jeho změnu o n-násobek délky typu T, podobně odečtení a rozdíl ukazatelů int a[10], *p = &a[0]; *(p + 3) = 10; /* do a[3] se uloží 10 */ /* vynulování pole a */ for (p = &a[0]; p <= &a[9]; p++) *p = 0; /* nebo */ for (p = &a[0]; p <= &a[9]; *p++ = 0); 12/26

Pole a ukazatele Jméno pole prvků typu T = konstantní ukazatel typu T* ukazující na prvek s indexem 0 int a[10], *pa, i; pa = a; totéž co pa = &a[0] *(a + 2) = 3; totéž co a[2] = 3 *(a + i) = 4; totéž co a[i] = 4; for (pa = a; pa <= a + 9; *pa++ = 0); a++; Chyba (proč?) Upřesnění indexace: X [ Y ] kde jeden výraz je typu ukazatel na T a druhý typu int, výsledek je typu T Výraz X [ Y ] je ekvivalentní s *(( X ) + ( Y ) ) pa[3] = 10; totéž co*(pa + 3) = 10; 13/26

Pole a ukazatele Podívejte se na příklad prog8-vektory1.c skalární součin dvou vektorů, parametry funkcí specifikovány jako ukazatele... void ctivektor(int *v, int n) { int i; printf("zadejte %d celych cisel\n", n); for (i=0; i<n; i++) scanf("%d", &v[i]); } 14/26

Pole a ukazatele Podívejte se na příklad prog8-vektory2.c skalární součin dvou vektorů, průchody polem pomocí ukazatelové aritmetiky void ctivektor(int v[], int n) { int *p, *pn = v+n; printf("zadejte %d celych cisel\n", n); for (p=v; p<pn; p++) scanf("%d", p); } void ctivektor(int *v, int n) { int i; printf("zadejte %d celych cisel\n", n); for (i=0; i<n; i++) scanf("%d", &v[i]); } 15/26

Řetězce a ukazatele - PALINDROM Palindrom je alespoň dvojznakové slovo, které vychází stejně čteno odpředu i odzadu, např. kajak Pro zjištění, zda slovo je palindrom, zavedeme funkci #define MAXDELKA 100 int jepalindrom(char *s); int main(void) { } char slovo[maxdelka+1]; printf("zadejte slovo obsahujici nanejvys %d znaku: ", MAXDELKA); scanf("%s", slovo); printf("zadali jste %s\n", slovo); printf("toto slovo "); if (jepalindrom(slovo)) printf("je"); else printf("neni"); printf(" palindrom\n");... nepochopen nepotopen Dne moto: Palindrom i spáchá psí mord, Nil a potom End. 16/26

Řetězce a ukazatele Jak zjistit, že slovo je palindrom slovo délky d bude uloženo v poli s počínaje indexem 0 a konče indexem d-1 (hodnotou prvku s indexem d bude závěrečná nula) aby slovo bylo palindrom, musí platit: s[0] == s[d-1] s[1] == s[d-2]... test na rovnost skončíme, až dosáhneme poloviny délky slova Řešení (prog8-palindrom1.c): int jepalindrom(char *s) { int delka = strlen(s), polovina = delka/2, i; for (i=0; i<polovina; i++) if (s[i]!=s[delka-i-1]) return 0; return 1; } 17/26

Řetězce a ukazatele Testy rovnosti znaků můžeme provádět pomocí dvou proměnných typu ukazatel na char, z nichž první nastavíme na první znak a budeme ji zvětšovat a druhou nastavíme na poslední znak a budeme ji zmenšovat Test budeme opakovat, pokud první ukazatel bude menší než druhý ukazatel Řešení (prog8-palindrom2.c): int jepalindrom(char *s) { char *p, *q; for (p=s, q=s+strlen(s)-1; p<q; p++, q--) if (*p!= *q) return 0; return 1; } 18/26

Řetězce a ukazatele A něco na závěr řetězců a ukazatelů Literál tvořený posloupností znaků, která je uzavřena do uvozovek, je typu char* (připomeňme, že v paměti je reprezentován posloupností znaků zakončenou nulovým bytem) Podívejte se na příklad prog8-palindrom3.c #define SLOVO "kajak" int jepalindrom(char *s); int main(void) { printf("slovo %s ", SLOVO); if (jepalindrom(slovo)) printf("je"); else printf("neni"); printf(" palindrom\n"); jepalindrom("abcd"); return 0; } 19/26

Dynamické proměnné Ukazatele v jazyku C slouží především pro: předávání výstupních parametrů procedurám a funkcím předávání pole jako parametru procedurám a funkcím přístup k dynamickým proměnným Dynamická proměnná není zavedena deklarací, ale je vytvořena speciální funkcí (operátorem, příkazem) Dynamická proměnná nemá jméno, a proto k ní můžeme přistupovat pouze pomocí ukazatele (adresy) V jazyku C vytvoříme dynamickou proměnnou pomocí funkce malloc parametrem funkce je počet bytů, které budou vnitřní reprezentací proměnné funkce zařídí, že ve volné paměti je rezervováno místo pro proměnnou s danou velikostí vnitřní reprezentace a jejím výsledkem je adresa tohoto místa (tzn. ukazatel na dynamicky vytvořenou proměnnou) funkce je deklarována tak, že vrací výsledek typu void*; volání funkce je proto třeba přetypovat 20/26

Příklad (prog8-dynprom.c) Dynamické proměnné int main(void) { int *p; přetypování na typ int* p = (int*)malloc(sizeof(int)); *p = 10; printf("*p=%d\n", *p); system("pause"); return 0; } Jak je to v paměti počítače p 10 zásobník halda 21/26

Dynamicky vytvořené pole Dynamicky vytvořené proměnné jednoduchých typů obvykle nejsou třeba Užitečné je dynamicky vytvořené pole Příklad: skalární součin dvou vektorů, počet složek je dán vstupními daty funkce ctivektor dynamicky vytvoří pole, jehož délka je dána parametrem, a přečte jeho prvky z klávesnice int *ctivektor(int n) { int i, *p; p = (int*)malloc(sizeof(int)*n); printf("zadejte %d celych cisel\n", n); for (i=0; i<n; i++) scanf("%d", &p[i]); return p; } Ve funkci main nebudou deklarována pole, ale proměnné typu ukazatel, do nichž se uloží adresy polí dynamicky vytvořených funkcí ctivektor 22/26

prog8-dynpole.c Dynamicky vytvořené pole int ctiint(int min, int max) {...} int *ctivektor(int n) {...} int skalarnisoucin(int x[], int y[], int n) {...} int main(void) { int *x, *y, n; printf("zadejte pocet slozek vektoru: "); n = ctiint(1, INT_MAX); printf("vektor x\n"); x = ctivektor(n); printf("vektor y\n"); y = ctivektor(n); printf("skalarni soucin vektoru x a y je %d\n", skalarnisoucin(x, y, n)); return 0; } 23/26

Příklad: int *p, *q; p = (int*)malloc(sizeof(int)); q = (int*)malloc(sizeof(int)); *p = 10; *q = 20; Dealokace p 10 q 20 24/26

Příklad: int *p, *q; p = (int*)malloc(sizeof(int)); q = (int*)malloc(sizeof(int)); *p = 10; *q = 20; q = p; p Dealokace 10 q 20 Co s dynamicky vytvořenou proměnnou s hodnotpu 20, na kterou ukazovala proměnná q (není přístupná)? Před ztrátou ukazatele na ni je třeba ji dealokovat (vrátit paměť, kterou zabírá, zpět do volné paměti) 25/26

Dealokace Dealokaci provádí funkce free int *p, *q; p = (int*)malloc(sizeof(int)); q = (int*)malloc(sizeof(int)); *p = 10; *q = 20; free(q); q = p; p 10 q 20 Paměť přidělená modře zarámované proměnné se uvolní a je k dispozici pro další malloc 26/26

Pamět počítače program vytvořený překladačem jazyka C využívá pěti úseků paměti: paměť kódu paměť konstant paměť globálnich proměnných zásobník pro přidělení paměti parametrům a lokálním proměnným funkcí paměť pro dynamické proměnné Podívejte se na program prog8-pamet.c, který vypíše adresy z těchto úseků 27/26