Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: vilém 15. 07. 2013, 10:45:41

Název: Funkcia v C - faktorial
Přispěvatel: vilém 15. 07. 2013, 10:45:41
Dobry den,

Vymyslel som si priklad na pouzivanie funkcii v jazyku C. Je to faktorial zadaneho cisla. Cize chcem aby mi napr pre 4! zobrazilo 4!=1x2x3x4.

Zdrojak udavam:

Kód: [Vybrat]
#include <stdio.h>

int otrok (int a)
{
  int i = 0;
  while ( i < a)
    i++;
  return i;
}

int main ()
{
  int i, j;
  printf ("Ja som mudry pocitac a viem zobrazit postupne cisla zadaneho faktorialu.\n");
  printf ("Zadaj cislo na zobrazenie vypoctu faktorialu: ");
  scanf ("%d", &i);
  printf ("\n");
  printf ("%d! = ", i);
  while (i >= 1)
  {
    j = otrok (i);
    printf ("%d", j);
    if (j > 0)
    {
      printf (" x ");
      i--;
    }
  }
  printf ("\n");
  printf ("\n");
}

Ono by to aj fungovalo. Po dvoch hodinach "maturovania" nad problemom som na nieco aj prisiel, ale cisla zobrazuje v opacnom poradi. (4! = 4x3x2x1)
Poprosil by som Vas znalych, aby ste mi pomohli s identifikaciou chyby.

Dakujem
Název: Re:funkcia v C - faktorial
Přispěvatel: matusss 15. 07. 2013, 11:16:08
Ahoj,

v cykle while (i >= 1) ides od i po 1. Pouzi v cykle novu premennu a chod s nou od 1 po i.

Po dalsie si pomenovavaj premenne aspon celymi slovami (pripadne aj viacslovne), neboj sa dlhsich nazvov, tvoj kod bude ovela citatelnejsi (kym nebudu nazvy cez polku monitora :D )

(este by som vytkol ze funkcia otrok vrati cislo, ktore dostane ako parameter, skus radsej spravit funkciu, ktorej posles cislo a ona vypise cely zoznam tych cisel (bude v nej cely tvoj while))
Název: Re:funkcia v C - faktorial
Přispěvatel: nuda 15. 07. 2013, 11:16:51
No ved ta funkcia otrok Ti vrati furt o jedno mensie ako predchadzajuca hodnota... cize to robis odzadu :D
ja by som v maine zmazal celu while pasaz, a funkciu otrok prerobil tak, aby v kazdom cykle po zvyseni i++, vysledok hned aj vypisala... cize take nieco(pseudo):

while(i<a)
{
  i++;
  print(i);
}

a v maine miesto tvojej while pasaze, iba dosad
otrok(zadaneCisloOdUzivatela);

tie detaily ako "x"za kazdym cislom a kecy okolo si hadam dorobis...
Název: Re:funkcia v C - faktorial
Přispěvatel: rob 15. 07. 2013, 11:19:35
Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>

int main() {
    int faktorial;
    printf("Zadej faktorial: ");
    if ( scanf ("%d", &faktorial) != 1 ) {
        printf("Spatny vstup.\n");
        return 1;
    }
    printf("\n");
    printf("%d=", faktorial);
    for( int i = 1;i < faktorial;++i) {
        printf("%dx", i);
    }
    printf("%d\n", faktorial);
    return 0;
}
Název: Re:funkcia v C - faktorial
Přispěvatel: insider 15. 07. 2013, 11:23:18
Nebylo by lepsi pouzit for cyklus? Kde zapisem for(j = 1;j <= i;j++) bys dostal posloupnost j = 1;...;j = i a tedy ve vypise pak 1x*x*... samozrejme whilem to vyjde nastejno, ale musis si hlidat ten radek s i--
Název: Re:funkcia v C - faktorial
Přispěvatel: vilém 15. 07. 2013, 11:45:48
Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>

int main() {
    int faktorial;
    printf("Zadej faktorial: ");
    if ( scanf ("%d", &faktorial) != 1 ) {
        printf("Spatny vstup.\n");
        return 1;
    }
    printf("\n");
    printf("%d=", faktorial);
    for( int i = 1;i < faktorial;++i) {
        printf("%dx", i);
    }
    printf("%d\n", faktorial);
    return 0;
}

