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

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

- 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

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

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

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;

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

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

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

Algoritmizace a programování

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

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í

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

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

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

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ý

Práce s polem a pamětí

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

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

Ukazatele, dynamická alokace

2 Datové typy v jazyce C

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

Základy programování (IZP)

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

Základy programování (IZP)

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

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

Základy programování (IZP)

Základy programování (IZP)

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

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

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

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

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

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

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

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

Více o konstruktorech a destruktorech

4. Typ ukazatel, strukturované datové typy

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

Mělká a hluboká kopie

Odvozené a strukturované typy dat

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

Bitové operátory a bitová pole. Úvod do programování 2 Tomáš Kühr

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

Algoritmizace a programování

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

Programovanie v jazyku C - to chce dynamiku

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

Základy programování 2 KMI/ZP2

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

ZÁKLADY PROGRAMOVÁNÍ V C

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

Základy algoritmizace a programování

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

Základy programování (IZP)

Řešení sady 1. Úvod do programování 1 Tomáš Kühr

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

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

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

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

Algoritmizace a programování

Základy programování (IZP)

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.

Ukazatele #2, dynamická alokace paměti

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

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

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

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

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

Základní datové struktury

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

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

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

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 )/ ;

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

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

Struktura programu v době běhu

IUJCE Přednáška č. 1. programování v C na vyšší úrovni základy objektově orientovaného programovaní v (C++, C#)

POČÍTAČE A PROGRAMOVÁNÍ

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

Programování v jazyce C

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

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

Funkční objekty v C++.

C++ přetěžování funkcí a operátorů. Jan Hnilica Počítačové modelování 19

PŘETĚŽOVÁNÍ OPERÁTORŮ

Objektově orientované programování

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

Výčtový typ strana 67

Dílčí příklady použití jazykových konstrukcí v projektu. Jazyk C Příklady. Pravidla překladu v gmake. Zadání

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

PB071 Programování v jazyce C Jaro 2015

Základy algoritmizace a programování

Generické programování

Zápis programu v jazyce C#

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

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

Transkript:

Př. další použití pointerů char *p_ch; int *p_i; p_ch = (char *) p_i; // konverze int * na char * 8 int i = 5; int *p_i; p_i = &i; POZOR!!!! scanf("%d", p_i); printf("%d", *p_i); Obecný pointer na cokoliv: void *p_obec; - lze jej konvertovat na libolný typ pointeru - tento typ pointeru vrací funce malloc void *p_v; // univerzální pointer - jde přetypovat na pointer na cokoliv - přetypuji ho: double *p_d; p_d = (double *) p_v; - málokdy použijeme v této podobě, ale někdy spíše jako výsledek funkce: void *funkce() vrací obecný pointer, mohu přetypovat na cokoliv: double *p_d; p_d = (double *) funkce();

Operátor typedef - deklarace vlastního datového typu - je zvykem pojmenovávat nové typy velkými písmeny typedef unsigned char BYTE; /* deklaruji si nový typ BYTE */ BYTE a, b, c; // prom. a,b,c jsou typu BYTE - lze i toto (může být nepřehledné): typedef double *P_DOUBLE; P_DOUBLE p_d1, p_d2, p_d3; p_d1 až p_d3 jsou vnitřně typu double * Ovšem můžete potom omylem vytvořit: P_DOUBLE *p_d; - p_d je ale vnitřně double ** tj. double **p_d; neboli pointer na pointer na double double ** double * double: 893.67889 Pointerová aritmetika sizeof(dat_typ) - vrací kolik byte zabírá dat. typ, resp. proměnná Oba dva následující výrazy (kde deklarováno int i) vrátí velikost int:

sizeof(int); int i; sizeof(i); - přičtu-li k pointeru 1 (p_i + 1), zvětší se hodnota adresy o počet bytů, kolik má typ na který pointer ukazuje (např. u int o 4byte) - nutné u polí int *p_i; p_i bude adresa 10 - nějakým způsobem p_i = p_i + 1; p_i bude ukazovat na adresu 14 (int má 4 byte) a to vše automaticky nebo double *p_d; p_d bude adresa 10 // nějakým způsobem p_d = p_d + 1; p_d bude uk. na adresu 18 (double má 8 byte) a to vše opět automaticky atp. pro libovolný datový i uživatelem definovaný pomocí typedef Př.: #include <stdio.h> #include <stdlib.h> /* program přečte int a vypíše jeho jednotlive byty */ int main() { int *p_cislo; unsigned char *p_byte; int i;

p_cislo = (int *) malloc(sizeof(int)); if(p_cislo == NULL) { printf("\npamet dosla, nenadelas nic...\n"); return -1; printf("zadejte cele cislo, vypisu jeho byty: "); scanf("%d", p_cislo); p_byte = (unsigned char *) p_cislo; printf("\n"); for (i = (sizeof(int)-1); i >= 0 ; i--) { printf("%d ", *(p_byte + i)); free((void *) p_cislo); Dynamické přidělování paměti p_prom int *p_prom; p_prom = NULL; // dobrý zvyk, protože potom *p_prom = 78; // ohlásí chybu, jinak přepíše paměť a ani se tím nepochlubí -> nebezpečné!!! viz začátek přednášky p_prom = (int *) malloc(sizeof(int)); Co když došla paměť? Musím testovat. Při nedostatku paměti malloc vrátí NULL: p_prom = (int *) malloc(sizeof(int)); if (p_prom == NULL) { printf("mas smulu, pamet dosla ;-)");

exit(0); // např. ukončení programu - nebo totéž méně přehledně, leč takto běžnější: if ((p_prom = (int *) malloc(sizeof(int))) == NULL) { printf("mas smulu, pamet dosla ;-)"); exit(-1); // např. ukončení programu - přidělěnou paměť je třeba "hlídat" = neztratit odkaz (např. po skončení funkce), protože ji musíme ručně uvolnit. Ruční uvolnění paměti, kterou již nepotřebuji: free((void *) p_prom); p_prom = NULL; // není nutno, leč bezpečnější - důvod, proč nastavit pointer po free na NULL: v pointeru zůstane po uvolnění paměti původní adresa. Mohl bych tedy s pointerem dále pracovat, ale vlastně již s pamětí, kterou vrátil systému. Pole souvislost s pointery int *p_prom, kolik; printf("jak velke pole to bude: "); scanf("%d", &kolik); /* před., že zadáme z kláv. 100 */ p_prom = (int *) malloc(kolik * sizeof(int)); if (p_prom == NULL) { printf("mas smulu, pamet dosla ;-)"); exit(0); // např. ukončení programu *(p_prom + 0) = 10; // prvni prvek pole s indexem 0 *(p_prom + 10) = 20; // 11 prvek pole s indexem 10

*(p_prom + 99) = 54; // poslední prvek pole s indexem 99 - lze též opravdu jako pole: p_prom[0] = 10; p_prom[10] = 20; p_prom[99] = 54; zrušení tohoto pole: free((void *) p_prom); Pole souhrn a opakování - statická pole (ne dynamicky jako výše) - opakování int policko[100]; policko[5] = 7; // pozor je to 6. prvek s indexem 5 policko[99] = 2; // poslední prvek. policko[100] = 78; // C nijak neprotestuje příkaz vykoná - hodnota 78 je zapsána do paměti ZA moje pole, přepisuji paměť, kterou nemám přidělenu => pravděpodobně bude program chybovat. Může tam uložena moje jiná proměnná... - to znamená, že C nekontroluje rozsahy polí a ohlídání je na programátorovi musím si udržovat např. nějakou proměnnou, kde budu délku pole uloženu.

- dvourozměrné pole: int pol2d[5][10]; pol2d[0][0] = 4; Prolezu dvourozměrné pole: int pole2d[100][100]; for(i = 0; i < 100; i++) { for(j = 0; j < 100; j++) { pol2d[j][i] = 5; // jedu po poli po sloupcích j je číslo řádku, prolezu pro jedno I vždy všechna j for(i = 0; i < 100; i++) { for(j = 0; j < 100; j++) { pol2d[i][j] = 5; // jedu po poli po řádkách j je číslo řádku, prolezu pro jedno i vždy všechna j Prolezu jen horni trojuhelnikovou matici: for(i = 0; i < 100; i++) { for(j = i; j < 100; j++) { pol2d[i][j] = 5; Prolezu jen dolni trojuhelnikovou matici: radekkam = 1; for(i = 0; i < 100; i++) { for(j = 0; j < radekkam; j++) { pol2d[i][j] = 5; radekkam++;

Souřadnice prvků ve 2d polích int pol2d[5][10]; /* 5 řádek, 10 sloupců */ pol2d[0][0] = 4; /* prvek úplně vlevo nahoře */ pol2d[4][9] = 3; /* prvek úplně vpravo dole */ Použití konstanty lépe než přímo zapsat číslo jako rozměr pole #define MAX 10 double pold[max]; for (int i = 0; i < MAX; i++) { /* i běží od 0 do 9 */ pold[i] = 3.4;

Deklarace vlastního typu pole: typedef int VECTORPET[5]; - deklarace vlastního typu VECTOR5, který představuje pole 5ti intů. VECTORPET v1, v2, v3; v1[4] = 6; int v4[5]; /* totéž */ Lze i vícerozměrná pole: int pole3[2][3][4];

V ANSI C 89 NELZE!!!!!!!! následující konstrukci: int delka; scanf("%d", &delka); double prom_pole[delka]; - nelze ve velkém množství verzí C, záleží normě, kterou daný překladač splňuje-lze dle normy ANSI 99. - pokud toto překladač umí přeložit, zjistíte ve výsledném kódu, že použil obdobnou funkci jako je malloc - standardním řešením jsou: Dynamická pole (viz výše několikrát) int *p_pole, kolik; printf("jak velke pole to bude: "); scanf("%d", &kolik); /* před., že zadáme z kláv. 100 */ p_pole = (int *) malloc(kolik * sizeof(int)); if (p_pole == NULL) { printf("mas smulu, pamet dosla ;-)"); exit(0); // např. ukončení programu *(p_pole + 0) = 10; // prvni prvek pole s indexem 0 *(p_pole + 10) = 20; // 11 prvek pole s indexem 10 *(p_pole + 99) = 54; // poslední prvek pole s indexem 99 lze opravdu jako pole: p_pole[0] = 10; p_pole[10] = 20; p_pole[99] = 54;

- likvidace dynamického pole - jako u jiných pointerů free((void *) p_pole); p_pole = NULL; /* pro jistotu, abych ho nemohl omylem použít */ Pole může tedy vzniknou za běhu, dle potřeby: int *p_pole, delkapole; scanf("%d", &delkapole); p_pole = (int *) malloc(delkapole * sizeof(int)); Př.: #include <stdio.h> #include <limits.h> int main (void) { unsigned char *p_ch; int *p_i; p_ch = (unsigned char *) malloc(sizeof(unsigned char)); if(p_ch == NULL) { printf("\ndosla pamet, p_ch se neveslo..."); exit(-1); if((p_i = (int *) malloc(sizeof(int))) == NULL) { printf("\ndosla pamet, p_i se neveslo..."); exit(-1); *p_i = INT_MIN; p_ch = (unsigned char *) p_i; // konverze (int *) na (unsigned char *)

printf("\nint je: %d (velikost %d)", *p_i, sizeof(*p_i)); printf("\n\na jako ctyri byte: %d, %d, %d, %d", *p_ch, *(p_ch + 1), *(p_ch + 2), *(p_ch + 3)); free((void *) p_ch); free((void *) p_i); printf("\n\n\n"); system("pause");