Usporiadanie programov a dát // C++

Programovacie jazyky, rady, poradňa...
Fata! ChaoS
Star
Star
Používateľov profilový obrázok
Príspevky: 650
Registrovaný: 12 apr 2006, 20:23
Bydlisko: Tvrdošovce
Kontaktovať používateľa:

Usporiadanie programov a dát // C++

Príspevok od používateľa Fata! ChaoS »

Nazdar, študujem jednu knihy pre začiatočníkov, nuž a opisujem z neho jeden program aby som ho mohol spustiť a vyskúšať, ale skladá sa zviacerých programov a vlastných knižníc a robím takéto prvýkrát a v knihe to nieje moc jednoznačne napísané, ktorí zdroják má ísť kam.

Už som napísal "hlavný" program znamkovani.cpp a tiež knižnice stred.h znamka.h Student_info.h

nuž a tie knižnice majú takýto obsah

napr. znamka.h:

Kód: Vybrať všetko

#ifndef HLIDAC_znamka_h
#define HLIDAC_znamka_h
#include <vector>
#include "Student_info.h"

double znamka(double, double, double);
double znamka(double, double, const std::vector<double>&);
double znamka(const Student_info&);

#endif
čiže len to #ifndef....#endif a ešte v knihe je nejaký zdroják kde sa definujú funkcie a pod. čo je tiež v iných súboroch ako je "hlavný" program a to neviem, že tie definície funkcií mám napísať do tách knižních alebo do súboru typu .c

v knihe je ešte takýto zdroják k tomu znamka

Kód: Vybrať všetko

#include <stdexcept>
#include <vector>
#include "znamka.h"
#include "stred.h"
#include "Student_info.h"

using namespace std;

double znamka(double polovina, double zaver, double domaciukol)
{
       return 0.2 * polovina + 0.4 * zaver + 0.4 * domaciukol;
}
lenže kebyže to dám do znamka.h tak mi to pripadá čudné, že zas sa tam dáva #include <vector> ale hento v tele #ifndef....#endif už neplatí tak asi preto a zas do znamka.c súboru by to podľa mňa preto nepasovalo, lebo tam nieje ani int main() a ani return 0, nuž ja som s toho mimo, takže ak ste ma pochopili tak prosím poradte kam, dať tie definície funkcií?? a v jakom tvare? Vopred ďakujem
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

Keď robíš väčší program je dobré rozdeliť funkcie do súborov podľa toho, čo robia. Napr. v jednom súbore budú funkcie na načítavanie údajov, v ďalšom na ich spracovanie...
Každý taký súbor bude pravdepodobne obsahovať aj funkcie, premenné, konštanty... ktoré budeš chcieť použiť v inom súbore. V takom prípade dáš ich deklaráciu do hlavičkového súboru.

Napr.: mám funkciu

Kód: Vybrať všetko

void parse_file(FILE *file)
{
  // niečo urobíme
}
a do hlavičkového súboru dám deklaráciu

Kód: Vybrať všetko

void parse_file(FILE *file);
V súbore, kde budem chcieť použiť tú funkciu použijem klasické include.

Definícia premennej, funkcie patrí (zvyčajne) do súboru .c/.cpp. Deklarácia buď do .h súboru (ak sa tá funkcia bude používať aj v iných súboroch), alebo bude v tom istom .c/.cpp súbore (ak je to potrebné). V tom druhom prípade je dobrá, aby bola tá funkcia statická.

Tá #ifdef, #define, #endif konštrukcia sa tam používa preto, aby sa hlavičkový súbor vložil do zdrojového kódu len raz (jeden .h súbor môže byť vkladaný v .c/.cpp súbore ale aj v niektorom hlavičkovom súbore, ktorý je vložený do .c/.cpp). V Php na niečo také existuje include_once.
tuti
Light Professional
Light Professional
Používateľov profilový obrázok
Príspevky: 740
Registrovaný: 01 okt 2006, 19:23
Bydlisko: Prievidza

Príspevok od používateľa tuti »

este doplnim:

do suborov sa potom includuju subory *.h pricom sa do suboru ???.cpp zasadne includuje zodpovedajuci si subor ???.h kvoli tomu aby nebolo nieco ine v subore .h a ine v subore .cpp . Subory *.h si mozes predstavit ako informacie pre prekladac ze dane funkcie budu "dodane od inakadial" (napr. prelozena z asembleru) a ze budu vyzerat podla dodaneho prototypu. Subory *.cpp obsahuju detailne informacie o tom co ma dana funkcia robit a vyziva linker ktory zostavuje samotny program. a prave linker zahlasi chybu ked mu chyba definicia funkcie (undefined reference + nazov skomoleny polskou notaciou)
Fata! ChaoS
Star
Star
Používateľov profilový obrázok
Príspevky: 650
Registrovaný: 12 apr 2006, 20:23
Bydlisko: Tvrdošovce
Kontaktovať používateľa:

Príspevok od používateľa Fata! ChaoS »

aha díky za objasnenie, no ale ešte stále neviem kam mám dať ten druhý zdroják v mojom predošlom príspevku.
Mám to celé dať do znamka.h takto??

Kód: Vybrať všetko

#ifndef HLIDAC_znamka_h 
#define HLIDAC_znamka_h 
#include <vector> 
#include "Student_info.h" 

double znamka(double, double, double); 
double znamka(double, double, const std::vector<double>&); 
double znamka(const Student_info&); 

#endif