Rob, ono ma to tiez takto napadlo, ale mne ide o precvicovanie si funkcii. Vcera som totiz na funkcie a ich schopnost "rozdeluj a panuj" (rozdel si problem na male casti a ries ich postupne) natrafil. A dnes sa zamyslam nad tym, ze ako to pouzit.
Název: Re:funkcia v C - faktorial
Přispěvatel: rob 15. 07. 2013, 11:50:53
tak to si naprogramuj funkci na serazeni posloupnosti celych cisel.
Pouzij algoritmus binarniho puleni a mas to procviceny :)
Název: Re:funkcia v C - faktorial
Přispěvatel: gamer 15. 07. 2013, 12:00:00
Vilém: s rozdělováním faktoriálu na fukce jsi na dobré cestě, jednou z tebe bude enterprise programmer ;):
http://dis.4chan.org/read/prog/1180084983/
Název: Re:Funkcia v C - faktorial
Přispěvatel: vilém 15. 07. 2013, 12:21:59
gamer: diky za povzbudenie. Moje snahy vsak vacsinou idu inym smerom Som po ukonceni studia na VS - odbor humanitnych vied - Anglicky a nemecky jazyk pre ZS a SS. Programovanie ma "dostalo" iba preto, lebo som pomahal bratrancovi rozpracovavat maturitne otazky z informatiky. Popri tom si zo mna robil zartiky, ze ovlada Pascal a HTML a PHP a ja nic. Tak ma to vytocilo a dnes som ho s vedomostami s programovania troska preskocil a hrajkam sa s funkciami. Napr. minuly tyzden to bolo nacitanie suboru a vykonanie nejakej operacie a ulozenie do ineho suboru.
Dalej zacinam tak troska s programovanim, aby si zo mna moji buduci ziaci neutahovali, ze oni vedia nieco, co ja nie. Od septembra (9. mesiac) zacinam totiz pracovat ako profesor AJ a NJ na priemyselnej skole elektrotechnickej.
Název: Re:Funkcia v C - faktorial
Přispěvatel: gamer 15. 07. 2013, 12:32:00
Podle mě sis nezvolil dobrý jazyk do začátku, C je pro začátečníka dost hardcore (ale o tom je tady flamewar v jiném vlákně...). Zkus se podívat i na python:
http://wiki.python.org/moin/BeginnersGuide/
Název: Re:Funkcia v C - faktorial
Přispěvatel: vilém 15. 07. 2013, 12:47:06
Ja viem, ze je to troska hardcore na zaciatok. Tiez mi odporucali Python. Najprv som zacal s Pythonom podla knizky Dive into Python 3 od Pilgrima. Avsak sposob jeho vysvetlovania bol pre mna nanajvys nevhodny. Okrem toho, mam prazdniny, cize vela casu.

