NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Parametry v C - doporučte prosím z čeho se učit

V předchozím kvízu, Online test znalostí C++, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
Jirka
Člen
Avatar
Jirka:13.1.2018 15:50

Ahoj,
mohli byste prosím doporučit nějakou stránku, případně něco v PDF, z čeho bych se mohl začít učit parametry v C?
Našel jsem si k tomu pár materiálů, ale nejsem absolutně schopen to pochopit.
Hodilo by se mi něco s nějakými jednoduchými příklady vč. vysvětlivek, neboť je to jedna část zkoušky a já na tom absolutně vyhořim.
Děkuju moc.

 
Odpovědět
13.1.2018 15:50
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:13.1.2018 18:01

Funkce jsou kostrou programu v jazyce C. Zdrojů, odkud čerpat znalosti, bude jistě hodně. S parametry souvisí mnoho pojmů. To nejdůležitější je vědět co hledat a vědět co je:

obecný formát funkce, argument funkce, prototyp funkce, deklarace, formální parametr, skutečný parametr, procedura, parametrizovaná funkce, void, návratová hodnota, volání funkce, funkce s proměnným počtem parametrů, předběžná deklarace, volání hodnotou, volání odkazem, a další...

To nejpodstatnější je, zda-li se má obsah proměnné měnit či nikoli.

Co konkrétně potřebuješ pochopit?

Nahoru Odpovědět
13.1.2018 18:01
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Štefan Melich:13.1.2018 18:26

Učebnice jazyka C od Pavla Herouta je asi najlepšia učebnica. Nájdeš ju ľahko aj ako pdf.

 
Nahoru Odpovědět
13.1.2018 18:26
Avatar
Jirka
Člen
Avatar
Jirka:13.1.2018 20:22

Ahoj, díky oběma.
Mám udělanou kalkulačku a mám tam použít i parametry, tzn. že jí pustím z konzole a zadám tam třeba "/f 10".
f by byl třeba faktoriál, takže faktoriál čísla 10.

Teď jí mám udělanou obyčejně, že zadám v menu třeba číslo 9 pro faktoriál a pak zadám číslo, třeba 10.
Kód mám na 1530 řádků, ale dát ho sem klidně můžu, pokud byste ho chtěli vidět.
Je teda hodně neupravenej a není psanej hezky, spíš jen aby to splňovalo podmínku 1500ti řádků (taky k té zkoušce). Zkrátit bych ho mohl, ale to teď zatím ne.

Jediný co zatím mám, že v Mainu je "int argc, char** argv". Zkusím se v tom teď navečer ještě trochu pohrabat, spíš mám strach abych to nemusel celý nějak předělávat, když jsem s tím nepočítal hnedka od začátku.

Ty parametry by stačili třeba na pár funkcí, kdyby to bylo časově složitý na předělání, spíš abych to chápal a pak uměl vysvětlit. Mám tam 60 casů.

 
Nahoru Odpovědět
13.1.2018 20:22
Avatar
Jirka
Člen
Avatar
Jirka:13.1.2018 20:39

Vypadá to nějak takto.

int main(int argc, char** argv)
{
.........

case 9: // faktorial
                printf("Zadej cislo: ");
                scanf("%ld", &prvnicislofaktorial);
                if (prvnicislofaktorial < 0)
                {
                        printf("Faktorial nelze pro zaporne cislo spocitat\n");
                        return 0;
                }
                else
                {
                        for (int i = 1; i <= prvnicislofaktorial; ++i)
                        {
                                faktorial *= i; // faktorial = faktorial * i;
                        }
                        printf("Faktorial cisla %ld je %llu\n", prvnicislofaktorial, faktorial);
                }
                printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
                fseek(stdin, 0L, SEEK_END);
                zapis = getchar();
                if ((zapis == 'Y') || (zapis == 'y'))
                {
                        printf("Zapisuji...\n");
                        fprintf(soubor, "Faktorial cisla %ld je %llu\n", prvnicislofaktorial, faktorial);
                }
                break;
}

