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

Podobné dokumenty
Př. další použití pointerů

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

Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0

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

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

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

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ý

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;

Dynamická vícerozměrná pole. Základy programování 2 Tomáš Kühr

Práce s pamětí a předávání parametrů. Úvod do programování 1

Algoritmizace a programování

Více o konstruktorech a destruktorech

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

Vícerozměrná pole. Úvod do programování 2 Tomáš Kühr

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

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

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

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

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

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

Pole a Funkce. Úvod do programování 1 Tomáš Kühr

Základy programování (IZP)

KTE / ZPE Informační technologie

int => unsigned int => long => unsigned long => float => double => long double - tj. bude-li:

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

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

Práce s polem a pamětí

Úvod do programování. Lekce 5

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

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

2 Datové typy v jazyce C

Základní datové typy, proměnné - deklarujeme předem - C je case sensitive rozlišuje malá a velká písmena v názvech proměnných a funkcí

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

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

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

POČÍTAČE A PROGRAMOVÁNÍ

10 Práce s řetězci - pokračování

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

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

4. Typ ukazatel, strukturované datové typy

Struktura programu v době běhu

Základy programování (IZP)

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

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

PB071 Programování v jazyce C Jaro 2015

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

Mělká a hluboká kopie

Základní datové struktury

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

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

- transpozice (odlišuje se od překlopení pro komplexní čísla) - překlopení matice pole podle hlavní diagonály, např.: A.' ans =

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

Odvozené a strukturované typy dat

11b Další příklady operací vstupu a výstupu (úvod viz 10)

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

ZÁKLADY PROGRAMOVÁNÍ V C

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Pokročilé programování v jazyce C pro chemiky (C3220) Třídy v C++

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

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

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.

MAXScript výukový kurz

Algoritmizace a programování

III/2 Inovace a zkvalitnění výuky prostřednictvím ICT

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

8 Třídy, objekty, metody, předávání argumentů metod

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

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

- tzv. standardní vstupní a výstupní proud (input / output stream)

Ukazatele, dynamická alokace

Základy programování 2 KMI/ZP2

Práce s řetězci. IUJCE Přednáška č. 10. string.h. vrací: délku řetězce str (bez '\0')

Algoritmizace a programování

Ukazatele, paměťové třídy, volání funkcí

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

Programování v jazyce C

Funkce, procedury, složitost

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

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. December 7, 2016

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

Spojová implementace lineárních datových struktur

Aplikace Embedded systémů v Mechatronice. Michal Bastl A2/713a

Konstruktory a destruktory

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

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

Množina čísel int stl-set-int.cpp

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

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

typová konverze typová inference

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

Programovanie v jazyku C - to chce dynamiku

pi Ludolfovo číslo π = 3,14159 e Eulerovo číslo e = 2,71828 (lze spočítat jako exp(1)), např. je v Octave, v MATLABu tato konstanta e není

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

Správa paměti. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta, 2016

Základy programování (IZP)

Programování v jazyce C pro chemiky (C2160) 11. Vizualizace sekvence proteinů

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

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

Ukazatele #2, dynamická alokace paměti

Transkript:

11a Dynamické dvourozměrné pole (obdobně vícerozměrné) počet hvězdiček == počet rozměrů (dimenze pole) int **p_2d; int radku, sloupcu; printf("zadejte pocet radku a sloupcu pole:"); scanf("%d,%d", &radku, &sloupcu) p_2d = (int **) malloc(radku * sizeof(int *)); for (int i = 0; i < radku; i++) *(p_2d + i) = (int *) malloc(sloupcu * sizeof(int)); nebo for (int i = 0; i < radku; i++) p_2d[i] = (int *) malloc(sloupcu * sizeof(int)); int **p_2d int int * Zeleně označené hodnoty rozměry pole by v praxi byly proměnné.

Použití opět jako "normální" pole (viz výše): p_2d[radek][sloupec] = 5; p_2d[2][3] = 5; identická operace "pointerovým" způsobem: *(*(p_2d + radek) + sloupec) = 5; *(*(p_2d + 2) + 3) = 5;

Uvolnění paměti 2D dynamického pole int i; for (i = 0; i < radku; i++) free((void *) *(p_2d + i)); free((void *) p_2d); resp. bez přetypování (umí samo) int i; for (i = 0; i < radku; i++) free(*(p_2d + i)); free(p_2d); Jinak pomocí [ ] int i; for (i = 0; i < radku; i++) free(p_2d[i]); free(p_2d); Obecně u dynamických polí platí: &pole[0] == &*(pole + 0) == pole, tj. adresa nultého prvku pole je rovna adrese hodnoty nultého prvku pole a lze ji vyjádřit samotným názvem pole (bez hranatých závorek) Tento přístup k polím (pomocí pointerů) umožňuje i následující postup: double **p_p_double, *p_prvek, *p_radek;

p_p_double = (double **) malloc(4 * sizeof(double *)); for (int i = 0; i < 4; i++) p_p_double[i] = (double *) malloc(3 * sizeof(double)); p_radek = p_p_double[2]; Dále pracuji s p_radek, jako s jednorozměrným polem, nijak není vidět, že vlastně upravuji řádek 2d pole p_double s indexem 2 p_radek[1] = 6.54; vykoná totéž jako: p_p_double[2][1] = 6.54; Obdobně pro jeden prvek: p_prvek = &(p_p_double[2][1]); A opět obdobná operace: *p_prvek = 6.54;