Potom som vsak na nete natrafil na Ucebnicu jazyka C pre kvartu a kvintu 8-rocneho gymnazia od jedneho ucitela informatiky (Konkretne tu: http://www.smnd.sk/anino/moje/C.pdf (http://www.smnd.sk/anino/moje/C.pdf)) Tam bolo vsetko krasne vysvetlovane. Navyse tam boli aj cvicne ulohy - to prave orechove pre mna, aby som sa presvedcil, ze ci problematiku naozaj ovladam.
A kedze kvarta a kvinta su nejak 9. rocnik ZS/1. rocnik SŠ, tak som si povedal, ze to skusim.

Okrem toho, ako tak programujem, tak v C vidim zopar vyhod oproti Pythonu v tom, ze nepotrebujem po skompilovani kodu mat nejaky dodatocny interpreter ako v Pythone.

Okrem toho, este niektore odpovede na otazky hladam po nete a v knihe Jazyk C od Dalibora Kacmara.
Název: Re:Funkcia v C - faktorial
Přispěvatel: gamer 15. 07. 2013, 13:00:38
Z té knížky bych vybral jen jeden příklad, aby bylo vidět, jak dokáže být C záludné:
Kód: [Vybrat]
float uradnik(float r)
{
    float s;
    s = 3.1415926 * r * r;
    return( s );
}
Většina lidí si myslí, že se to bude počítat jako float, ale není to tak. 3.1415926 je totiž datový typ double, takže všechny argumenty toho výrazu (r) se převedou na double, výpočet se provede v double a nakonec se výsledek opět převede na float. Konverze float <-> double jsou hodně drahé, takže ve výsledku to bude mnohem pomalejší, než kdyby bylo všechno v double. Správný zápis té konstanty má být 3.1415926f.

gcc pro 3.1415926 vygeneruje tenhle kód:
Kód: [Vybrat]
uradnik:
.LFB11:
    .cfi_startproc
    unpcklps    %xmm0, %xmm0
    cvtps2pd    %xmm0, %xmm1
    movsd   .LC0(%rip), %xmm0
    mulsd   %xmm1, %xmm0
    mulsd   %xmm1, %xmm0
    unpcklpd    %xmm0, %xmm0
    cvtpd2ps    %xmm0, %xmm0
    ret
a pro 3.1415926f:
Kód: [Vybrat]
uradnik:
.LFB11:
    .cfi_startproc
    movaps  %xmm0, %xmm1
    movss   .LC0(%rip), %xmm0
    mulss   %xmm1, %xmm0
    mulss   %xmm1, %xmm0
    ret
Název: Re:Funkcia v C - faktorial
Přispěvatel: Karel 15. 07. 2013, 14:42:48
No, funkce otrok není zrovna dobrá jako příklad rozděl a panuj. Funkce, které zadám číslo a ona mi vrátí přesně to samé číslo. To je spíš metoda rozděl a panuj podle státní správy - když už není co dělit, tak se nějaká nová funkce vymyslí i když nic nedělá.

Doporučuji jednu věc, kterou "staří" programátoři ovládají poměrně dobře. Je to Desk Checking. Vemte si tužku, papír, a zkuste si ten program spustit "ručně". Prostě si ho odkrokujte tužkou na papír. Poměrně záhy tak objevíte zbytečnost funkce otrok a i vám bude jasné, proč výpis začíná nejvyšším číslem a klesá.

Programování není žádná alchymie. Obzvláště v C ne. Co v něm ale nefunguje je metoda pokus a omyl. Přepisovat + na -, vyměňovat for za while atd., tím se nikam nedostanete. V první řadě musíte pochopit, co vlastně chcete udělat. Pokud chcete vypsat čásla od 1 do N, tak vám musí být jasné, že začínáte u 1 a jdete nahodu. Začít na N a jít dolu těžko může produkovat požadovaný výsledek. I když i na to jsou triky, stačí vypsat zadanou hodnotu minus počitadlo, nebo to psát do pomocného řetězce zprava doleva.

A na závěr se přidávám k jednomu z diskutujících - zadaná úloha je natolik triviální, že na ni rozděl a panuj nelze efektivně použít. Tam prostě není co "delegovat", protože je tam výpočet jediný. Pomohlo by změnit trochu zadání - třebas aby se výpis prováděl rekurzivně.
Název: Re:Funkcia v C - faktorial
Přispěvatel: rob 15. 07. 2013, 14:53:22
No ten assembler mu urcite pomuze :-D

Hele pokud chces zacit s ceckem, musis si nastudovat dost teorie. Jak jsou ulozeny v pameti jednotlivy dat. typy, staticky/dynamicka alokace, dal pamet na zasobniku/halde, pointry na dat. typy/fce a pripadne aritmetika s nima. Konverze mezi dat. typy; struktury,uniony atd atd

Segfaulty a mem leaky nebudu tady rozvadet vubec :-D
Název: Re:Funkcia v C - faktorial
Přispěvatel: prezek 15. 07. 2013, 16:28:01
Hele, pokud chceš začít s céčkem, tak hlavně nesmíš studovat moc teorie (pokud tě na tom nezajímá právě ta teorie). Vědomosti "jak jsou ulozeny v pameti jednotlivy dat. typy, staticky/dynamicka alokace, dal pamet na zasobniku/halde, pointry ..." ti budou v začátku na nic.
Já se programováním už pár let živím a stejně ještě pořád ani nechápu, jak program Hello World ve Windows, nebo Linuxu funguje. Snad to pochopím dřív, než půjdu do důchodu.

Dobré je naučit se krokovat program v debugeru a sledovat, co se děje, případně krokovat program na papíře, jak psal Karel.
Název: Re:Funkcia v C - faktorial
Přispěvatel: Josef Pavlik 15. 07. 2013, 23:18:59
nevěř prezkovi. Jestli už pár let programuje a nepochopil, jak funguje hello world, tak ti nemá co říct. Kromě toho, debugger je sice krásná věc, ale v praxi je poměrně málo použitelný. Krokovat se dá tak leda právě ten hello world, ale na složitější programy se mi osvědčily debugovací hlášky. Prostě si do programu dám pár fprintf(stderr, "cyklus, i=5%", i); a pak se podívám co to při běhu vyhlašuje. Osvědčilo se mi to podstatně víc než krokování programu debugerem. Vyplatí se ti nechat většinu debugovacích hlášek i v produkční verzi programu a v případě potřeby je přesměrovat do file. Pak, když se klientovi někde něco podělá, tak se mrkneš kudy ten program chodil a kde byla chyba.
Ale hlavně, při programování (nejenom) v C bys měl vědět jak program funguje. Pokud to nevíš, tak těžko napíšeš program, který dělá víc než hello world a podobně.

příklad faktoriálu s rekurzí (bez kontroly počtu parametrů a rozsahu):
Kód: [Vybrat]
#include "stdio.h"
void print_fact(int n)
{
  if (n>1) { print_fact(n-1); printf("x"); }
  printf("%d", n);
}
main(int argc, char **argv)
{
  int n=atoi(argv[1]); // fixme - kontrolovat pocet parametru
  // fixme - kontrolovat rozsah hodnot
  printf("%d!=", n); print_fact(n); printf("\n");
}

Samozřejmě to bude žrát spoustu stacku, ale zato je to krátké.
Rekurze je krásná věc, ale v praxi je ve většině případů lepší použít cyklus. Ale zkuste třeba někdo napsat quicksort bez rekurze :-)
Název: Re:funkcia v C - faktorial
Přispěvatel: ApoC 16. 07. 2013, 07:29:13
tak to si naprogramuj funkci na serazeni posloupnosti celych cisel.
Pouzij algoritmus binarniho puleni a mas to procviceny :)