Potřeboval bych mu pak říct přes tu konzoli, aby udělal ten faktoriál. Mám tu stažený nějaký program, kde už to je, ale nejsem schopnej si to ani vyvodit :(.

 
Nahoru Odpovědět
13.1.2018 20:39
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:13.1.2018 21:07

Pokud chceš využívat možnosti načtení argumentů z příkazového řádku, pak funkce main() má tvar:

int main(int argc, char *argv[]){
  //...
return 0;
}

To ale není to co bys měl v programu hlavně udělat.

Způsob, jakým volit operaci, měnit nemusíš. Ten je v pořádku.
Ale jednotlivé operace by bylo dobré mít v podobě funkcí.

Tak například pro faktoriál by prototyp funkce mohl vypadat následovně:

long factorial(int n);
Editováno 13.1.2018 21:08
Nahoru Odpovědět
13.1.2018 21:07
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Jirka
Člen
Avatar
Jirka:13.1.2018 21:25

Takže by to mělo vypadat nějak takto?

lcase 9: // faktorial
                long factorial(int n);
                printf("Zadej cislo: ");
                scanf("%ld", &prvnicislofaktorial);
                if (prvnicislofaktorial < 0)
                {
                        printf("Faktorial nelze pro zaporne cislo spocitat\n");
                        return 0;
                }
                else
                {
                        for (int i = 1; i <= prvnicislofaktorial; ++i)
                        {
                                faktorial *= i; // faktorial = faktorial * i;
                        }
                        printf("Faktorial cisla %ld je %llu\n", prvnicislofaktorial, faktorial);
                }
                printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
                fseek(stdin, 0L, SEEK_END);
                zapis = getchar();
                if ((zapis == 'Y') || (zapis == 'y'))
                {
                        printf("Zapisuji...\n");
                        fprintf(soubor, "Faktorial cisla %ld je %llu\n", prvnicislofaktorial, faktorial);
                }

                break;
 
Nahoru Odpovědět
13.1.2018 21:25
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:13.1.2018 21:30

Chybí Ti tam inicializace proměnné faktoriál na hodnotu 1.
Funkce na faktoriál by pak mohla vypadat třeba takto:

long factorial(int n){
        int i;
        long result = 1L;

        if (n<0) return 0L;
        for (i = 1; i <= n; i++) result *= i;
        return result;
}

Podotýkám, že funkce není ošetřena zprava a může dojít k přesahu typu long.

Nahoru Odpovědět
13.1.2018 21:30
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Jirka
Člen
Avatar
Jirka:13.1.2018 21:32

Když to udělám stejně jako to máš ty, tak mi to vždycky podtrhne ten long :(

case 9: // faktorial
                long factorial(int n)
                {
                printf("Zadej cislo: ");
                scanf("%ld", &prvnicislofaktorial);
                if (prvnicislofaktorial < 0)
                {
                        printf("Faktorial nelze pro zaporne cislo spocitat\n");
                        return 0;
                }
                else
                {
                        for (int i = 1; i <= prvnicislofaktorial; ++i)
                        {
                                faktorial *= i; // faktorial = faktorial * i;
                        }
                        printf("Faktorial cisla %ld je %llu\n", prvnicislofaktorial, faktorial);
                }
                printf("Prejes si zapsat vysledek do souboru? Y pro ANO / N pro NE\n");
                fseek(stdin, 0L, SEEK_END);
                zapis = getchar();
                if ((zapis == 'Y') || (zapis == 'y'))
                {
                        printf("Zapisuji...\n");
                        fprintf(soubor, "Faktorial cisla %ld je %llu\n", prvnicislofaktorial, faktorial);
                }
                }

                break;
 
Nahoru Odpovědět
13.1.2018 21:32
Avatar
DarkCoder
Člen
Avatar
Odpovídá na DarkCoder
DarkCoder:13.1.2018 21:39

Prototypy funkcí je dobré uvádět na začátku programu po vložení hlavičkových souborů. Nebo ještě lépe v samostatném modulu (.h). Pokud už děláš takto komplexní program, bylo by to elegantnější řešení.
Ale pokud to uděláš následovně:

/* hlavickove soubory */

/* prototypy funkci */

int main(int argc, char * argv[]){
//...
}

/* definice funkci */

Tak to bude obstojné a v pořádku.

Nahoru Odpovědět
13.1.2018 21:39
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Jirka
Člen
Avatar
Jirka:13.1.2018 21:47

Takže ten case 9, tedy celý faktoriál mám šoupnout nad Main? Takhle to tam budu přeci 2x, ne?

 
Nahoru Odpovědět
13.1.2018 21:47
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:13.1.2018 21:57

Podívej na následující kód, je v něm pouze výpočet a výpis hodnoty faktoriálu bez omáčky:

#define _CRT_SECURE_NO_WARNINGS

// headers
#include <stdio.h>

// prototyps
long factorial(int n);

int main(int argc, char *argv[]) {
        long factout;
        int factin;

        printf("Zadej cislo: ");
        scanf("%d", &factin);
        factout = factorial(factin);
        printf("Faktorial cisla %d = %ld\n", factin, factout);

        return 0;
}

// factorial fce
long factorial(int n) {
        int i;
        long result = 1L;

        if (n<0) return 0L;
        for (i = 1; i <= n; i++) result *= i;
        return result;
}
Editováno 13.1.2018 21:57
Nahoru Odpovědět
13.1.2018 21:57
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Jirka
Člen
Avatar
Odpovídá na DarkCoder
Jirka:13.1.2018 22:23

Děkuju. A jak ho prosím spustím s těmi parametry přes konzoli? Dostat se k programu pomocí příkazu cd umím, spustit taky, ale máme to spouštět ještě přímo z té řádky, např tedy zadat -faktorial 10. Zkoušel jsem to teď pár kombinacemi a nedaří se mi to.

 
Nahoru Odpovědět
13.1.2018 22:23
Avatar
Jirka
Člen
Avatar
Jirka:13.1.2018 23:12

Mám od začátku namysli parametry příkazovýho řádku, asi jsem to napsal prve špatně, když jsem to nenapsal.

 
Nahoru Odpovědět
13.1.2018 23:12
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:13.1.2018 23:19

Za předpokladu, že aplikace se jmenuje fact.exe, bys program z příkazové řádky pak spouštěl následovně:

fact.exe -faktorial <hodnota> tedy např. fact.exe -faktorial 10

a kód bys upravil následovně:

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

int main(int argc, char *argv[]) {
        long factout;

        if ((argc != 3) || (strcmp(argv[1],"-faktorial"))) exit(1);
        factout = factorial(atoi(argv[2]));
        printf("Faktorial cisla %d = %ld\n", atoi(argv[2]), factout);

        return 0;
}
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
13.1.2018 23:19
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Jirka
Člen
Avatar
Jirka:14.1.2018 11:20

Ahoj, děkuju moc. Našel jsem si k tomu vysvětlivky a mám pocit že to i chápu a v mém programu mi to taky funguje, tak snad to budu chápat i u zkoušky :-) Ještě jednou díky!
Kdyžtak bych to tu ještě v případě potřeby trochu zaspamoval, ale snad si s tím co tu je vystačím.

Editováno 14.1.2018 11:21
 
Nahoru Odpovědět
14.1.2018 11:20
Avatar
Jirka
Člen
Avatar
Jirka:14.1.2018 13:38

Ahoj,
tak jsem ještě narazil.. nevíš prosím kde by mohla být chyba? Pokouším se to samé udělat pro součet čísel.

Toto mám nahoře:

if ((argc != 4) || (strcmp(argv[1], "-soucet"))) // argc predstavuje pocet argumentu prikazove radky, zde musi byt tedy 3
        {
                exit(1); // indicates unsuccessful termination
        }
        vysledeksouctu = factorial(atoi(argv[2]) & (atoi(argv[3]))); // argv[2] ukazuje na treti retezec, tedy cislo
        //vysledeksouctu = factorial(atoi(argv[3]));
        printf("Soucet cisel je %ld\n", vysledeksouctu); // The C library function int atoi converts the string argument to an integer (type int)
        return 0;

Toto dole:

float soucetcisel(int a, int b)
{
        float vysledeksouctucisel;

        if ((a < 0) || (b < 0))
        {
                return 0;
        }
        else
        {
                vysledeksouctucisel = a + b;
        }
}

Když zadám parametry, tedy "test -soucet 5 2", tak mi to nic nevypíše a hodí mě to o krok zpět.
Zkoušel jsem s tím trochu čachrovat ale nic jsem nevymyslel :(.
Dělám to stejně jako ty, ale někde asi dělám pořád chybu.

Editováno 14.1.2018 13:39
 
Nahoru Odpovědět
14.1.2018 13:38
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na Jirka
ostrozan:14.1.2018 14:13

V bloku else ti chybí return

 
Nahoru Odpovědět
14.1.2018 14:13
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na DarkCoder
ostrozan:14.1.2018 14:26

Chybí ti tam jedna podstatná informace, která se ho dost týká :
Deklarace prototypu funkce, natož její definice není možná v těle jiné funkce - což evidentně udělal a proto mu to házelo chybu

 
Nahoru Odpovědět
14.1.2018 14:26
Avatar
Jirka
Člen
Avatar
Jirka:14.1.2018 14:31

Ono mi to nejede ani s tim returnem :(

 
Nahoru Odpovědět
14.1.2018 14:31
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:14.1.2018 15:17

Pokud sloučím oba dva své příspěvky (čas 21.57 a čas 23.19) do jednoho, vypadá výsledný kód takto:

// faktorial z prikazove radky

#define _CRT_SECURE_NO_WARNINGS

// headers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// prototyps
long factorial(int n);

int main(int argc, char *argv[]) {
        long factout;

        if ((argc != 3) || (strcmp(argv[1], "-faktorial"))) exit(1);
        factout = factorial(atoi(argv[2]));
        printf("Faktorial cisla %d = %ld\n", atoi(argv[2]), factout);

        return 0;
}

// factorial fce
long factorial(int n) {
        int i;
        long result = 1L;

        if (n<0) return 0L;
        for (i = 1; i <= n; i++) result *= i;
        return result;
}
Nahoru Odpovědět
14.1.2018 15:17
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Jirka
Člen
Avatar
Jirka:14.1.2018 15:19

Jo, jo, já to tak mám a funguje mi to perfektně :-). Akorát mi to nefunguje, když jsem se to pokoušel dělat pro součet dvou čísel viz příspěvek ve 13:38.
Snažil jsem se to z toho odvodit ale nevidím v tom chybu :(
Když zadám ten parametr pro součet tak to neudělá nic.

Editováno 14.1.2018 15:20
 
Nahoru Odpovědět
14.1.2018 15:19
Avatar
DarkCoder
Člen
Avatar
Odpovídá na ostrozan
DarkCoder:14.1.2018 15:35

Z příspěvku který poslal není žádný náznak toho, že by provedl deklaraci či definici funkce v těle jiné funkce. Ve zkratce shrnu, že to co provedl bylo chybné volání funkce, nikoli definice ani deklarace. Chyb je tam více, ale o tom se rozepíši v samostatném příspěvku.

Nahoru Odpovědět
14.1.2018 15:35
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:14.1.2018 15:52

Takto to máš samostatně pro součet:

// soucet z prikazove radky

#define _CRT_SECURE_NO_WARNINGS

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

// prototyp fce soucet - deklarace funkce
int soucet(int m, int n);

int main(int argc, char *argv[]) {

        if ((argc != 4) || (strcmp(argv[1], "-soucet"))) exit(1);
        // Jako argument funkce printf je pouzito volani fce soucet
        printf("Soucet cisel %d a %d = %d\n", atoi(argv[2]), atoi(argv[3]), soucet(atoi(argv[2]), atoi(argv[3])));

        return 0;
}

// fce soucet - definice funkce
int soucet(int m, int n) {
        return m + n;
}
Nahoru Odpovědět
14.1.2018 15:52
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Jirka
Člen
Avatar
Jirka:14.1.2018 16:16

Tak mi to furt nejde. Vypadá to nějak takto:

long factorial(int n);
int soucet(int m, int n);

int main(int argc, char** argv[]) {

        Tady je hromada promennych atd...

        // faktorial
        if ((argc != 3) || (strcmp(argv[1], "-faktorial"))) // argc predstavuje pocet argumentu prikazove radky, zde musi byt tedy 3
        {
                exit(1); // indicates unsuccessful termination
        }
        vysledekfaktorial = factorial(atoi(argv[2])); // argv[2] ukazuje na treti retezec, tedy cislo
        printf("Faktorial cisla %d = %ld\n", atoi(argv[2]), vysledekfaktorial); // The C library function int atoi converts the string argument to an integer (type int)
        return 0;

        // soucet cisel
        if ((argc != 4) || (strcmp(argv[1], "-soucet"))) exit(1);
        // Jako argument funkce printf je pouzito volani fce soucet
        printf("Soucet cisel %d a %d = %d\n", atoi(argv[2]), atoi(argv[3]), soucet(atoi(argv[2]), atoi(argv[3])));

        return 0;
} // konec main

// faktorial funkce
long factorial(int n)
{
        int i;
        long result = 1;

        if (n < 0)
        {
                return 0;
        }
        for (i = 1; i <= n; i++)
        {
                result *= i;
        }
        return result;
}

// soucet funkce
int soucet(int m, int n)
{
        return m + n;
}

Faktoriál mi to provede, ale ten součet stále ne.

Do konzole píšu "test -soucet 2 3".

Editováno 14.1.2018 16:17
 
Nahoru Odpovědět
14.1.2018 16:16
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:14.1.2018 17:04

Ahoj, tak jsem ještě narazil.. nevíš prosím kde by mohla být chyba? Pokouším se to samé udělat pro součet čísel.

Jak by to mohlo vypadat pro součet čísel jsem již uvedl v předchozím příspěvku.
Teď bych se chtěl hlavně vyjádřit k chybám a k tomu proč se Ti to nepodařilo zprovoznit.

Než používat pojmy "dole" a "nahoře" je lepší používat pojmy uvnitř funkce a vně funkce.
Dále pro práci s funkcemi potřebuješ znát následující pojmy - prototyp funkce, deklarace funkce, definice funkce a volání funkce.

Začnu samotnou definicí funkce. To jakého typu bude její návratová hodnota a parametry, je jen na tobě. To hlavní, co by tato funkce měla mít a co ti tam chybělo a již to zmínil ostrozan, je její návratová hodnota. Tu tam sice máš ale ne pro výsledek ale pro omezení platnosti funkce. Navíc sčítat můžeme i záporná čísla a tak je tato podmínka nesprávná. Else navíc není potřeba, pokud jej v tomto případě neuvedeš bude kód efektivnější (bude se zpracovávat méně instrukcí).

Prototyp je deklarací funkce a je důležitý. Informuje program o správném použití funkce (Dříve než je funkce použita zná informace o počtu a typy parametrů a tedy nesrovnalost ve volání funkce může být odchycena).

Navrácení hodnoty můžeš udělat dvěma způsoby. S tím souvisí kromě návratové hodnoty znalost pojmů: volání hodnotou, volání odkazem a formální parametr, skutečný parametr.

První způsob za pomocí return kde prototyp funkce vypadá takto:

int soucet(int m, int n);

Výsledek funkce pak můžeš přiřadit nějaké proměnné za pomoci volání funkce (viz. ukázky kódů výše).
m a n jsou formální parametry funkce a používá se zde volání hodnotou. Návratová hodnota se získává použitím příkazu return.

Druhý způsob za pomoci volání odkazem kde prototyp funkce vypadá takto:

void soucet(int m, int n, int *vysl);

Zde výsledek funkce přímo přiřazuješ nějaké proměnné jejíž adresa je uvedena jako skutečný parametr funkce při volání funkce. Zde se používá volání odkazem. V tomto případě se už nepoužívá návratová hodnota funkce proto je použit datový typ void. Volání funkce pak vypadá následovně:

soucet(5, 10, &x);

Kde do proměnné x se uloží výsledek součtu hodnot 5 a 10.

V sekci ve volání funkce mícháš dvě funkce které spolu nesouvisí (faktoriál a součet). Faktoriál tam být vůbec nemá. Používáš bitový součin & který v příkladu vůbec nepotřebuješ. Pokud chci do proměnné přiřadit výsledek součtu argumentů zadaných z příkazové řádky pak bych použil toto:

vysledek = soucet(atoi(argv[2]), atoi(argv[3]));

Typ proměnné výsledek je důležitý a měl by korespondovat s návratovým typem funkce soucet()! Pokud by tomu tak nebylo, dochází k implicitné konverzi typu pravé strany na typ levé strany, což může v některých případech vést k chybě programu (některé konverze jsou nepovolené). V lepším případě dostaneš nesmyslnou hodnotu. V nejlepším případě dosáhneš správného výsledku, ale způsob, jakým toho bylo dosaženo je nesprávný. Nakonec při volání funkce znát typ návratové hodnoty a tedy použít správný specifikátor formátu ve funkci printf() (%ld pro long, %d pro int, %f pro float a double, atd).

Nahoru Odpovědět
14.1.2018 17:04
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:14.1.2018 17:38

Chybně definuješ funkci main(), ve druhém parametru máš hvězdičku navíc. Správně je:

int main(int argc, char *argv[])

Pokud zadáváš argumenty na příkazové řádce, musíš znát povolené kombinace programem.
Tvé současné povolené kombinace programem jsou:

test.exe -faktorial <hodnota> tedy např. test.exe -faktorial 10
test.exe -soucet <hodnota> <hodnota> tedy např. test.exe -soucet 2 3

v prvním případě může funkce přijmout 3 argumenty, ve druhém 4.

Podívej co se stane, když budu chtít provést operaci součet a zadám: test.exe -soucet 2 3

Podmínka:

if ((argc != 3) || (strcmp(argv[1], "-faktorial"))) exit(1);

Způsobí ukončení programu protože zadáváš 4 argumenty kdežto program testuje na 3.

Výraz:

(argc != 3)

je vyhodnocen jako pravdivý (4!=3) a automaticky ukončuje (exit). Zbylé výrazy v podmínce už ho ani nezajímají.

kód musíš upravit tak, aby program dokázal zpracovat operace na základě hodnoty druhého argumentu a odlišného počtu argumentů.

Ještě jedna věc, je dobré nemíchat způsoby výpisu výsledku operace. Způsob jaký jsem uvedl u operace součet byl ukázán pro zajímavost, že není třeba vůbec definovat proměnnou. Doporučuji druhý způsob (u operace součet). Důvodem je že každá funkce vrací odlišný typ, ušetříš paměť za defici proměnných.

Nahoru Odpovědět
14.1.2018 17:38
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Jirka
Člen
Avatar
Jirka:14.1.2018 18:07

Ahoj, děkuju za vyčerpávající odpovědi, pokusím se to upravit jak říkáš. Nevíš prosím jak to tedy udělat, aby mi nekolivdovaly ty argumenty, viz

//faktorial
if ((argc != 3) || (strcmp(argv[1], "-faktorial"))) // argc predstavuje pocet argumentu prikazove radky, zde musi byt tedy 3
        {
                exit(1); // indicates unsuccessful termination
        }
        vysledekfaktorial = factorial(atoi(argv[2])); // argv[2] ukazuje na treti retezec, tedy cislo
        printf("Faktorial cisla %d = %ld\n", atoi(argv[2]), vysledekfaktorial); // The C library function int atoi converts the string argument to an integer (type int)
        return 0;

        // soucet cisel
        if ((argc != 4) || (strcmp(argv[1], "-soucet"))) exit(1);
        // Jako argument funkce printf je pouzito volani fce soucet
        printf("Soucet cisel %d a %d = %d\n", atoi(argv[2]), atoi(argv[3]), soucet(atoi(argv[2]), atoi(argv[3])));

        return 0;

Když jsem faktoriál zakomentoval, tak se mi součet provede, jen nevím, jak to oddělit :(.
Pokouším se to porovnávat zda argv = "-faktorial" nebo "-soucet", ale vždycky mi to spadne.

 
Nahoru Odpovědět
14.1.2018 18:07
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Jirka
DarkCoder:14.1.2018 18:29

Pokud máš na výběr z více variant, nesmíš ukončit program dřív než projdeš všechny kombinace. Použití funkce exit() je v tomto případě nesprávné. Test podmínek musíš v tomto případě obrátit. Níže přikládám kód:

// soucet a faktorial z prikazove radky

#define _CRT_SECURE_NO_WARNINGS

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

long factorial(int n);
int soucet(int m, int n);

int main(int argc, char *argv[]) {

        if ((argc == 3) && (!strcmp(argv[1], "-faktorial"))) printf("Faktorial cisla %d = %ld\n", atoi(argv[2]), factorial(atoi(argv[2])));
        else if((argc == 4) && (!strcmp(argv[1], "-soucet"))) printf("Soucet cisel %d a %d = %d\n", atoi(argv[2]), atoi(argv[3]), soucet(atoi(argv[2]), atoi(argv[3])));

        return 0;
}

long factorial(int n) {
        int i;
        long result = 1L;

        if (n<0) return 0L;
        for (i = 1; i <= n; i++) result *= i;
        return result;
}

int soucet(int m, int n) {
        return m + n;
}
Nahoru Odpovědět
14.1.2018 18:29
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
ostrozan
Tvůrce
Avatar
Odpovídá na DarkCoder
ostrozan:14.1.2018 18:31

V tom případě se podívej ještě jednou a lépe :)
Hned na prvním řádku máš

case 9: // faktorial

Co bys řekl, že to je?
Já myslím, že část switche, který pravděpodobně nevisí v luftě, ale je v těle funkce - dokonce funkce main, jak je vidět v příspěvku o něco výše (20:39)
Ale na druhou stranu - tyhle manýry začátečníků, kteří si nevím z jakého důvodu myslí, že když přehodí útržky kódu bez jakýchkoliv souvislostí, tak případným lidem ochotným pomoct "zjednoduší" práci taky nemám moc rád.

Editováno 14.1.2018 18:33
 
Nahoru Odpovědět
14.1.2018 18:31
Avatar
DarkCoder
Člen
Avatar
Odpovídá na ostrozan
DarkCoder:14.1.2018 18:48

Ano, tam se jednalo o deklaraci funkce na nesprávném místě. To však už bylo řešeno ve dvou následujících příspěvcích (21.39 a 21.57). To se týkalo ještě způsobu provádění operace přímo v programu. Další části se již týkaly řešení načtení z příkazové řádky. Tvůj příspěvek o chybějícím příkazu return se jistě vztahuje k příspěvku v čase 13.38 začínající:

Ahoj, tak jsem ještě narazil.. nevíš prosím kde by mohla být chyba? Pokouším se to samé udělat pro součet čísel.

A tady opravdu žádná deklarace ani definice funkce v jiné funkci není.

Nahoru Odpovědět
14.1.2018 18:48
"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 31 zpráv z 31.