NOVINKA: Získej 40 hodin praktických dovedností s AI – ZDARMA ke každému akreditovanému kurzu!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze – Lekce 4 - Dynamické textové řetězce a struktury v jazyce C

Zpět

Upozorňujeme, že diskuze pod našimi online kurzy jsou nemoderované a primárně slouží k získávání zpětné vazby pro budoucí vylepšení kurzů. Pro studenty našich rekvalifikačních kurzů nabízíme možnost přímého kontaktu s lektory a studijním referentem pro osobní konzultace a podporu v rámci jejich studia. Toto je exkluzivní služba, která zajišťuje kvalitní a cílenou pomoc v případě jakýchkoli dotazů nebo projektů.

Komentáře
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Patrik Pastor
DarkCoder:30.8.2019 19:15

Důvodem je efektivita. Funkce puts() používá pro výpis samotného řetězce méně strojových instrukcí než-li funkce printf(). Na druhou stranu je méně obecná, nelze ji použít pro výpis jiného typu nežli řetězce a dochází u ní k odřádkování. Je na programátorovi, aby použil vhodnou funkci.

Maďarská notace je konvence popisu proměnných a funkcí. Jméno proměnné nebo funkce pak obsahuje identifikátor vyjadřující návratovou hodnotu. Více na: Maďarská notace

Odpovědět
30.8.2019 19:15
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Patrik Pastor:30.8.2019 19:50

co se tyka toho odradkovani, to uz jsi zminoval pri analyze vstupniho retezce (tehda jsme se bavili o funkci fgets), nicmene samotny presne nerozumim, jak je odradkovani mysleno, nebo spise jaky to ma dopad na vstup/vystup. Vim pouze ze se odradkovani znaci '\n', ale - to uz jsem se kdysi ptal - neni to jediny bily znak (znam <cr> <_> a <tab>)
pro tyto dva zbyla ma cko znak? (pro tab to bude asi '\t') - nicmene, chybi mi v cecku "univerzalni sekvence pro bily znak" - pouzivam textovy editor "vim", a zde je univerzalni byly znak znace '\s'. Ma neco podobneho cecko? - protoze zatim jsem videl pouze znak \n uplne na vsechno. Stale me spis ale zajima, jake dusledky muze mit odradkovani na vstupu a vystupu

 
Odpovědět
30.8.2019 19:50
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Patrik Pastor
DarkCoder:30.8.2019 20:13

Když je ve formátovacím řetězci funkce printf() nalezen znak '\n', převede se na dvojici znaků "návrat na začátek řádku" a "posun o řádek".

printf("Tento text bude odradkovan\n");

// lze napsat i takto:

puts("Tento text bude odradkovan");

Při čtení bílé znaky oddělují hodnoty. Při výstupu mají vliv na formát výpisu. V C není žádný univerzální identifikátor pro bílý znak. Každý bílý znak má nějakou hodnotu.

' ' - mezera, '\t' - horizontální tabulator, '\v' - vertikální tabulator, '\n' - nový řádek, '\f' - nová stránka, '\r' - návrat na začátek řádku.

Kromě těchto jsou další znaky s lomítkem (escape sekvence).

Odpovědět
30.8.2019 20:13
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Patrik Pastor:30.8.2019 20:15

jake to jsou vsechny, protoze jak rikam - asi se budou lisit na ty, na ktere jsem zvykly z vimu. Je nejaka dokumentace k escape sekvencim?

 
Odpovědět
30.8.2019 20:15
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Patrik Pastor
DarkCoder:30.8.2019 20:23

Seznam escape sekvencí:

\a Alarm or Beep
\b Backspace
\f Form Feed
\n New Line
\r Carriage Return
\t Tab (Horizontal)
\v Vertical Tab
\\ Backslash
\' Single Quote
\" Double Quote
\? Question Mark
\ooo octal number
\xhh hexadecimal number
\0 Null

Editováno 30.8.2019 20:23
Odpovědět
30.8.2019 20:23
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Martin Russin:7.7.2021 20:43

Poprosím o vysvetlenie:

Kódom nižšie sme si alokovali potrebnú pamäť pre buffer, definovali ukazovateľ a následne ho inicializovali adresou, od ktorej sa začína nám pridelená pamäť?

char* jmeno je ten istý zápis ako char *jmeno?

V spomínanom kóde nie je pri alokácií pamäte použitá funkcia sizeof(). Je to chyba alebo je to tak správne?

char* jmeno = (char *) malloc(strlen(buffer) + 1);
 
Odpovědět
7.7.2021 20:43
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Martin Russin
DarkCoder:7.7.2021 22:02

