nemam, izgleda da je to problem jer mi javlja error da taj file ne postoji, doduse nije nista objasnjeno u knjizi kako ga napravit da program funkcionira pa sam mislio da ga napravi automatski?
Programiranje u C++-u - pitanja i odgovori
- poruka: 7.285
- |
- čitano: 1.712.650
- |
- moderatori:
Lazarus Long, XXX-Man, vincimus
- +/- sve poruke
- ravni prikaz
- starije poruke gore
nemam, izgleda da je to problem jer mi javlja error da taj file ne postoji, doduse nije nista objasnjeno u knjizi kako ga napravit da program funkcionira pa sam mislio da ga napravi automatski?
Jesi li siguran da u knjizi nema to objašnjeno? Mislim, moralo bi biti, pogledaj ako ima neki CD priložen uz knjigu ili link na neku stranicu sa materijalima, da nema taj header.
Postavi cijeli .cpp kôd, da vidimo šta pokušavaš implementirati iz tog header-a.
#include <iostream>
#include "Sales_item.h"
int main()
{
Sales_item book;
std::cin >> book;
std::cout << book << std::endl;
return 0;
}
odnosno nesto najjednostavnije, upis i ispis iz te klase..
Valjda unosiš neki atribut objekta, a ne kompletan objekt preko cin?
Recimo, ta klasa može imati atribute price, name, quantity, description, date... Onda instanciraš klasu i na taj objekt unosiš te atribute.
Napravi Sales_item.h fajl i u njega dodaj atribute koje sam naveo, osim ako se želiš striktno držati te knjige.
Valjda unosiš neki atribut objekta, a ne kompletan objekt preko cin?
Mislim da je u ovom slucaju operator >> preopterecen pa se na taj nacin upisuju atributi toga objekta. Npr. 1, 2, 3
Mislim da je u ovom slucaju operator >> preopterecen pa se na taj nacin upisuju atributi toga objekta. Npr. 1, 2, 3
U pravu si, vjerovatno jeste, ali mislim da je knjiga na početku objašnjavanja klasa, pa sumnjam da je već do preklapanja operatora došli. Ne znamo ovako, autor je tajnovit. :)
evo sad vidim kasnije da u pise stranica na kojoj mogu skinut taj Sales_item.h file no nema ga, googlao sam i nasao ali to sto sam nasao je iz knjige koja je 4th edition, ja imam 5th edition a razlika je. Uglavnom, javlja mi error:
C:\****\****\Desktop\c++\Untitled10.o:Untitled10.cc|| undefined reference to `operator>>(std::istream&, Sales_item&)'|
C:\****\****\Desktop\c++\Untitled10.o:Untitled10.cc|| undefined reference to `operator<<(std::ostream&, Sales_item const&)'|
zna netko mozda u cemu je problem s ovom .h datotekom?
Knjiga je ''C++ Primer, 5th edition, Lippman,Lajoie,Moo"
Jesu li operatori preklopljeni? Probaj ispisati određeni atribut, npr. book.Price, pogledaj u .h datoteci koje atribute ima ta klasa.
Molim pomoć:
može li mi netko objasniti zašto u ovom dijelu koda (to je primjer) kod
hdc = BeginPaint(hWnd,&ps); ide znak "&" (tj pokazivac) na ps? Kod nekih stvari se to mora stavljati, a kod nekih ne,
pa me zanima kako da ja i po cemu prepoznam kad ide "&" znak prije neke strukture ili cega vec (u ovom slucaju paint struktura), a kad ne?
Nije mi to baš jasno pa svaki put moram gledati po netu, a nikako da skuzim.
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, World!");
switch (message)
{ case WM_PAINT:
hdc = BeginPaint(hWnd, &ps); // Here your application is laid out. // For this introduction, we just print out "Hello, World!" // in the top left corner.
TextOut(hdc, 5, 5, greeting, _tcslen(greeting)); // End application-specific layout section. EndPaint(hWnd, &ps);
break;
}
Molim pomoć:
može li mi netko objasniti zašto u ovom dijelu koda (to je primjer) kod
hdc = BeginPaint(hWnd,&ps); ide znak "&" (tj pokazivac) na ps? Kod nekih stvari se to mora stavljati, a kod nekih ne,
pa me zanima kako da ja i po cemu prepoznam kad ide "&" znak prije neke strukture ili cega vec (u ovom slucaju paint struktura), a kad ne?
Nije mi to baš jasno pa svaki put moram gledati po netu, a nikako da skuzim.
Moraš proslijediti adresu strukture zato što te funkcija za drugi argument traži adresu strukture.
http://msdn.microsoft.com/en-us/library/windows/desktop/dd183362%28v=vs.85%29.aspx
To je sve što trebaš znati. Što ti nije jasno?
A ako *baš želiš* znati zašto BeginPaint funkciji treba pokazivač na strukturu, to je zato što ta funkcija kani upisivati svoje podatke u tu strukturu, a to ne može ako ju proslijediš po vrijednosti.
I zašto ti je EndPaint unutar komentara? Kada si završio sa crtanjem otpusti resurse...
Hvala na objasnjenju :)
Taj kod je skopiran s neta za primjer ovdje. Nisam to ja pisao.
Znači, ako sam dobro shvatio, gdje god funkcija (bilo koja funkcija, ne govorim sad o BeginPaint funkciji) kani upisivati podatke u nesto (strukturu ili vec nesto), uvijek se koristi pokazivac !?
Da, jer moraš mijenjati podatke na memorijskoj adresi originalne varijable. Ako u funkciju proslijediš samo vrijednosti te varijable dobiješ kopiju podataka koji nestanu nakon što se ta funkcija izvrši.
Evo ti i primjer:
#include <stdlib.h>
#include <stdio.h>
void funkcija1(int *arg)
{
*arg=5;
}
void funkcija2(int *arg)
{
arg=5;
}
void funkcija3(int arg)
{
arg=5;
}
int main()
{
int a=0, b=0, c=0, d=0;
printf("prije pozivanja funkcija: a=%d, b=%d, c=%d, d=%d\n", a, b, c, d);
funkcija1(&a);
funkcija2(&b);
funkcija3(c);
funkcija3(&d);
printf("nakon pozivanja funkcija: a=%d, b=%d, c=%d, d=%d\n", a, b, c, d);
system("pause");
return 0;
}
Jel ti jasno zašto se samo 'a' mijenja, a 'b', 'c' i 'd' ostaju isti? Ako nije, ponovi si pokazivače (ili pitaj :D).
E sad mi je jasnije. Puno ti hvala.
Pa rađe bi da mi objasnis nego da tresnem i ostanem živ :D Makar mislim da znam, ali rađe se neću sramotit ako možda nije točno :D
Pa rađe bi da mi objasnis nego da tresnem i ostanem živ :D Makar mislim da znam, ali rađe se neću sramotit ako možda nije točno :D
U redu.
Prvo pitanje što je pokazivač? Da, da, to je varijabla koja pokazuje na nešto, bla bla bla...
Ali što to zapravo znači?
Pokazivač je po svojoj definiciji varijabla čija je vrijednost memorijska adresa nečega. Memorijske adrese su obični cijeli brojevi (i to pozitivni, ne postoji negativna memorijska adresa). Tako da se pokazivač u osnovi ne razlikuje previše od klasičnog unsigned integera (unsigned int, jel).
Sad kad smo to probavili, ajmo vidjeti što se događa u programu. Dakle imamo 4 brojčane varijable (a, b, c, i d) čija je početna vrijednost nula i pokušavamo im izmijeniti vrijednost koristeći funkcije.
Slučaj 1:
funkcija1(&a);
Funkciji proslijeđujemo adresu varijable 'a' (tome služi '&' operator). Primijeti da je adresa samo cijelobrojna vrijednost, dakle mi funkciji i dalje proslijeđujemo samo broj (ali taj broj nije vrijednost varijable 'a' nego adresa varijable 'a').
funkcija1 je deklarirana ovako:
void funkcija1(int *arg)
Dakle funkcija ima samo jedan argument (imena 'arg', baš sam maštovit, ne?), i on je deklariran kao pokazivač na integer. Taj naš 'arg' poprimi vrijednost koju smo mu proslijedili (a ta vrijednost je adresa varijable 'a'). Dakle sada je vrijednost pokazivača memorijska adresa varijable 'a'.
Nakon toga se događa ovo:
*arg=5;
Izgleda kao klasično dodjeljivanje vrijednosti, samo... što ova zvjezdica radi ispred imena varijable? To ti je takozvani operator dereferenciranja. Ono što on radi jest govori da je sadržaj varijable koju smo dereferencirali zapravo adresa i da želimo raditi sa onime što se nalazi na toj adresi. Znači upravo smo naredili računalu da vrijednost na adresi na koju pokazivač pokazuje izmjeni u broj 5, kako ta adresa pripada varijabli 'a' to znači da smo upravo izmijenili varijablu 'a' i to je to.
Slučaj 2:
funkcija2(&b);
Ovdje se nema što komentirati, objašnjenje ove linije je isto kao u prvom slučaju.
deklaracija funkcije također ide na istu šablonu kao i u slučaju 1
void funkcija2(int *arg)
Ali ovo je bitna razlika:
arg=5;
Primjećuješ da nema operatora dereferenciranja? Što smo tu upravo napravili? Izmijenili smo vrijednost varijable 'arg' umjesto vrijednost na adresi na koju pokazuje. Znači vrijednost varijable 'b' će ostati 0 jer nismo ništa radili sa memorijom varijable 'b'.
Primijeti i da 'arg' sada pokazuje na memorijsku adresu 5, što je vjerojatno nevažeća adresa i program bi se srušio kada bi ju pokušali dereferencirati.
Slučaj 3:
funkcija3(c);
Vrijednost varijable 'c' (koja je 0) proslijeđujemo funkciji.
funkcija3 je deklarirana na slijedeći način:
void funkcija3(int arg)
Dakle vidimo da je argument 'arg' deklariran kao integer (a ne pokazivač na integer). Kako smo funkciji proslijedili vrijednost varijable 'c' to znači da varijabla 'arg' poprima vrijednost 0
Dalje se događa ovo:
arg=5;
Varijabli 'arg' smo izmijenili vrijednost u broj 5. Nigdje nismo ni taknuli memoriju na adresi varijable 'c', dakle varijabla 'c' ostaje neizmijenjena.
Slučaj 4:
funkcija3(&d);
Ovo je zanimljiva ideja. Proslijediti adresu varijable 'd' funkciji koja kao argument ne prima memorijsku adresu nego cijeli broj. Zašto to uopće možemo? Zato što, kao što sam već rekao, memorijska adresa i jest cijeli broj (tako da, sa stajališta računala, integer je integer i boli ga neka stvar jel taj broj zapravo memorijska adresa ili broj tvojih godina).
deklaracija funkcije3, čisto da se podsjetimo:
void funkcija3(int arg)
I što se dalje događa? Sada varijabla 'arg' (čija je vrijednost do sada bila adresa varijable 'd'), dobiva vrijednost 5.
arg=5;
Opet, memorija na adresi varijable 'd' je netaknuta, jedino što se tu mijenjalo jest vrijednost varijable 'arg'.
Dakle da zaključimo. Proslijeđivanje po vrijednosti (pass by value, googlaj) je zapravo kopiranje podataka. Isto kao kada bi ti recimo prepisao nešto na list papira. Sve što ti kasnije pišeš po tom papiru neće izmijeniti ono odakle si ti to prepisao. Dok si proslijeđivanje po referenci možeš zamisliti kao nekakav link na originalnu varijablu.
Nadam se da ti sve ovo ima smisla, hebeno je vruće i mozak mi se pregrijava :D
Da, ima smisla i zahvaljujem ti na ovako detaljnom objasnjenju, znam da nisi trebao, ali ipak jesi pa ti se puno zahvaljujem.
Cijenim to. ;)
Imam još samo jedno pitanje, da li je moguće kod Win32 programiranja napraviti posebnu funkciju koja stvara prozor (onih mozda 50+ linija koda za obican prozor) pa bi se onda ta funkcija pozvala unutar main funkcije ili bas taj sav kod mora biti baš unutar main funkcije?
npr:
int createWindow()
{
/* znači tu bi sad bilo sve ono skupa sa callback funkcijom, petlja koja provjerava da li je pritisnut x za izlaz iz programa itd*/
....
....
....
}
int WINAPI WinMain()
{
...
CreateWindow();
}
Da li je to moguće ako me kužiš što hoću reći?
Imam još samo jedno pitanje, da li je moguće kod Win32 programiranja napraviti posebnu funkciju koja stvara prozor (onih mozda 50+ linija koda za obican prozor) pa bi se onda ta funkcija pozvala unutar main funkcije ili bas taj sav kod mora biti baš unutar main funkcije?
Da li je to moguće ako me kužiš što hoću reći?
Naravno da je moguće.
Funkcija main ima samo jednu osnovnu svrhu. Ona predstavlja entry point (točku odakle počinje izvršavanje) tvog programa. Nije ona ni po čemu drugome "glavna".
Dakle program počinje od main funkcije, a ono što se dalje događa je isključivo na tebi.
Jedino mi nije jasno što si sa callback funkcijom mislio? Callback funkcija mora biti deklarirana na točno određen način, i biti postavljena u window klasu koju potom registriraš (kako bi OS imao pokazivač na tu funkciju i mogao ju pozivati po potrebi).
Ne može ti u callback funkciji stajati kod koji po defaultu stvara prozor svaki puta kada ta funkcija bude pozvana (jer će biti pozivana često i to odmah pri prikazivanju prozora, pa si zamisli koliko će prozora biti stvoreno) i u biti ćeš stvoriti rekurzivnu petlju jer svako stvaranje prozora poziva callback funkciju koja će opet stvoriti novi prozor pa će opet pozvati callback funkciju...
Da, znam da je to entry point za windows programe, a za callback funkciju sam mislio ovako (budem probao bolje objasniti), znači :
Da li je moguće tako nekako otprilike napraviti posebnu funkciju za stvaranje prozora, pa da se ne gubim u kodu unutar main funkcije nego da jednostavno pozovem CreateWindow()?
Mozda cu isprobavati raditi 2D igru u directXu pa bi mi jednostavnije bilo da vec imam posebnu eksternu funkciju i header file koji includeam za stvaranje prozora
tako da mogu mainLoop i logiku igru normalno kodirati bez da se gubim po kodu u main funkciji.
Mislim, znam da je moguce sve unutar main funkcije ali me to zivcira toliko koda svakakvog pa bi si ja to rađe posebno, pa čak i za kreiranje prozora kod napravio.
Znači onda bi u main funkciji pozivao samo ostale funkcije npr. CreateWindow, loadImages, mainLoop, itd ... jesi me sad skuzio?
Da li je to moguće na neku foru tako napraviti bez prevelike zahebancije?
LRESULT CALLBACK WndProc (...)
{
switch (message)
{
case WM_QUIT:
return 0;
break;
}
}
int createWindow()
{
...
znači ostatak koda, window klasa, registracija window klase, kreiranje prozora itd...
}
int WINAPI WinMain()
{
// znaci tu bi pozvali funkciju koja stvara prozor
createWindow();
....
}
Da, znam da je to entry point za windows programe, a za callback funkciju sam mislio ovako (budem probao bolje objasniti), znači :
Da, to definitivno može.
Samo jedno pitanje. Zašto to pitaš na forumu kada ti je brže jednostavno isprobati (pa onda ako ustanoviš da ne radi pitati zašto ne radi)?
Zato jer sam prije isprobavao već pa mi nije baš proradilo, a navečer planiram to jos proučiti jer trenutno nisam u mogućnosti isprobavati sad.
Budem danas pokušao opet, pa ako zapne se javim. :D
Zato jer sam prije isprobavao već pa mi nije baš proradilo, a navečer planiram to jos proučiti jer trenutno nisam u mogućnosti isprobavati sad.
I onda izrežeš kod i napraviš minimalni slučaj koji ti radi probleme pa onda s time ovdje na forum.
Evo isprobao sam i kad pokrenem program ništa se ne događa. main.cpp i window.h sam sam napravio, sve unutar window.cpp je kopirano s neta
Znači koristim C++ Builder XE2, imam main.cpp | window.cpp | window.h
main.cpp
#pragma hdrstop
#include <vcl.h>
#include <windows.h>
#include <tchar.h>
#include "window.h"
WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
WindowCreate(hInstance,hPrevInstance,lpCmdLine,nCmdShow);
}
Ah.. DX.. Nisam vidio.
http://realmike.org/blog/articles/using-directx-with-cbuilder/
Na dnu stranice imaš zip s gotovim primjerom.
Da, nisam ni ja odmah vidio :D Zasad ide sve po planu, planiram neku jednostavnu 2D igricu u DirectXu napraviti da malo proučim directX bolje :D
Evo ti i jedan primjer koji imam kod sebe: LINK
Aplikacija iscrtava jednu BMP sliku po tvom izboru 1000 puta pomoću Direct Draw-a. Unutra možeš vidjeti kako se inicijalizira D3D, postavlja tekst, slike itd itd..
Budem proučio, hvala, probat ću napraviti sprite da se miče i kolizije (pošto nikad nisam baš radio nešto takvo, pa da isprobam sad kad imam volje za učiti nešto novo :D)
Btw što znači "**" (dvije zvijezdice) u lDirect3DTexture9 ** ppTexture
Sa jednom zvijezdicom znam da je pointer.
Pointer na pointer. Ili analogija;
int* p, gdje se 'p' može pisati u notaciji za 1D polje tj. p[0], p[1]... u ovisnosti koliko je elemenata alocirano => *(p+i) = p[i] . Isto tako
int** p, u notaciji za 2D polje tj. p[0][0]... itd. itd..
Hvala na objašnjenju :D Ček to je onda pointer na 2D polje (mislim, te dvije zvijezdice predstavljaju pointer na 2D polje) ili što?
pointer na pointer ili pointer na 1D polje.
Dobro, kuzim, hvala. Vec je kasno pa ne mogu razmisljati vise :D