Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?

[es] :: C/C++ programiranje :: C/C++ za početnike :: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?

[ Pregleda: 2317 | Odgovora: 10 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

S-man
ing
HR

Član broj: 290535
Poruke: 19
37.244.190.*



Profil

icon Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?30.10.2012. u 20:34 - pre 139 meseci
Učim C++ osnove iz knjige "Demistificirani C++" autora Julijana Šribara i Borisa Motika. Ima malo previše teksta za moj ukus, više bih volio da je malo konkretnija, ali dobro ... nije to sad važno. Uglavnom, evo što me zanima:

Trenutno sam na poglavlju o osnovama funkcija. Kaže da se deklaracija funkcije mora nalaziti u kodu bilo gdje prije prvog poziva funkcije. Nakon par strana piše da je svaka definicija neke funkcije ujedino i njena deklaracija, te da se funkcija ne mora deklarirati ako se njena definicija prebaci na početak koda.. Zašto onda uopče postoji deklaracija?


Imam neke ideje, npr: ako se definicija postavi u nekom drugom fajlu možda. Tada bi u fajlu u kojem se poziva bilo potrebno ubaciti deklaraciju. Ima li to možda nekakve logike?
- C++ novalija bez iskustva u drugim programskim jezicima
- Code::Blocks v.10.05 IDE okruženje
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.dynamic.sbb.rs.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?30.10.2012. u 22:07 - pre 139 meseci
Kompajler, da bi napravio izvršni fajl, redom "čita" source kod, i očekuje da sve bude jasno i nedvosmisleno. Odjednom dolazi na poziv nečega (npr. funkciju), o kojoj ne zna praktično ništa, čak ni da li se radi o grešci u kucanju. U principu, u toj početnoj fazi, zanima ga samo prototip (povratne vrednosti, naziv, argumenti), da bi nešto za sebe "rezervisao". Kada ima makar deklaraciju, zna da je tako predviđeno i ide dalje sa prevođenjem. Tek u nekoj kasnijoj fazi prevođenja, doći će do uspostavljanja veza među "rezervisanog" i "konkretnog".

Ovakav slučaj imaćeš ne samo kod funkcija, već i kod organizacije koda gde je klasa/struktura unutar neke druge klase/strukture, pa je potrebna makar odgovarajuća deklaracija, ukoliko kompajler već nije naišao na definiciju one unutrašnje klase/strukture. Tada se poseže ili za deklaracijom na pogodnom mestu ili za podizanjem definicije na vrh, tako da kompajler prvo dođe do nje.

Svakako, sada je pravi trenutak da baciš pogled iznutra na sadržaj standardnih biblioteka (može i one od C jezika: stdio, sdlib, ...), da pogledaš šta se zapravo postiže njihovim uključivanjem na početku koda. Tu su prototipovi, konstante, uslovna prevođenja i sl. Nekada davno, kada je procesorsko vreme bilo skupo i kada su se programeri takmicili ko ce biti veci haker, stedelo se cak i na ukljucivanju standardnih biblioteka, ukoliko se koristila tek poneka funkcija ili konstanta iz njih, pa se vrsila eksplicitna deklaracija, naravno, negde pri vrhu koda, pre upotrebe. Napominjem da je u praksi ovo opasno i da to ne ne radis, vec samo pominjem jedan od slucajeva koji moze posluziti da bolje razumes potrebu za deklaracijom.

Pomenuo si i organizaciju koda u više fajlova. Iako C++ jezici teže idealnoj organizaciji, verovatno će te praksa demantovati, pa ćeš imati posla i sa ključnom reči "extern", tako da pogledaj o čemu je reč. Ima veze sa onim "rezervisanjem", pa sad dal' se misli na isti objekat (deklarisan/definisan u nekom drugom modulu) ili neki sasvim drugi, koji tek treba rešavati.


[Ovu poruku je menjao X Files dana 30.10.2012. u 23:41 GMT+1]
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.3gnet.mts.telekom.rs.



+2789 Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?30.10.2012. u 22:39 - pre 139 meseci
Postoje slučajevi kada funkcija f poziva funkciju g, a funkcija g poziva funkciju f. Koju ćeš pre definisati? Ako definišeš prvo f, ona ne može da poziva g i obrnuto. Međutim, ako ih prvo deklarišeš, onda ih možeš definisati u bilo kom redosledu. To je slučaj kada prividno ne možeš da izbegneš deklarisanje funkcija pre njihovih definicija. U stvari možeš tako što ćeš funkcionalnost obe funkcije da objediniš u jednu funkciju, koja samu sebe poziva. Ovo je najređa situacija kada ti u praksi treba deklaracija pre definicije. Kasnije ću navesti i druge slučajeve.

Primer: Ako bi pisao program za igranje šaha, onda se svakoj poziciji pridružuje neka numerička vrednost. Vrednost 0 znači da ni jedna strana nije u prednosti, negativne vrednosti da je crni u prednosti i to utoliko većoj što je vrednost negativnija (dalja od nule), a pozitivne bi značile da je beli u prednosti i to utoliko većoj što je vrednost pozitivnija (dalja od nule). Dakle, crni se trudi da smanji vrednost pozicije, a beli da je poveća. Ako je crni na potezu, onda je vrednost pozicije minimum od vrednosti pozicija u koje se može preći jednim potezom crnog, a ako je beli na potezu, onda je vrednost pozicije maksimum vrednosti pozicija u koje se može preći jednim potezom belog. No, u jednom trenutku se mora stati i drugačije oceniti vrednost pozicije (statička vrednost pozicije). Funkcije min i max se mogu napisati ovako:

Code (cpp):

bool whitesTurn(Position p);
int possibleMoves(Position p);
Position makeMove(Position p, int moveNum);
int staticValue(Position p);
int min(Position p, int depth);
int max(Position p, int depth);

int min(Position p, int depth)
{
    if (depth <= 0) {
        return staticValue(p);
    }

    int currentMin = INT_MAX;
    int moves = possibleMoves(p);

    for (int i = 0; i < moves; ++i) {
        Position q = makeMove(p, i);
        int value = max(q, depth - 1);

        if (value < currentMin) {
            currentMin = value;
        }
    }

    return currentMin;
}

int max(Position p, int depth)
{
    if (depth <= 0) {
        return staticValue(p);
    }

    int currentMax = INT_MIN;
    int moves = possibleMoves(p);

    for (int i = 0; i < moves; ++i) {
        Position q = makeMove(p, i);
        int value = min(q, depth - 1);

        if (value > currentMax) {
            currentMax = value;
        }
    }

    return currentMax;
}

int minmax(Position p, int depth)
{
    if (depth <= 0) {
        return staticValue(p);
    }

    bool whitesTurn = whitesTurn(p);

    int currentValue = whitesTurn ? INT_MIN : INT_MAX;
    int moves = possibleMoves(p);

    for (int i = 0; i < moves; ++i) {
        Position q = makeMove(p, i);
        int value = minmax(q, depth - 1);

        if ((whitesTurn && value > currentValue) || whitesTurn == false && value < currentValue)) {
            currentValue = value;
        }
    }

    return currentValue;
}