Př. funkce, které posíláme na zpracování jen jeden řádek void vypln_radek(double *p_radek, double cim) int i; for(i = 0; i < POCET_SLOUPCU; i++) p_radek[i] = cim; Potom v např. mainu: int main(void) double **p_double, *p_prvek, *p_radek; p_double = (double **) malloc(4 * sizeof(double *)); for (int i = 0; i < 4; i++) *(p_double + i) = (double *) malloc(3 * sizeof(double)); p_radek = p_double[2]; vypln_radek(p_radek, 3.45); vypln_radek(p_double[2], 3.45); // totéž bez pomocné prom.p_radek // uvolnění paměti 2D dynamického pole for (int i = 0; i < 4; i++) free((void *) *(p_double + i)); free((void *) p_double);

Pointery ve vztahu k funkcím mějme funkci deklarovanou takto: void pocitej(double *p_param) mohu volat v programu různými způsoby. Záleží na tom, co je obsahem funkce, tj. musím vědět, jaký parametr chce. Uvedený parametr může být jeden double, nebo 1D pole double (což ovšem může být i jeden řádek 2D pole) Tj.: double a; double *p_d; double **p_pole2d; /* zde proběhne alokace paměti, neuvádím, viz výše */ pocitej(&a); /* předám adr. jednoho double */ pocitej(p_d); /* předám adr. dyn. alokované paměti jeden nebo více double (tj. třeba jednorozměrné pole) */ pocitej(p_pole2d[2]); /* předám adr. dyn. alokované paměti jeden nebo více double jeden řádek 2D,tj.totéž jako jednorozměrné pole) */ To, která varianta je ta pravá, rozhoduje vnitřek funkce pocitej.

Např. pro 1D pole (nebo jeden řádek 2D pole) Je lépe předat také rozměr pole: void pocitej(double *param, int delkapole) double pom; pom = 6.98; for (int i = 0; i < delkapole; i++) param[i] = param[i] * pom; Potom volání: double *p_d; p_d = (double *) malloc(10 * sizeof(double)); pocitej(p_d, 10); Lze i pro staticky vytvořené pole: double policko[10]; pocitej(policko, 10); Pro 2D pole: void pocitej2d(double **param, int poc_radek, int poc_sloupcu) int i, j; double pom; pom = 6.98; for (i = 0; i < poc_radek; i++) for (j = 0; j < poc_sloupcu; j++) param[i][j] = param[i][j] * pom; Obdobným způsobem může funkce vracet výsledek typu pointer int * vyrob_1dpole(int delka_pole)

int *p_prom; p_prom = (int *) malloc(delka_pole * sizeof(int)); if (p_prom == NULL) printf("mas smulu, pamet dosla ;-)"); exit(0); // např. ukončení programu else return(p_prom); Volání této funkce: int *p_pole; p_pole = vyrob_1dpole(30); Pozor na závážnou chybu: int * vyrob_1dpole(int delka_pole) int prom[delka_pole]; /* půjde jen v některých verzích C (ANSI99) */ return(prom); Horší případ (projde přes všechny překladače) a opět velká chyba, vracím odkaz na paměť která na konci funkce je uvolněna!!!!: int * vyrob_1dpole100(void) int prom[100]; return(prom); // vracím adresu kde to této chvíle BYLO pole, ale po návratu z funkce už nebude, ale já to nemám šanci poznat => budu pracovat s oblastí paměti, kde nemám co dělat!!!! Zdánlivě bude fungovat, vrátí adresu pole prom. Bude chybovat, protože prom je lokální proměnná, po skončení funkce zanikne tj. vracím sice

adresu paměti, ta však byla po skončení funkce vrácena systému jako volná => budu přepisovat, používat oblast paměti, která mi již nepatří. Mohou být v ní vytvořeny další proměnné a já si je nechtíc přepíši. Pozn.: různé "hezké" deklarace komplikovaných pointerů viz učebnice double (* nazev())[]; - nazev je funkce vracející pointer na pole doublů double (* nazev[])(); - nazev je pole pointerů na funkce, které vracejí double Pozn.: bylo zmíněno pole pointerů na funkce. Jak zjistit adresu funkce: nazev_funkce bez kulatých závorek, jen název adresa Např.: mám funkci: double pocitej(void)...tělo funkce... void main(void) double x; double (* p_funkce)(); p_funkce = pocitej; // do p_funkce jsem dal adresu funkce pocitej x = p_funkce(); - vyvolá totéž jako příkaz x = pocitej();

Např.: #include <stdio.h> #include <math.h> #define DELKA 3 main() double cislo = 2.45; int i; double (* p_fun[delka])(double); printf("\nsin %f je %f", cislo, sin(cislo)); printf("\ncos %f je %f", cislo, cos(cislo)); printf("\ntan %f je %f\n", cislo, tan(cislo)); p_fun[0] = sin; p_fun[1] = cos; p_fun[2] = tan; for(i = 0; i < DELKA; i++) printf("\nvysledek pro %f je %f", cislo, p_fun[i](cislo)); printf("\n"); system("pause");