Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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 14 - Funkce 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
Odpovídá na Libor Šimo (libcosenior)
Martin Russin:22.6.2021 16:30

Dobrý deň, chcel som si vyskúšať načítať meno pomocou príkazu scanf, no neúspešne. Neviete mi prosím poradiť, ako na to? Neviem skĺbiť načítanie mena pomocou príkazu scanf("%s", jmeno); s príkazom na vyvolanie funkcie pozdrav -> pozdrav("").

#include <stdio.h>
#include <stdlib.h>

/*
 *
 */

void pozdrav(char jmeno[])
{
    printf("Ahoj, vřele tě tu vítám %s!\n", jmeno);
}

int main(int argc, char** argv)
{
    scanf("%s", jmeno);
    pozdrav(.......);
    return (EXIT_SUCCESS);
}
 
Odpovědět
22.6.2021 16:30
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Martin Russin
DarkCoder:22.6.2021 17:57

Nejprve si musíš vyhradit paměťový prostor pro jméno. Tedy alokovat pole takové délky, aby se Ti do něj vešlo požadované jméno a to včetně nulového znaku.

Např.

#define NAME_LIMIT 20
char szName[NAME_LIMIT + 1];

Poté načteš jméno pomocí scanf

scanf("%s", szName);

A nakonec zavoláš funkci pozdrav

pozdrav(szName);
Odpovědět
22.6.2021 17:57
"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:22.6.2021 18:21

Ďakujem za odpoveď a pomoc.

Mám to prosím správne?

#include <stdio.h>
#include <stdlib.h>
#define VELKOST_POLE 20

void pozdrav(char jmeno[])
{
    printf("Ahoj, vřele tě tu vítám %s!\n", jmeno);
}

int main(int argc, char** argv)
{
    char jmeno[VELKOST_POLE];
    scanf("19%s", jmeno);
    pozdrav(jmeno);
    return (EXIT_SUCCESS);
}

Prečo si definoval veľkosť poľa týmto spôsobom?

char szName[NAME_LIMIT + 1];

Mám na myslí to +1. Viem, že veľkosť poľa musí byť väčšia o 1 ako počet znakov, ktoré sa do neho uložia (kvôli nulovému znaku '\0') ale nebolo by jednoduchšie len v príkaze scanf zadefinovať koľko znakov sa ma načítať?

Chcel by som sa prosím opýtať ešte na jednu vec. Spravil som chybu ak som vo funkcii main zadeklaroval pole s textovým reťazcom pod názvom jmeno a to iste som spravil aj vo fukncii pozdrav? Narobí to nejakú šarapatu alebo je potrebné použiť v týchto dvoch funkciách odlišné názvy polí?

 
Odpovědět
22.6.2021 18:21
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Martin Russin
DarkCoder:22.6.2021 19:09

Je to správně, pouze bych jako identifikátor konstanty zvolil významově jasnější jméno. viz můj předešlý příspěvek.

Deklaraci pole tímto způsobem jsem zvolil z důvodu přehlednosti. Jasně vidím, že délka pole je dána konstantou velikosti délky jména a nulovým znakem. Rovněž i identifikátor říká že proměnná je pole znaků ukončené nulovým znakem.

Jednoduší by to nebylo, neboť počet znaků které může funkce scanf() načíst není spárovaná s konstantou. Když pak budu chtít měnit délku pole, neměním hodnotu uvnitř scanf(), což je špatně. Mohlo by to vést k nesprávné funkcí programu když se na to zapomene. Vhodně zvolenou konstantou toto mohu vyřešit.

Používání totožných jmen není úplně správné, ikdyž jazyk C má jasná pravidla kterou proměnnou použít. V příkladu je to v pořádku, neboť obojí jsou lokální proměnné a každá je tak viditelná ve své funkci. Práce s polem ve funkci je dáno tím, že se toto pole předává jako argument funkce a pracuje se s ním prostřednictvím jména parametru.

Odpovědět
22.6.2021 19:09
"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:22.6.2021 19:55

O tomto som nevedel: "Jednoduší by to nebylo, neboť počet znaků které může funkce scanf() načíst není spárovaná s konstantou."

Ako ale potom pri tvojom spôsobe ošetrím to, aby sa do poľa nenačítalo väčší počet znakov, než je jeho veľkosť (napr. ak by náhodou užívateľ mal dlhšie meno ako 20 písmen)?

 
Odpovědět
22.6.2021 19:55
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Martin Russin
DarkCoder:22.6.2021 21:19

Pokud je uvedena šířka u specifikace formátu pro řetězec ve funkci scanf(), může být načteno pouze uvedené množství znaků. Tato hodnota je součástí formátovacího řetězce funkce scanf(). Maximální délka pole je dána konstantou a s tou to je třeba spárovat.

Aby to bylo možné je třeba pokročilejších znalostí práce s řetězci. Konkrétně dvě věci:

  1. Dva sousední řetězce uzavřené mezi uvozovky jsou spojovány do jednoho.
  2. Převod číselné hodnoty na řetězec v čase kompilace.

První bod je jasný, netřeba více rozebírat. Snad jen pro ukázku:

"spojování" "řetězců"
// dává výsledek
"spojování řetězců"

Druhý bod je alfou a omegou celého řešení. Využívá se operátoru preprocesoru #, který převádí hodnotu na řetězec v čase kompilace.

Tedy se nejprve převede na řetězec hodnota makra a následně se řetězce spojí do jednoho, čímž vznikne dynamicky se měnící formátovací řetězec měnící hodnotu dle hodnoty definované konstanty zvenčí.

Tedy výsledek by mohl vypadat následovně:

scanf(#NAME_LIMIT "%s", jmeno);

což po zpracování preprocesorem přejde do následující podoby:

scanf("19%s", jmeno);

Hodnota ve formátovacím řetězci se mění dle hodnoty makra NAME_LIMIT.

Dále přesně vyjádřená hodnota makra NAME_LIMIT pomáhá snazšímu pochopení funkčnosti formátovacího řetězce funkce scanf(). Odpovídá počtu znaků které může tvořit jméno.

Tímto způsobem lze provázat hodnotu makra s částmi kódu, které využívají jeho hodnotu v určité podobě a vyhnout se tak chybám způsobených opomenutím změny kódu.

Ještě dodatek, pro práci s řetězci se než různé manipulování s možnostmi funkce scanf() používá funkce fgets(), jejíž jeden parametr je hodnota maximálního počtu načtených znaků.

Odpovědět
22.6.2021 21:19
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
DarkCoder:23.12.2023 14:41

Jedno z nejdůležitějších témat programování v jazyce C - Funkce, na kterých vše stojí, a přesto je článek bohužel pojat velmi stroze a nepřesně. Moderní C stojí na prototypech funkcí, o těch v článku není jediná zmínka. Proč? Funkce má obecný tvar jak by měla vypadat, opět chybí. Parametr a argument funkce jsou naprosto dvě odlišné věci které nelze zaměňovat, jak je chybně uvedeno v článku. Chybí popis toho co se ve funkci děje, jak to vůbec funguje. Čtenář dále může mít pocit, že definice funkcí jsou umístěny v hlavičkovém souboru, což samozřejmě není pravda. Do ukázkového příkladu dáváte předávání řetězce funkci, ale už zde není absolutně žádná zmínka ani odkaz na ukazatele. A mnoho dalšího neméně důležitého. Nováčci netuší na co se ptát a že vzniká otázek hodně. Je třeba jim to řádně vysvětlit!

Odpovědět
23.12.2023 14:41
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
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 7 zpráv z 17.