Dakle, može sa dve funkcije (min i max), a može i sa jednom (minmax).

Drugi slučaj kada ti treba deklaracija pre definicije je kada treba koristiti konvencije o pozivanju funkcija nekog drugog programskog jezika.

Primer:

Code (cpp):

extern "C" double add(double x, double y);

double add(double x, double y)
{
    return x + y;
}


Treći i najčešći slučaj je kada pišeš program iz više modula. Modul (ili jedinica za prevođenje) je jedan cpp fajl zajedno sa svim zaglavljima koje neposredno ili posredno uključuje. Neka funkcija može biti definisana u jednom modulu, a da se koristi u drugom. Taj drugi modul mora znati njen prototip. Recimo da je funkcija definisana u bib.cpp, a da se koristi u main.cpp. Uobičajeno je da postoji zaglavlje bib.h u kome je deklarisano sve što se definiše u bib.cpp, a što drugi moduli treba da vide, a da onda main.cpp ima direktivu #include "bib.h", kao i da bib.h ima oblik

Code (cpp):

#ifndef BIB_H
#define BIB_H

// Some contents

#endif


Četvrti slučaj, koji je najčešći posle trećeg je da pišeš biblioteku. Ona ti je zapravo kao zaseban modul, koji se zasebno kompajlira i lepo zapakuje, tako da veže iste napomene kao u trećem slučaju.
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

S-man
ing
HR