#include <stdexcept> 
#include <vector> 
#include "znamka.h" 
#include "stred.h" 
#include "Student_info.h" 

using namespace std; 

double znamka(double polovina, double zaver, double domaciukol) 
{ 
       return 0.2 * polovina + 0.4 * zaver + 0.4 * domaciukol; 
}
alebo jak, lebo keď som to dal takto a chel som skompilovať súbor kde bolo include-nutý ten súbor znamka.h, tak kompilácia neustále prebieha a vypisuje nekonečnekrát, .......znamka.h compiling, no ešte zajtra poskúšam, veci, ale keď viete, z táchto informácií pomôcť tak píšte, ak nie tak ešte neskôr ak poskúšam veci pridám ďalšie informácie.
tuti
Light Professional
Light Professional
Používateľov profilový obrázok
Príspevky: 740
Registrovaný: 01 okt 2006, 19:23
Bydlisko: Prievidza

Príspevok od používateľa tuti »

tuto cast by som povedal ze patri do casti znamka.cpp

Kód: Vybrať všetko

#include <stdexcept> 
#include <vector> 
#include "znamka.h" 
#include "stred.h" 
#include "Student_info.h" 

using namespace std; 

double znamka(double polovina, double zaver, double domaciukol) 
{ 
       return 0.2 * polovina + 0.4 * zaver + 0.4 * domaciukol; 
}
este poznamka pod ciarov: *.h subory by mali zacinat #ifndef ... a koncit #endif. ziadny uzitocny kod mimo :!:
Fata! ChaoS
Star
Star
Používateľov profilový obrázok
Príspevky: 650
Registrovaný: 12 apr 2006, 20:23
Bydlisko: Tvrdošovce
Kontaktovať používateľa:

Príspevok od používateľa Fata! ChaoS »

Aha díky, za ďalšie rady, dneska ma niečo osvietilo a napadlo ma, že to najprv vyskúšam na nejakom jednoduchom programe a nie na takom rozsiahlom, a pomocou toho a vašich rád som to konečne pochopil :D

A zaujala ma jedna vec, že prečo je potrebné deklarovať funkciu v hlavičkovom súbore.

Vezmime si najprv, že v jedinom "1".c/"1".cpp súbore si definujem určitú funkciu a neskôr ju už len používám a nie je potrebná deklarácia tej funkcie. Avšak ak tú funkciu definujem v inom "2".c/"2".cpp súbore, tak už potrebná je aj deklarácia tej funkcie ak ju chcem použiť v súbore 1.cpp
a práve toto mi pripadá zaujímavé, že prečo vyžaduje kompilátor aby tá funkcia bola deklarovaná, prečo mu nestačí ak v súbore 1.cpp je include-nutý súbory 2.cpp, kde je tá funkcia definovaná?!
Nečakám, že mi nato odpoviete, ale ak viete tak super, ale len si chcem o tom podiskutovať.

P.S. Je to jak u premenných, najprv sa musia deklarovať a potom do nich ukladáme dáta, ale zas ak všetko je v jednom súbore, tak to prečo nevyžaduje?!
...
Expert
Expert
Príspevky: 157
Registrovaný: 07 apr 2006, 18:13

Príspevok od používateľa ... »

V prvom rade: do c/cpp sa NEincluduje dalsi c/cpp subor. Includuju sa len hlavickove (.h) subory.

Treba sa na to pozriet tak, ze zdrojaky c/cpp su samostatne celky, kompiluju sa od seba nezavisle. Preto ak mam nejaku funkciu foo() v a.cpp, tak b.cpp ju pouzit nemoze, lebo o nej nevie. Ak chcem pouzit foo() v b.cpp, musim jej deklaraciu umiestnit do nejakeho hlavickoveho suboru a.h, ktory potom includnem do b.cpp (a do a.cpp tiez). Tak bude b.cpp vediet, ze nejaka funkcia (s takymi a takymi parametrami a takym navratovym typom) existuje a tym padom s nou bude vediet pracovat. Kde je jej kod umiestneny (ci v a.cpp, x.cpp alebo v nejakej uplne cudzej kniznici, napr. DLL) a co robi, je b.cpp celkom jedno. Podstatne je, ze pri kompilacii celeho projektu sa postupne spracuju vsetky zdrojaky (cpp) a "zlepia" (zlinkuju) sa do jedneho vysledneho spustitelneho suboru. Tam sa potom objavi aj prelozeny kod foo() z a.cpp, a teda kod z b.cpp ju bude moct pouzit (zavolat) pri spusteni programu.

Hlavickove subory informuju o tom, ze nejaka funkcia (struktura, trieda, premenna) existuje (a ako funguje praca s nou). Na zaklade toho (ak sa pouzije zodpovedajuci include) s tymito objektami moze kod pracovat, aj ked su umiestnene v inych zdrojakoch (kvoli prehladnosti a usporiadanosti).
Neviem ci si robil niekedy s Pascalom, ale ak hej, tak treba zabudnut na to ako tam funguju a su previazane unit-y, v C je to vcelku o inom :)
chrono
VIP
VIP
Používateľov profilový obrázok
Príspevky: 7127
Registrovaný: 25 dec 2006, 15:17

Príspevok od používateľa chrono »

tuti napísal:este poznamka pod ciarov: *.h subory by mali zacinat #ifndef ... a koncit #endif. ziadny uzitocny kod mimo :!:
To je pravda len čiastočne. Občas sa môže hodiť, ak sa ten hlavičkový súbor dá vložiť viac krát.
Napísať odpoveď