Binarni puleni se pouziva pro vyhledavani ne pro razeni.
Název: Re:Funkcia v C - faktorial
Přispěvatel: ApoC 16. 07. 2013, 07:38:18
Krokovat se dá tak leda právě ten hello world, ale na složitější programy se mi osvědčily debugovací hlášky. Prostě si do programu dám pár fprintf(stderr, "cyklus, i=5%", i); a pak se podívám co to při běhu vyhlašuje.

Umet pracovat s debuggerem je stene dulezite jako ovladat samotny programovaci jazyk. Pokud clovek vyviji nejaky slozitejsi kod, ktery se preklada radove treba 30 minut, tak pridani jakekoliv debug hlasky do implementace v header filu muzu zpusobit, ze budete debuggovat cely den a stejne prijdete na prd, protoze mate kod zaneradeny tolika vypisy, ze se v tom proste nevyznate a uz po destate prekladate binarku co se kompiluje 30 minut :).

Název: Re:funkcia v C - faktorial
Přispěvatel: Kolemjdoucí 16. 07. 2013, 07:45:50
Binarni puleni se pouziva pro vyhledavani ne pro razeni.

Quicksort je založen na binárním půlení.
Název: Re:Funkcia v C - faktorial
Přispěvatel: Kolemjdoucí 16. 07. 2013, 07:53:46
Kód: [Vybrat]
Ale zkuste třeba někdo napsat quicksort bez rekurze :-)
[/quote]

Levou zadní. V prostředích kde je málo paměti pro stack je dokonce nerekurzivní implementace quicksortu nutnost.
Název: Re:Funkcia v C - faktorial
Přispěvatel: and 16. 07. 2013, 12:56:41
Pokud clovek vyviji nejaky slozitejsi kod, ktery se preklada radove treba 30 minut, tak pridani jakekoliv debug hlasky do implementace v header filu muzu zpusobit, ze budete debuggovat cely den a stejne prijdete na prd, protoze mate kod zaneradeny tolika vypisy, ze se v tom proste nevyznate a uz po destate prekladate binarku co se kompiluje 30 minut :).

Mohl by jsi uvest priklad takto sloziteho projektu? I kernel se zvladne rychleji...

Ja rozhodne podporuji debug vypisy. Spusteny debuger jsem naposledy videl jen u embedded desek...
Název: Re:Funkcia v C - faktorial
Přispěvatel: gamer 16. 07. 2013, 13:23:11
Ja rozhodne podporuji debug vypisy. Spusteny debuger jsem naposledy videl jen u embedded desek...