Član broj: 290535
Poruke: 19
31.45.208.*



Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?31.10.2012. u 02:30 - pre 139 meseci
Evo sam odspavao par sati ispred televiszije pa sam sad budan i nastavljam :).

Ok, sad shvaćam potrebu deklaracije.

Nastavio sam čitat knjigu koja upravo tumaći primjer kada se tražena funkcija nalazi u drugom fajlu pa treba imati i header fajl. Ali čini se da je u ovoj knjizi nedovoljno objašnjeno ili ima neka pogreška. Ovo je moj primjer:

Ovo je sadržaj moga glavnog fajla "glavni_program.cpp":
Code:

#include <iostream>
#include "datoteka_zaglavlja.h"       
using namespace std;
int main()
{
    prva_funkcija();
    druga_funkcija();
    return 0;
}


Ovo je sadržaj moga header fajla "datoteka_zaglavlja.h":
Code:

extern void prva_funkcija();
extern void druga_funkcija();


Ovo je sadržaj modula koji sadrži definiciju prve funkcije "modul_prve_funkcije.cpp":
Code:

#include <iostream>
using namespace std;
void prva_funkcija()
{
    cout<<"Ovaj tekst je prikazan pomocu prve funkcije!"<<endl<<endl;
}


Ovo je sadržaj modula koji sadrži definiciju druge funkcije "modul_druge_funkcije.cpp":
Code:

#include <iostream>
using namespace std;
void druga_funkcija()
{
    cout<<"Ovaj tekst je prikazan pomocu druge funkcije.";
}


E sada prilikom kompajliranja "glavni_program.cpp" dobivam poruku
undefined reference to `prva_funkcija()
undefined reference to `druga_funkcija()
Build finished: 2 errors, 0 warnings

Ono što ja primjećujem, to je da nigdje u kodu nisu spomenuta imena fajlova koji sadrže funkcije. Kako će kompajler onda pronaći gdje se nalazi kod tih funkcija (tj njihove definicije)?











- C++ novalija bez iskustva u drugim programskim jezicima
- Code::Blocks v.10.05 IDE okruženje
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.3gnet.mts.telekom.rs.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?31.10.2012. u 07:30 - pre 139 meseci
Na pravom si putu. Postoji još jedan pojam koji treba da usvojiš, a on je "Dodavanje u projekat" (Add to project...).

Ona dva fajla za koja si lepo uočio da "vise", tj. da niko ne zna za njih, treba nekako da uključiš u projekat. Svako okruženje ti nudi tu funkcionalnost (Project > Add to project, Project > Add files, ...). Header fajlove NE dodaješ u projekat, oni se bukvalno vezuju kao klasičan insert, kroz #include. Ne dodaješ ni fajl u kome je main(), jer je on automatski dodat, kada si napravio nov projekat. Koje sve tipove fajlova moraš dodavati, pogledaj u padajućoj listi ekstenzija u "Add to project" dijalogu.

Ako nove projektne fajlove kreiraš kroz IDE, onda su oni sigurno već uključeni u projekat. Ako ih kreiraš ručno i naknadno kopiraš negde u strukturu projekta, onda ih moraš dodati kako je opisano.

Drugim rečima, okruženje ne polazi od pretpostavke da sve što se nalazi u folderu gde je main fajl, automatski predstavlja i fajl tog projekta. Ovo dalje može da znači, da jednog dana možeš imati više projekata (na zasebnim lokacijama) i nekakav zajednički univerzalni kod (na sopstvenoj lokaciji). Tada svaki projekat može za sebe da u svoj projekat uključi fajlove tog zajedničkog koda, da ih ne kopiraš svaki čas i održavaš "up to date".



[Ovu poruku je menjao X Files dana 31.10.2012. u 08:47 GMT+1]
 
Odgovor na temu

S-man
ing
HR

Član broj: 290535
Poruke: 19
95.168.101.*



Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?31.10.2012. u 19:22 - pre 139 meseci
Znaći tako, sad mi kompajlira bez greške. Ali, da li je to jedini naćin? Nije moguće nekako "ručno" to obaviti, tj upisati neku predprocesorsku instrukciju ili nešto slićno kojom se pokazuje na željene fajlove? Ćisto me zanima.
- C++ novalija bez iskustva u drugim programskim jezicima
- Code::Blocks v.10.05 IDE okruženje
 