Funkce malloc() vrací v případě úspěchu ukazatel na přidělený úsek paměti. Funkce vrací typ void* tudíž je dobré jak správně uvádíš přetypovat návratovou hodnotu na typ char*. Výsledek přiřazuješ znakovému ukazateli nazvanému jmeno. Ten ukazuje na začátek přidělené paměti. Velikost přidělené paměti je dáno výslednou hodnotou výrazu prvního parametru.

Všechny následující zápisy jsou správně.

char* jmeno = NULL;
char * jmeno = NULL;
char *jmeno = NULL;

preferuje se první nebo třetí možnost..

Zápis který si uvedl bych si dokázal představit pro vytvoření dalšího bufferu, třeba pro kopírování apod.

Povětšinou se to dělá takto:

#define BUFF_SIZE 100

char *jmeno = (char *) malloc(BUFF_SIZE);

Tímto si dynamicky alokuješ paměť o velikosti 100 bytů, pro uložení nějakého textu.
Přidělení není automatické.. mělo by se ověřit zda přidělení paměti bylo úspěšné (jmeno != NULL). A když paměť není třeba, uvolnit ji pomocí funkce free().

sizeof používáš když potřebuješ znát velikost nějakého typu nebo proměnné.

Např.

int *val = (int *) malloc(sizeof(int));

Tím si alokuješ prostor o velikosti typu int pro uložení celého čísla (v odpovídajícím rozsahu).

Odpovědět
7.7.2021 22:02
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Odpovídá na DarkCoder
Martin Russin:12.7.2021 16:05

V nasledujúcom kóde:

typedef struct {
    char meno[51];
    char ulica[51];
    int vek;
} UZIVATEL;

void zostarnutie(UZIVATEL *uzivatel) {
    uzivatel->vek++;
}

int main(int argc, char** argv) {
    UZIVATEL *p_Karol = malloc(sizeof(UZIVATEL));
    strcpy(p_Karol->meno, "Karol Nový");
    strcpy(p_Karol->ulica, "Šikmá 5");
    p_Karol->vek = 29;

    UZIVATEL *p_uzivatel2 = p_Karol;
    p_Karol->vek = 15;
    zostarnutie(p_uzivatel2);
    printf("Meno: %s\nUlica: %s\nVek: %d", p_uzivatel2->meno, p_uzivatel2->ulica, p_uzivatel2->vek);
    free(p_Karol);
    return (EXIT_SUCCESS);
}

sme v riadku

UZIVATEL *p_uzivatel2 = p_Karol;

definovali ukazovateľ s menom p_uzivatel2 na typ UZIVATEL a inicializovali ho adresou ukazovateľa p_Karol, t. j. adresa štruktúry s názvom UZIVATEL?
Z tohto dôvodu nie je pri ukazovateľovi p_Karol použitý dereferenčný ukazovateľ? Lebo predávame adresu a nie hodnotu?
Mám na myslí niečo takéto:

UZIVATEL *p_uzivatel2 = *p_Karol;

Na to isté sa chcem opýtať pri predávaní parametra funkcii zostarnutie. Ako parameter funkcii predávame ukazovateľ p_uzivatel2. Funkcii predávame adresu, na ktorú ukazuje ukazovateľ p_uzivatel2? Preto je opäť kód nižšie bez dereferenčného ukazovateľa?

zostarnutie(p_uzivatel2);

Ďakujem za odpoveď :).

 
Odpovědět
12.7.2021 16:05
Avatar
Odpovídá na Martin Russin
Patrik Valkovič:12.7.2021 16:51

Ahoj. Ano, přesně tak. Jakmile je u deklarovaného typu hvězdička, je to ukazatel - uchovává adresu paměti. Ukazatel lze přiřadit do ukazatela a typ pouze do typu. Proto UZIVATEL *p_uzivatel2 = p_Karol přiřazuje ukazatel do ukazatele, UZIVATEL uzivatel = *p_Karol přiřazuje objekt typu UZIVATEL. Podobně zostarnutie(UZIVATEL *uzivatel) přijímá jako parametr ukazatel, a tak mu musí být ukazatel předán. Kdyby funkce přijímala hodnotu zostarnutie(UZIVATEL uzivatel) potom do ní musí být předána hodnota a to dereferencí zostarnutie(*p_uzivatel2).
Snad jsem to dostatečně vysvětlil :)

Odpovědět
12.7.2021 16:51
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
Odpovídá na Patrik Valkovič
Martin Russin:12.7.2021 17:24

UZIVATEL uzivatel = *p_Karol přiřazuje objekt typu UZIVATEL.

Neviem, či to správne chápem, do premennej s názvom uzivatel, dátového typu UZIVATEL sa priradí hodnota, na ktorú ukazuje ukazovatel p_Karol?

 
Odpovědět
12.7.2021 17:24
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 27.