Debug výpisem nenastavíš memory breakpoint, breakpoint při vyhození výjimky a podobné věci. Jinak bych ale používání debuggeru nepřeceňoval, moje zkušenost je taková, že projekty, u kterých bylo nutné často používat debugger, nekončily dobře.
Název: Re:Funkcia v C - faktorial
Přispěvatel: iwtu 16. 07. 2013, 13:57:56
Mily Vilem.
Super, ze si programujem len tak pre radost, z hanby ci nasrania. Rozdeluj a panuj neries, zvlast, pokial mas problemy s takymi ulohami ako tu pises.  Jednak ta tema nie je trivialna, druhak pri faktorialy je to ale uplne zbytocne, tretiak v praxi to cloveku treba malokedy. Aspon pre mna tak 10 rokov dozadu ta tema fakt nebola trivialna. Vybral si si C, lebo Ti viac sedelo, ok. No mozno by bolo lepsie sa odhladnut po nejakej inej ucebnici Pythonu. Ale ak sa Ti C paci a vyhovuje Ti v nom robit, tak potom asi uvazujes priamociaro a s C by si nemal mat problemy. Sice, nebudes mysliet na take veci ako spominal gamer, napriklad ta implicitna konverzia, ale to nevadi. Tym sa fakt teraz netrap. C je jednoduchy jazyk, ak clovek uvazuje priamociaro, lebo tam nie je skoro ziadna magia. Aj tie pointre su v principe jednoduche a vo svojich malych programikoch by si s nimi nemal mat problem. Teda bez do C. Velmi Ti moze pomoct Ucebnica jazyka C od Herouta. Sice jeden znamy guru vravel, ze Herout tomu C az tak nerozumie, ale to su uz ludia uplne niekde a inde a ja v C nie som doma. Jo, a este jedna vec. Keby bol ucitel a moji studetni by vedeli nieco, co ja nie, tak by som mal z toho velku radost :)

Ak chces riesit C, do toho ale rozdeluj a panuj teraz este neries. Najprv zvladni ako tak C :-)

Drz sa.
Název: Re:Funkcia v C - faktorial
Přispěvatel: prezek 16. 07. 2013, 14:08:34
Josef Pavlik: Dokážeš mi pospat, jak se Hello World tahá do paměti? Která knihovna, či jaká část kernelu a jak se stará o to, aby printf začernil/zabělil/vystínoval určitý pixel? Jak se přepíná kontext mezi současně běžícími aplikacemi? Jak se předávají vstupní parametry a návratové hodnoty? U mikrokontrolerů bez operačního systému jakž-takž chápu, jak Hello World funguje, ale jak to probíhá na čemkoliv s operačním systémem, to je mi záhadou.
Název: Re:Funkcia v C - faktorial
Přispěvatel: Josef Pavlik 16. 07. 2013, 18:24:12
jak se hello world taha do pameti, to zalezi na operacnim systemu a/nebo loaderu. Napriklad v CP/M nebo v MSDOS (v pripade programu.com) se napred program natahne do pameti od adresy 0x100 a pak se spusti od te same adresy. Na ni vetsinou byva skok na zacatek inicializacnich rutin programu.

V linuxu je to zajimavejsi. program se napred spusti a teprve potom se natahne :-). Zjednodusene receno se program namapuje do urciteho mista pameti (coz je prakticky zavolani jednoho syscallu, ktery zinicializuje swapovaci tabulky). Pak se skoci na zacatek tohoto bloku. Pokus o cteni nebo vykonani kodu ve frame pameti, kde neni namapovana zadna fyzicka stranka vede k vyjimce (interrupt), ktera je obsouzena kernelem. Ten do prislusneho frame namapuje fyzickou stranku pameti (kde ji vezme je namet na dalsi kapitolu). Pokud se ukaze, ze tento frame je namapovany na urcity file (text programu), jednoduse se tato cast programu precte z disku a zapise do pameti. Pokud naopak tato adresa mela obsahovat globalni promenne, tato stranka se vynuluje, pripadne zinicializuje.
 
Jak printf zacerni/zabeli/vystinuje urcity pixel? Jednoduse nijak. Printf tady neni proto, aby se staral o takovehle veci. O tohle se stara VGA v pripade textoveho rezimu, pripadne X server v pripade grafickeho rezimu (embeded graficke programy ted nechame stranou). Printf je funkce libc. Prevezme parametry, na jejich zaklade vygeneruje output string a s nim zavola funkci puts nebo fwrite. Tyto dve posledni funkce vedou na zavolani syscallu kernelu, ktery uz to posle na VGA nebo pres nejake presmerovani do X nebo jineho grafickeho serveru.

