Evo ja počeo čeprkat i lagano se učit u Cpp-u. Gledam razne tutoriale vec par dana. Skinuo sam neki framework i pokusavam naprvait jednostavnu igru. Za sad imam strelicu koju mogu pomicat po ekranu tipkama te mijenjat brzinu sa space i enter tipkom.
Polako ali sigurno :D
Programiranje u C++-u - pitanja i odgovori
- poruka: 7.284
- |
- čitano: 1.948.201
- |
- moderatori:
XXX-Man
- +/- sve poruke
- ravni prikaz
- starije poruke gore
Ali se barem trudiš.
Dakle trebaš definirati samo jednu strukturu, ne treba ti cvor2 i cvor3.
struct cvor
{
int value;
node *next;
};
...
Skuzio sam sve sto si napisao u postu. Hvala!
Napisao sam svoju jako slicnu verziju jednostruko povezane liste sa 4 cvora te me sada zanima kako da ispisem ta 4 elementa?
Dole je while petlja napisana cisto ovako, tako nekako mi se cini da ide, ali ne znam točno napisati.
Skuzio sam sve sto si napisao u postu. Hvala!
Napisao sam svoju jako slicnu verziju jednostruko povezane liste sa 4 cvora te me sada zanima kako da ispisem ta 4 elementa?
Dole je while petlja napisana cisto ovako, tako nekako mi se cini da ide, ali ne znam točno napisati.
Na dobrom si tragu.
Uzmeš pokazivač koji će ti predstavljati trenutan čvor u listi na kojem se nalaziš, i postaviš ga da pokazuje na prvi čvor u listi (ili bilo koji čvor od kojeg želiš početi), nakon toga u petlji taj pokazivač samo postaviš da uvijek pokazuje na sljedeći čvor u listi (označeno zeleno), ovako:
node *temp = &a;
while (temp != NULL)
{
cout << temp->value << endl;
temp = temp->next;
}
For petlja se jako zgodno može postaviti za prolazak kroz listu, pogledaj ovo:
for (node *temp = &a; temp != NULL; temp = temp->next)
{
cout << temp->value << endl;
}
Ponavljaš tako dugo dok 'temp' nije NULL. Kada naletiš na NULL znaš da si došao do kraja...
Tako je. Kada imaš običnu strukturu njenim članovima pristupaš koristeći točku, kada imaš pokazivač na strukturu onda koristiš strelicu.
Ako pogledaš u ovim primjerima petlji što sam ih napisao, 'temp' je pokazivač na strukturu, stoga se koristi strelica.
Aha znaci pokazivac mi je bio kljucan za ispis hah ok :D
Kuzim sve do sada, sada imam materijale za procitati do kraja pa krecem s analizom koda na vrhu stranice.
Hvala na vrlo kvalitenim postovima!
Samo da se nadovezem. Strelica '->' je ustvari ljepsi nacin za napisati:
(*pok).value;Jer kad imas pokazivac na neku strukturu (ili klasu), da bi pristupio njezinim clanovima prvo moras dereferencirati pokazivac (to je ovo (*pok)), a onda tek mozes pristupati clanovima s tockom. Zato je uvedena strelica koja je jasniji i ljepsi nacin za napisati to.
Ne, to nije cijeli zadatak, nego samo kreiranje liste iz datoteke i njezin ispis, demostracijski rad da vidiš način rada.
Inače, ovaj zadatak baš nije tako jednostavan kako se čini, ja sam shvatio da treba izvršiti sortiranje prilikom upisa, a ne posebnim metodom, što bi ipak bilo lakše izvršiti upis na kraj i poslije sortirati posebnom metodom. Ovako treba u jednoj metodi vršiti upis na kraj, početak i između ovisno o vrijednosti stringa. Izbacivanje elemenata, obrnuti ispis i dealokacija ne bi trebalo biti problem.
Malo sam se ostavio lista pa cu se kasnije vratiti. Trebam objasnjenje komentiranih linija što se tocno izvodi.
#include <fstream>
#include <iostream>
using namespace std;
/*
Napišite program koji æe najprije izraèunati kolika je velièina neke tekstualne
datoteke znakovi.txt u koju su pohranjeni znakovi i potom dinamièki alocirati
polje znakova i uèitati u njega sadržaj datoteke.
Potom se sva pojavljivanja malog slova 'a' zamjenjuju s velikim slovom 'A'.
Na kraju se ispisuje izmijenjeni sadržaj i oslobaða memorija.
*/
int main ()
{
ifstream ulaz ("znakovi.txt");
streampos pocetak, kraj;
pocetak = ulaz.tellg();
ulaz.seekg(0, ios::end);
kraj = ulaz.tellg();
ulaz.seekg(0, ios::beg);
const int n = kraj - pocetak;
cout << "Velicina datoteke je " << n << " bajtova."<<endl;
char *pokazivac; //ovo je din alokacija, kako to izgleda u memoriji, ne mogu si objasniti?
pokazivac = new char[n];
ulaz.read(pokazivac, n); // objasniti što se točno izvodi u ovoj liniji
cout << "Sadrzaj datoteke:" << endl << endl;
cout.write(pokazivac, n) << endl << endl;
for (int i = 0; i < n; i++)
{
ulaz >> pokazivac[i];
if(pokazivac[i] == 'a')
pokazivac[i] = 'A';
}
cout << "Nakon izmjene a -> A:" << endl;
cout.write(pokazivac, n) << endl << endl;
delete [] pokazivac;
return 0;
}
char *pokazivac; //ovo je din alokacija, kako to izgleda u memoriji, ne mogu si objasniti?
pokazivac = new char[n];
ulaz.read(pokazivac, n); // objasniti što se točno izvodi u ovoj liniji
Ovo prvo nije dinamicka alokacija, vec stvaranje jedne varijable koja pokazuje na neku drugu varijablu. Ta varijabla se zove pokazivac, ocito. U nju se sprema adresa neke druge varijable.
Ovo drugo je dinamicka alokacija. Poziva se new operator koji zauzima odredenu kolicinu memorije i vraca pokazivac na tu memoriju. Ta adresa se dodjeljuje ovom nasem pokazivacu i on sad pokazuje na tu dinamicki alociranu memoriju.
Za ovo trece procitaj referencu za read. Read izvlaci n znakova iz streama i sprema ih u polje na koje pokazuje neki pokazivac.
char *pokazivac; //ovo je din alokacija, kako to izgleda u memoriji, ne mogu si objasniti?
pokazivac = new char[n];
ulaz.read(pokazivac, n); // objasniti što se točno izvodi u ovoj liniji
Ovo prvo nije dinamicka alokacija, vec stvaranje jedne varijable koja pokazuje na neku drugu varijablu. Ta varijabla se zove pokazivac, ocito. U nju se sprema adresa neke druge varijable.
Ovo drugo je dinamicka alokacija. Poziva se new operator koji zauzima odredenu kolicinu memorije i vraca pokazivac na tu memoriju. Ta adresa se dodjeljuje ovom nasem pokazivacu i on sad pokazuje na tu dinamicki alociranu memoriju.
Za ovo trece procitaj referencu za read. Read izvlaci n znakova iz streama i sprema ih u polje na koje pokazuje neki pokazivac.
Da, malo sam zeznuo liniju..
Recimo da je n = 15, znaci zauzet ce polje od 15 charova, i na sta sad pokazuje taj pokazivac? Na cijelo polje ili na neki odredeni char od ovih 15?
Slika koju sam stavio u post na prošloj stranici, nađi i pogledaj, a pročitaj i ostatak posta. Ukratko, pokazivač pokazuje na prvi char u polju.
Da, malo sam zeznuo liniju..
Recimo da je n = 15, znaci zauzet ce polje od 15 charova, i na sta sad pokazuje taj pokazivac? Na cijelo polje ili na neki odredeni char od ovih 15?
Na prvi clan tog polja. Dalje se pokazivac inkrementira da bi se pristupilo ostalim clanovima.
Zaboravio hah, hvala.
U vezi onog koda gore koji sam postao, nakon izmjena malog slova a u veliko slovo A, kako bi ja to zapisao u tu istu datoteku?
Ovo sam napisao za sad:
ifstream ulaz ("znakovi.txt");
ofstream izlaz ("znakovi.txt", ios::app); //append da mi ne izbrise postojeci text u datoteci
Jos sam nesto:
izlaz << pokazivac[i] = 'A';
Ali to naravno ne radi :D
EDIT: krenuo sam sa listama ponovo i vec na pocetku mi nisu jasni ovi pokazivaci izvan main ili bilo koje druge funkcije i strukture, kao da su sami za sebe? Jel to nekakva globalna deklaracija ili šta?
1. post na 185. (ovoj) stranici, odmah ispod prve strukture.
*pocetak = NULL, *trenutni, *pomocni;
Zaboravio hah, hvala.
U vezi onog koda gore koji sam postao, nakon izmjena malog slova a u veliko slovo A, kako bi ja to zapisao u tu istu datoteku?
Ovo sam napisao za sad:
ifstream ulaz ("znakovi.txt");
ofstream izlaz ("znakovi.txt", ios::app); //append da mi ne izbrise postojeci text u datoteci
Jos sam nesto:
izlaz << pokazivac[i] = 'A';
Ali to naravno ne radi :D
Pa ako u zadatku već imaš pročitan cijeli sadržaj datoteke u memoriju, zašto si onda napravio ovakvu petlju:
for (int i = 0; i < n; i++)
{
ulaz >> pokazivac[i];
if (pokazivac[i] == 'a')
pokazivac[i] = 'A';
}
To jest, zašto dva puta čitaš istu stvar?
'pokazivac' ti već pokazuje na memorijski spremnik u koji si učitao kompletnu datoteku, imajući to na umu dovoljno ti je napraviti ovo:
for (int i = 0; i < n; i++)
{
if (pokazivac[i] == 'a')
pokazivac[i] = 'A';
}
Što se zapisivanja tiče, samo koristiš write na otvorenom streamu, kao što si ga koristio i za ispis na ekran:
izlaz.write(pokazivac, n);
To napraviš nakon što si konvertirao sva slova, zapišeš sve u komadu u datoteku.
1. post na 185. (ovoj) stranici, odmah ispod prve strukture.
*pocetak = NULL, *trenutni, *pomocni;
Kada definiraš strukturu odmah možeš deklarirati i varijable tog tipa, objašnjavao sam to već u ovom postu.
I da, varijable deklarirane izvan funkcija su globalne varijable, što znači da im sve funkcije unutar iste source datoteke mogu pristupati (ili da budem precizniji sve funkcije koje su definirane ispod te varijable, ako varijablu deklariraš pri vrhu datoteke onda sve funkcije mogu pristupati).
U ovom slučaju taj pocetak je globalni pokazivač koji pamti početak liste, da sam ga stavio u main, pa prenio u funkciju dodaj, to bi bilo kopiranje pokazivača, a ne prenošenje varijable pokazivačem, ne bi mi zapamtio poziciju nakon izlaska iz funkcije dodaj.
Ali, ti moraš najprije dobro proći teoriju, pa izvježbati jednostavnije zadatke sa pokazivačima, da bi spajao liste. Mislim, mogu ti riješiti taj zadatak, nije problem, ali ne mogu objasniti svaki korak iz koda, moraš znati to u teoriji.
Ovo ti je primjer kopiranja pokazivača:
void ispis()
{
pomocni = pocetak; // pomocni na pocetak
while (pomocni->naprijed != NULL) // pomocni seta do zadnjeg
{
cout << pomocni->pjesma << endl << pomocni->izvodjac << endl << pomocni->vrijeme << endl;
pomocni = pomocni->naprijed;
}
cout << pomocni->pjesma << endl << pomocni->izvodjac << endl << pomocni->vrijeme << endl; // u while je zadnji ostao neispisan
}
Dakle, ovih ispisa mogu napravtti koliko hoću jer pokazivač početak nisam pomicao, on uvijek stoji na početku liste, a pomoćni polazi od početka liste i pomiče se naprijed, da sam koristio pokazivač početak, samo bi jedan ispis mogao napraviti.
Uz put, mogao sam to napraviti i jednostavnije, mea culpa, pošto mi pokazivač pomoćni više ne treba, pa može postati i null.
void ispis()
{
pomocni = pocetak; // pomocni na pocetak
while (pomocni != NULL) // pomocni seta do zadnjeg
{
cout << pomocni->pjesma << endl << pomocni->izvodjac << endl << pomocni->vrijeme << endl;
pomocni = pomocni->naprijed;
}
}
A naravno da postoji alternativa, ne moramo imati nijedan globalni pokazivač, deklariramo pokazivač početak u main funkciji i prenosimo ga dvostrukim pokazivačem u funkciju dodaj. U tom slučaju pokazivač u main funkciji pamti položaj na listi. Uoči da sam u funkciji ispis kopirao pokazivač, za razliku od funkcije dodaj gdje sam ga prenio dvostrukim pokazivačem, u funkciji ispis ne diramo pokazivač pocetak, samo nam treba njegova kopija da počnemo ispis.
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
struct cvor
{
string pjesma;
string izvodjac;
string vrijeme;
cvor *naprijed;
cvor *nazad;
};
void dodaj(cvor **pocetak, cvor *trenutni)
{
cvor *pomocni;
if (*pocetak == NULL) // ako na listi nema nijednog cvora
{
*pocetak = trenutni;
trenutni->naprijed = NULL;
trenutni->nazad = NULL; // ovaj cvor nam je prvi, prednji i zadnji pokazivac su mu null
}
else
{
pomocni = *pocetak; // uzimamo pomocni cvor i stavljamo ga na pocetak
while (pomocni->naprijed != NULL)
{
pomocni = pomocni->naprijed; // pomocni cvor seta na kraj liste
}
pomocni->naprijed = trenutni; // onaj na kraju liste prednji veze za nas trenutni kojeg ubacujemo
trenutni->nazad = pomocni; // nas trenuni zadnji veze za onog na kraju liste
trenutni->naprijed = NULL; // povezali smo trenutni, prednji je null
}
}
void ispis(cvor *pomocni)
{
while (pomocni != NULL) // pomocni seta do zadnjeg
{
cout << pomocni->pjesma << endl << pomocni->izvodjac << endl << pomocni->vrijeme << endl;
pomocni = pomocni->naprijed;
}
}
int main()
{
cvor *pocetak = NULL, *trenutni;
ifstream citaj;
string linija;
citaj.open("myPlayList.txt");
if (citaj.is_open())
{
while (!citaj.eof())
{
trenutni = new cvor(); // alociramo novi cvor
getline(citaj, linija); // kupimo podatke iz datoteke za njega
trenutni->pjesma = linija;
getline(citaj, linija);
trenutni->izvodjac = linija;
getline(citaj, linija);
trenutni->vrijeme = linija;
dodaj(&pocetak, trenutni); // idemo ga dodati na listu
}
}
else
cout << "greska";
ispis(pocetak);
cout << endl;
ispis(pocetak);
return 0;
}
bi li netko moga napisat program da od prosjeka konzola izbacuje sve koji su u amo rec dosegu od 0.5 bilo cega ..
bi li netko moga napisat program da od prosjeka konzola izbacuje sve koji su u amo rec dosegu od 0.5 bilo cega ..
Mogli bi, ali što bi onda ti radio?
oprostite sta zelim naucit i vidit kako radi .
oprostite sta zelim naucit i vidit kako radi .
Oprastamo.
oprostite sta zelim naucit i vidit kako radi .
Pa u čemu je problem? Imaš neku vrijednost koju uzimaš za mjerilo svih ostalih vrijednosti i ako su te vrijednosti veće za 0.5 ili manje za 0.5 onda ne zadovoljavaju u kriterij koji si postavio.
Znači ako je ta neka ogledna vrijednost recimo 1.1, svi brojevi koji su istovremeno veći od (1.1 - 0.5) i manji od (1.1 + 0.5) zadovoljavaju kriterij.
I nemaš se razloga duriti, pitao si bi li mogli napisati takav program. Nisi postavio konkretna pitanja, rekao što ne znaš, nego si samo tražio gotov program.
hvala.. Nije nego san mislia da ima mozda nekako preko neke opcije ili funkcije gg.
Evo jedno pitanje.
Pripremam se za ispit iz OOP programiranja i rješavam neki primjer zadatka gdje treba napraviti klasu Natjecatelj sa podacima tipa ime, prezime, godište, ime kluba za koji igra, matični broj.
Problem dolazi jer te podatke moramo učitati za pet natjecatelja preko konstruktora. Korisnik treba upisati podatke za svakog natjecatelja.
Nemam ideju kako napraviti taj dio sa učitavanjem preko konstruktora. Pada mi na pamet samo korištenje Vektora liste, ali to nismo učili pa kao ne smijemo koristiti.
Evo jedno pitanje.
Pripremam se za ispit iz OOP programiranja i rješavam neki primjer zadatka gdje treba napraviti klasu Natjecatelj sa podacima tipa ime, prezime, godište, ime kluba za koji igra, matični broj.
Problem dolazi jer te podatke moramo učitati za pet natjecatelja preko konstruktora. Korisnik treba upisati podatke za svakog natjecatelja.
Nemam ideju kako napraviti taj dio sa učitavanjem preko konstruktora. Pada mi na pamet samo korištenje Vektora liste, ali to nismo učili pa kao ne smijemo koristiti.
Inicijalizacijska lista?
class Natjecatelj
{
private:
std::string mIme;
std::string mPrezime;
// ...
public:
Natjecatelj(std::string ime, std::string prezime) : mIme(ime), mPrezime(prezime) {}
// ...
};
int main(void)
{
Natjecatelj natjecatelj1("Wedran", "Dev");
return 0;
}
Jel moze netko malo pojasniti zadatak?
ZAD:// Napiši funkciju koja vraća pokazivač na n ti element liste. Parametri funkcije su glava liste i broj n.
Jel moze netko malo pojasniti zadatak?
ZAD:// Napiši funkciju koja vraća pokazivač na n ti element liste. Parametri funkcije su glava liste i broj n.
Dobijes pokazivac na glavu. Prolazis po listi n puta (ona fora node->next). Kad prodes tih n puta, tada ces imati pokazivac na n-ti element i njega returnas.
da li je ovo dovoljno dobro rjesenje za taj isti problem?
http://pastebin.com/RFNTGZH3
da li je ovo dovoljno dobro rjesenje za taj isti problem?
http://pastebin.com/RFNTGZH3
Onaj return ne treba, i ja bi drukčije izveo funkciju elementn u maloj sitnici, ali ništa nema što bi zamjerio. Petica.
#include <iostream>
#include <string>
using namespace std;
struct cvor
{
string n1;
int n2;
cvor *veza;
};
void dodaj(cvor *&glava, string p1, int p2)
{
cvor *n = new cvor;
n->n1 = p1;
n->n2 = p2;
n->veza = glava;
glava = n;
}
void dodaj_kraj(cvor *& glava, string s, int n)
{
cvor *novi = new cvor;
novi->n1 = s;
novi->n2 = n;
novi->veza = NULL;
if (glava == NULL){
glava = novi;
}
else{
cvor *tr = glava;
while (tr->veza != NULL){
tr = tr->veza;
}
tr->veza = novi;
}
}
void ispisi(cvor *glava)
{
cvor *tr = glava;
while (tr != NULL){
cout << tr->n1 << " " << tr->n2 << endl;
tr = tr->veza;
}
}
cvor * elementn(cvor* glava, int redniBroj) {
cvor *tr = glava;
while (tr != NULL && redniBroj-1>0){
tr = tr->veza;
redniBroj--;
}
return tr;
}
int main()
{
cvor *glava = NULL;
dodaj_kraj(glava, "prvi", 745);
dodaj_kraj(glava, "drugi", 3123);
dodaj_kraj(glava, "treci", 213);
ispisi(glava);
cvor *mojCvor = elementn(glava, 2);
cout << "Trazeni stogod: " << mojCvor->n1 << " " << mojCvor->n2;
return 0;
}
Baš sam planirala postaviti pitanje može li se to kako jednostavnije riješiti tj. izvesti? I može li malo pojašnjenje izmjene? Hvala. :)
Baš sam planirala postaviti pitanje može li se to kako jednostavnije riješiti tj. izvesti? I može li malo pojašnjenje izmjene? Hvala. :)
Petlju while vrtimo dok ne pronadjemo traženi redni broj ili ne dođemo na kraj niza. Smanjujemo redni broj dok ne dodje na 0, a za redni broj 1 je prvi element po redu, primjeti da uopće ne ulaziimo u while petlju.
Još jedna napomena, ako funkcija vrati null pokazivač, odnosno ako nema tog rednog broja, u main funkciji ne smiješ ispisivati elemente, nego idi if(mojCvor != null) {ispisi} else {redni broj ne postoji}
AC Milan - IL CLUB PIU' TITOLATO AL MONDO