Odgovor na temu

X Files
Vladimir Stefanovic
Pozarevac

SuperModerator
Član broj: 15100
Poruke: 4902
*.dynamic.sbb.rs.

Jabber: xfiles@elitesecurity.org


+638 Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?31.10.2012. u 20:16 - pre 139 meseci
MAKEFILE (ili slična alternativa) je uputstvo kompajleru/linkeru kako da obradi projektne fajlove. Pogledaj na primer:
http://wiki.codeblocks.org/ind...tle=Code::Blocks_and_Makefiles

Drugim rečima, "Add to project" zapravo menja taj MAKEFILE.

Školski primeri još i mogu da se prevedu kroz komandnu liniju, uz malo pažljivog kucanja, navođenjem serije projektnih fajlova, ali veći... zaboravi.


 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.3gnet.mts.telekom.rs.



+2789 Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?31.10.2012. u 21:56 - pre 139 meseci
Treba koristiti direktivu kompajlera za prevođenjem bez linkovanja, pa na kraju linkovati, ako ćeš ručno da kompajliraš. Na GNU C++ prevodiocu bi odgovarajuće komande bile

g++ -c main.cpp
g++ -c modul_prve_funkcije.cpp
g++ -c modul_druge_funkcije.cpp
g++ -oime_programa main.o modul_prve_finkcije.o modul_druge_funkcije.o

Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.3gnet.mts.telekom.rs.



+2789 Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?31.10.2012. u 22:03 - pre 139 meseci
Citat:
X Files: Header fajlove NE dodaješ u projekat, oni se bukvalno vezuju kao klasičan insert, kroz #include.

Sa ovim se nikako ne slažem, jer mada će se isprva projekat tako ispravno prevesti, okruženje će napraviti pogrešan projektni fajl (recimo Makefile ili nešto drugo), pa izmena zaglavlja neće uzrokovati ponovno prevođenje jedinica za prevođenje koje ga ne uključuju. Naravno, osim ako je okruženje dovoljnoo pametno da isprati sve pretprocesorske direktive, što ne treba pretpostavljati. U projekat se stavljaju i zaglavlja i cpp-ovi, jer svi čine projekat (kao i potrebni resursni fajlovi).
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

S-man
ing
HR

Član broj: 290535
Poruke: 19
31.45.209.*



Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?31.10.2012. u 22:44 - pre 139 meseci
Ok, sada mi je sve dosta jasnije. Nemam neku posebnu želju da sve to ručno ukucavam , ali volim znati kako stvari funkcioniraju. Puno hvala obojici na pomoći.
- C++ novalija bez iskustva u drugim programskim jezicima
- Code::Blocks v.10.05 IDE okruženje
 
Odgovor na temu

Nedeljko
Nedeljko Stefanović

Član broj: 314
Poruke: 8632
*.3gnet.mts.telekom.rs.



+2789 Profil

icon Re: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?01.11.2012. u 09:18 - pre 139 meseci
Možda sam se malo izlupetao sa pogrešnim pravljenjem projektnog fajla jer bi okruženje svakako moralo da prati pretprocesorske direktive da bi izvuklo ispravne zaključke o zavisnostima, ali zaglavlja svakako ulaze u sastav projekta i dodaju se u okruženju.

Čini mi se, mada nisam siguran jer sam u Visual C++ 6 jako malo radio, da sam imao problem kada sam dodavao posebno novo zaglavlje, a posebno cpp fajl, već da sam morao da preko čarobnjaka da dodam klasu, i sa njom njeno zaglavlje i njen .cpp fajl da bi okruženje ispravno rukovalo sa tim. No, takve čudne zahteve da moram da dodajem klasu preko čarobnjaka, a ne .h i .cpp u kojima bih pisao šta hoću (npr. kod klase) nisam imao ni u jednom drugom okruženju, uključujući i kasnija majkrosoftova (mada sam FOSS orjentisan, znači GNU C++, Qt itd).
Nije bitno koji su zaključci izvučeni, već kako se do njih došlo.
 
Odgovor na temu

[es] :: C/C++ programiranje :: C/C++ za početnike :: Da li je potrebno uopče deklaritati funkciju, ako je definicija ujedino i deklaracija?

[ Pregleda: 2317 | Odgovora: 10 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.