Jak se prepina kontext mezi soucasne bezicimi aplikacemi? To je zalezitost kernelu, to muzes maximalne lehce ovlivnit, ale tezko se do toho hrabe.

Jak se predavaji parametry a navratove hodnoty (predpokladam, ze mas na mysli parametry funkci) - vetsinou na stacku, navratova hodnota se pravdepodobne predava v registru (pokud se nejedna o strukturu). Je to zajimava otazka, tohle je jedna z veci, ke kterym je debuger uzitecny. Tady bude taky dost zalezet na parametrech kompilatoru.

Ja samozrejme nerikam, ze debuger neni vubec k nicemu, obcas pouzivam ddd, ale pouzivam ho tak jednou za rok.


Pokud chces vedet ktere knihovny se tahaji z urcitemu programu, tak na to je ldd. Tohle je napriklad ten programek na faktorial, ale stejne to bude pro jakykoliv C program, kde nepotrebujes jine knihovny nez libc.
root@moonlight:/tmp# ldd ./f
        linux-gate.so.1 =>  (0xb7738000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb756e000)
        /lib/ld-linux.so.2 (0xb7739000)
co je to linux-gate.so.1 nemam tuseni, pravdepodobne je to interface na volani kernelu. ld-linux.so.2 je loader a libc.so.6 obsahuje vsechny standardni C funkce jako printf, qsort a podobne.

Název: Re:Funkcia v C - faktorial
Přispěvatel: ogar 16. 07. 2013, 21:48:30
Pokud by jsi to chtel s rekurzi, ktera faktorial vypocita a pritom jenom tak nahodou pri navratu z rekurze zobrazi i tu posloupnost:
Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>

static
int fakt(int x){
int Result;

if (x<=1){
Result=1;
printf("1");
}
else{
Result=x*fakt(x-1);
printf("*%d",x);
}

return Result;
}

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

printf("Enter number:");
Result=scanf ("%d", &x);
printf("\n");

if (Result==1){ // something acceptable
printf("%d!=",x);
Result=fakt(x);
printf("=%d\n",Result);
}

return 0;
}

Ale jak uz tady nekolikrat zaznelo: dulezite je vedet co chces dosahnout (co ma program delat), pak si poradne promyslet, jak to efektivne udelat a pak uz je jedno, v jakem jazyce to naprogramujes :-)

Ono pri tom reseni je dobre si problem rozlozit na vice mensich, ktere se daji resit vicemene samostatne a paralelne.
Ale pak je duelzite vybalancovat pomer mezi mnozstvim jednotlivych kousku/komponent a jejich rozhrannim:
Na jedne strave je klasicky spagheti kod, a nad druhe treba java, kdy na kazdy 'prd' sa dela specialni trida s 'kosatym interface' (milion funkci a frameworku), a pak sa vyslednem kodu a factory constructor factory maker .... (nejenom) clovek ztrati :-)
Název: Re:Funkcia v C - faktorial
Přispěvatel: ogar 16. 07. 2013, 21:51:21
Pokud by jsi to chtel s rekurzi, ktera faktorial vypocita a pritom jenom tak nahodou pri navratu z rekurze zobrazi i tu posloupnost:
Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>

static
int fakt(int x){
int Result;

if (x<=1){
Result=1;
printf("1");
}
else{
Result=x*fakt(x-1);
printf("*%d",x);
}

return Result;
}

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

printf("Enter number:");
Result=scanf ("%d", &x);
printf("\n");

if (Result==1){ // something acceptable
printf("%d!=",x);
Result=fakt(x);
printf("=%d\n",Result);
}

return 0;
}

Ale jak uz tady nekolikrat zaznelo: dulezite je vedet co chces dosahnout (co ma program delat), pak si poradne promyslet, jak to efektivne udelat a pak uz je jedno, v jakem jazyce to naprogramujes :-)

Ono pri tom reseni je dobre si problem rozlozit na vice mensich, ktere se daji resit vicemene samostatne a paralelne.
Ale pak je duelzite vybalancovat pomer mezi mnozstvim jednotlivych kousku/komponent a jejich rozhrannim:
Na jedne strave je klasicky spagheti kod, a nad druhe treba java, kdy na kazdy 'prd' sa dela specialni trida s 'kosatym interface' (milion funkci a frameworku), a pak sa vyslednem kodu a factory constructor factory maker .... (nejenom) clovek strati :-)