Programiranje u C-u - od svega pomalo
- poruka: 1.661
- |
- čitano: 386.997
- |
- moderatori:
Lazarus Long, XXX-Man, vincimus
- +/- sve poruke
- ravni prikaz
- starije poruke gore
To je preteško za nas. Prvo ti nama pomozi pa napiši bar jedan dio toga pa ćemo vidjeti da ti pomognemo to dovršiti.
Pozdrav, iman jedno pitanje.
Zašto sve koristit debuger, nisan ga nikad koristia pa neznan. Jeli to može samo izvršavat liniju po liniju koda, ili također recimo pruža uvid u memoriju? Npr. za gledanje registara varijabli?
Ako može gledat u registre, može li neko objasnit kako ako je jednostavno ili dat neki dobar link? Video tutorial po mogucnosti. :)
Debuger je koristan pri ispravljanju greški u programu. Primjerice, tvoj program se u nekoj liniji coda ruši a ti ne znaš zašto. Pa onda staviš breakpoint na tu liniju coda i onda debuger zaustavi program na toj liniji. Tada možeš vidjeti koje su vrijednosti svih varijabli u programu u tom trenutku pa tako prema tome vidjeti mogući razlog rušenja programa. Možeš čak u tom trenutku mijenjati vrijednosti pojedinih varijabli da testiraš konkretne slučajeve za greške itd.
Također, preko debugera možeš vidjeti kako se program izvršava liniju po liniju tj. kako i kada se pozivaju neke funkcije, vidjeti što se u njima događa tokom izvršenja programa itd.
Debuger je koristan pri ispravljanju greški u programu. Primjerice, tvoj program se u nekoj liniji coda ruši a ti ne znaš zašto. Pa onda staviš breakpoint na tu liniju coda i onda debuger zaustavi program na toj liniji. Tada možeš vidjeti koje su vrijednosti svih varijabli u programu u tom trenutku pa tako prema tome vidjeti mogući razlog rušenja.
Da, a kako vidit koje su vrijednosti varijabli, tako da ih ispišemo ili se može i pogledat u registre memorije?
Debuger je koristan pri ispravljanju greški u programu. Primjerice, tvoj program se u nekoj liniji coda ruši a ti ne znaš zašto. Pa onda staviš breakpoint na tu liniju coda i onda debuger zaustavi program na toj liniji. Tada možeš vidjeti koje su vrijednosti svih varijabli u programu u tom trenutku pa tako prema tome vidjeti mogući razlog rušenja.
Da, a kako vidit koje su vrijednosti varijabli, tako da ih ispišemo ili se može i pogledat u registre memorije?
Svaki kvalitetan IDE ima dobar vizualni prikaz stanja prilikom uporabe debugger-a.
Dakle ne moraš ništa raspisivati.
U trenutku štopanja programa imaš prikaz svih varijabli , adresa , vrijednosti ... na ekranu.
Najbolje ti je upaliti IDE koji koristiš , stavi bilokamo breakpoint i bit će sve puno jasnije.
Ovako to izgleda na Qt Creatoru :
pozdrav
evo jedan problem pa ako moze netko kakvu ideju ili pseudokod za rjesenje dat,
imam zadanu maticu (npr. neka bude [6][12]) te je popunjena nulama i jedinicama te neki n broj (neka bude 9)
u matrici trebam naci sve povrsine (povrsine su pravilnog oblika 2x3 , 5x10....te najvece moguce) popunjene jedinicama koje su >= 9, njihovu pocetnu i zavrsnu tocku
znaci npr. za ovu matricu postoje 4 povrsine koje zadovoljavaju uvijet
1. od [1][0] do [3][5]
2. od [1][3] do [4][5]
3. od [1][4] do [5][5]
4. od [1][9] do [3][11]
Znači, ovako razBu. Dođeš do prve jedinice u zadanoj matrici (mxn veličine), te kreneš ispitivati koliko ima jedinica u slijedu(crna boja na slici). Kad dojdeš do prve nule u susjednom elementu, kreneš prema dolje gledati koliko ima jedinica.
Znači, dobio su „dužinu“ svoje jedne stranice traženog oblika, pa se spuštaš dolje da vidi koliko je druga stranica tvojeg oblika „dugačka“. Na taj način se vratiš do onog elementa matrica od kuda si krenuo. Sada provjeravaš dal' nemaš slučajno koju nulu u tvom svojem svojevresnom „pravokutnik“. Spustiš se za jedan element dolje, te vršiš provjeru da nema 0. te tako za sve one redove koji su unutar tvojeg pravokutnika. Ako nema 0, ti si pronašao svoj prvi pravokutnik.
Eh, ona do prve slijedeće jedinice od kuda si krenuo, sve ponovno...
Lako se ubaci, onda ubaci neki uvjet koliko taj oblik smije najviše imati jedinica...
fala ti
works like a charm
Napisati program koji implementira funkcionalnosti studentske službe.
1. Omogućiti operacije unosa, izmjene, pregleda i brisanja: studijskih programa, predmeta, nastavnika, studenata, ispita, ocjena, godina studija i akademskih godina.
2. Početno punjenje baze vršit će se iz tekstualnih datoteka.
3. Unos novih stavki, te izmjenu postojećih vršiti sa tastature.
4. U slučaju izmjena na bazi prebrisati postojeću tekstualnu datoteku na koju se izmjena odnosi.
5. Željenu radnju (unos, izmjena, pregled, brisanje) korisnik unosi preko tastature na osnovu ponuđenih opcija u terminalu.
6. Za novi unos definirati potrebne kolone i ograničiti unos ukoliko se ne unesu potrebni podaci.
7. Za povezivanje tabela koristit će se ključevi, koji predstavljaju jedinstveni identifikator određene stavke:
- studijski program: tekstualna skraćenica od 2 znaka (IT, SP, itd.)
- predmet: tekstualna skraćenica od 4 znaka (URIT, PJIP, RAMR, itd.)
- nastavnik: tekstualni JMBG sa 13 cifara
- student: tekstualni broj indeksa (npr. I-0001/14)
- ispit: kontejner sa informacijom o predmetu, datumu i studentu
- godina studija: cijeli broj (1,2,3,4,5)
- akademska godina: tekstualna oznaka u formatu xxxx/yyyy (npr. 2015/2016.)
8.Napraviti dokumentaciju projekta u obliku Word dokumenta. Koristiti ovaj dokument kao šablon, obrisati 5. poglavlje i početi sa tim poglavljem svoj izvještaj o projektu.
Ako to trebaš u C-u napisati - Good luck!
Moraš sam krenuti i dati nešto koda da vidimo gdje si zapeo, nitko ti neće to iz nule raditi...
Tipično za ovaj forum. Čovjek s 0 dana članstva traži naivčine da mu riješe domaću zadaću.
Ja sa uradio al nije to to,imam ja uradjen ovaj primjer ali nece mi kompajlirati
#include <iostream>
#include <conio.h>
#include <string>
#include <iomanip>
using namespace std;
class Student {
protected:
string ime,prezime;
int indeks,brocjena;
double prosjek;
public:
Student(string ime,string prezime, int indeks) : ime(ime),
prezime(prezime), indeks(indeks),brocjena(0),prosjek(5){}
//string VratiIme() const { return ime; }
int VratiIndeks() const { return indeks; }
void UpisiOcj(int ocj);
virtual void Ispisi() const {
cout<<"Student "<<ime<<" "<<prezime<<" sa brojem indeksa "<<indeks
<<" ima prosjek "<<setprecision(2)<<prosjek<<endl;
}
};
void Student::UpisiOcj(int ocj){
double suma=brocjena*prosjek;
suma+=ocj;
brocjena++;
prosjek=suma/brocjena;
}
class Student_VI_stepena : public Student{
public:
Student_VI_stepena(string ime,string prezime, int indeks):
Student(ime,prezime,indeks){}
void Ispisi() const {
cout<<"Student VI stepena "<<ime<<" "<<prezime<<" sa brojem indeksa "<<indeks
<<" ima prosjek "<<setprecision(2)<<prosjek<<endl;
}
};
class Student_VII_stepena : public Student{
public:
Student_VII_stepena(string ime,string prezime, int indeks):
Student(ime,prezime,indeks){}
void Ispisi() const {
cout<<"Student VII stepena "<<ime<<" "<<prezime<<" sa brojem indeksa "<<indeks
<<" ima prosjek "<<setprecision(2)<<prosjek<<endl;
}
};
class Student_postdiplomac : public Student{
int goddipl;
public:
Student_postdiplomac(string ime,string prezime, int indeks,int goddipl):
Student(ime,prezime,indeks),goddipl(goddipl){}
void Ispisi() const {
cout<<"Student postdipl. studija "<<ime<<" "<<prezime
<<" sa brojem indeksa "<<indeks
<<",\ndiplomirao godine "<<goddipl
<<", ima prosjek "<<setprecision(2)<<prosjek<<endl;
}
};
class Stud_sluzba{
int brstud;
const int maxbrstud;
Student **studenti;
Stud_sluzba(const Stud_sluzba &v);
Stud_sluzba &operator =(const Stud_sluzba &v);
public:
Stud_sluzba(int kapacitet):maxbrstud(kapacitet),brstud(0),
studenti(new Student*[kapacitet]){
for(int i=0;i<maxbrstud;i++)studenti[i]=0;
}
~Stud_sluzba(){
for(int i=0;i<maxbrstud;i++)delete studenti[i];
delete[] studenti;
}
void UpisiStud(int brind,string Ime,string Prez,int GodDipl);
void UpisiOcjenu(int brind,int ocjena);
void IspisiSpisak(){
for(int i=0;i<brstud;i++)
studenti[i]-> Ispisi();
}
friend class Student_VI_stepena;
friend class Student_VII_stepena;
friend class Student_postdiplomac;
};
void Stud_sluzba::UpisiStud(int brind,string Ime,string Prez,int GodDipl){
if(brstud==maxbrstud)throw "nema mjesta...";
if(GodDipl==6)
studenti[brstud++]=new Student_VI_stepena(Ime,Prez,brind);
else if(GodDipl==7)
studenti[brstud++]=new Student_VII_stepena(Ime,Prez,brind);
else
studenti[brstud++]=new Student_postdiplomac(Ime,Prez,brind,GodDipl);
}
void Stud_sluzba::UpisiOcjenu(int brind,int ocjena){
int pom(-1);
for(int i=0;i<brstud;i++){
if((studenti[i]->VratiIndeks())==brind){
pom=i;break;
}
}
if(pom==-1)throw "ne...";
studenti[pom]->UpisiOcj(ocjena);
}
int main(){
try{
//Ovdje testirati klasu...
}
catch(...){
cout<<"error!";
}
getch();
return 0;
}
Imam jedno pitanje.
Kako tj. na koji način tražiti najveći zajednički podstring iz 3 različita stringa?
Npr. ako su stringovi abcdef, ccbcdcde i bcdbcdbcd, program bi mi trebao naći bcd.
Ne treba mi gotovo rješenje, nego samo ako netko može objasniti kako tražiti taj dio stringa. U funkciju prosljeđujem 3 stringa i ona bi mi trebala vratiti taj zajednički.
Googlao sam zadnjih sat vremena i tamo su većinom rješenja za 2 stringa i ne mogu baš skužiti što se tamo točno radi.
Zanimljiv zadatak!
Po meni! Uzmeš jedan string, pa ga uspoređuješ sa drugim. Jedan znak prvog stringa tražiš jel' ima isti takav zna u drugo stringu. Ako ima, spremiš taj znak u pomoćni neki string. Nakon toga, odmah pređeš na drugi znak, te tako kad opet naiđeš na isti znak, spremiš u taj pomoćni string. Nakon toga, vršiš provjeru za treći string, a to možeš odmah tim dobivenim pomoćnim poljem.
Npr, imaš tri stringa, "dinamo", "nama" i "namještaj".
prva provjera: znak "d" tražiš u drugo stringu, ako ga nema, odeš na znak "i" ni njega nema, onda ideš na znak "n", eh njega ima, pa ga spremiš u pomočni string, te odmah pređeš na drugo slovo "a", pa tako dobiješ na kraju pomočni string "nam", te onda pošto si već provjerio dva stringa, sa tim pomoćnim stringom provjeriš treći string.
Znači, provjeravaš znak po znak, te ako pronađeš dva ista spremiš u temp string.
Ovo je brzinsko nekakvo rješenje.
Ako zna netko lakše i bolje, nek' se javi sa svojim.
Ovo ne radi dobro ako su npr. zadani stringovi "dinamo", "na nama" i "namještaj" - tvoj algoritam daje "na" (a treba "nam"). Prvo "n" u stringu "na nama" je lošiji kandidat od drugog "n", tj. postupak ne smije stati nakon prvog pronađenog preklapanja.
Dodatni problem je što može biti više rezultata pa nije dovoljna jedna pomoćna varijabla, npr. za "abcX123", "abcY123" i "abcZ123" postoje dva rješenja, "abc" i "123".
Wikipedija ima članak longest common string problem. Rješenje koje koristi dinamičko programiranje za tri stringa S, T, U (duljine m, n, p) ide ovako
1. napravi nul-matricu L dimenzija m X n X p
2. ako je S[i] == T[j] == U[k] onda je L[i, j, k] = L[i-1, j-1, k-1] + 1
3. elementi L koji imaju najveće vrijednosti predstavljaju koordinate kraja najduljih zajedničkih podstringova.
Konkretan kod za tri stringa u Pythonu:
def LCSubstr(S, T, U):
m = len(S)
n = len(T)
p = len(U)
L = [[[0 for x in range(p)] for x in range(n)] for x in range(m)]
z = 0
ret = set()
for i in range(m):
for j in range(n):
for k in range(p):
if S[i] == T[j] == U[k]:
if i == 0 or j == 0 or k == 0:
L[i][j][k] = 1
else:
L[i][j][k] = L[i - 1][j - 1][k - 1] + 1
if L[i][j][k] > z:
z = L[i][j][k]
ret = {S[i - z + 1:i+1]}
elif L[i][j][k] == z:
ret.add(S[i - z + 1:i+1])
else:
L[i][j][k] = 0
return ret
print(LCSubstr('abcdef', 'ccbcdcde', 'bcdbcdbcd'))
print(LCSubstr('dinamo', 'nama', 'namještaj'))
print(LCSubstr('dinamo', 'na nama', 'namještaj'))
print(LCSubstr('abcX123', 'abcY123', 'abcZ123'))
================================= REZULTAT ==================================
{'bcd'}
{'nam'}
{'nam'}
{'123', 'abc'}
U C++ to bi se ovako napravilo
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int T[100][100][100];
vector<string> SubString(string a, string b, string c)
{
int maxLength = 0;
vector<string> I;
string temp;
for (int i = 0; i < a.size(); i++)
{
for (int j = 0; j < b.size(); j++)
{
for (int k = 0; k < c.size(); k++)
{
if (a[i] == b[j] && b[j] == c[k])
{
if (i == 0 || j == 0 || k == 0) T[i][j][k] = 1;
else T[i][j][k] = T[i - 1][j - 1][k - 1] + 1;
if (T[i][j][k] > maxLength)
{
maxLength = T[i][j][k];
I.clear();
I.push_back(a.substr(i - maxLength + 1, maxLength));
}
else if (T[i][j][k] == maxLength)
{
temp = a.substr(i - maxLength + 1, maxLength);
if (find(I.begin(), I.end(), temp) == I.end())
I.push_back(temp);
}
}
else T[i][j][k] = 0;
}
}
}
return I;
}
void Print(vector<string>& I)
{
for (std::vector<string>::iterator it = I.begin(); it != I.end(); it++)
cout << *it << endl;
}
int main()
{
vector<string> I;
I = SubString("dinamo", "nama", "namjestaj");
Print(I);
I = SubString("abcdef", "ccbcdcde", "bcdbcdbcd");
Print(I);
I = SubString("dinamo", "na nama", "namjestaj");
Print(I);
I = SubString("abcX123", "abcY123", "abcZ123");
Print(I);
return 0;
}

Ne, bitno je samo da je izvan glavnog programa, jer ionako se prvo on izvodi, pa te onda u njemu se pozivaju funkcije.
Al' radi preglednosti, obično se funkcije pišu prije glavnog programa.
Inače, ja kad pišem, onda stavljam prototip na početak, a razradu na kraju programa.
Ali razlike kako je već rečeno nema
To ovisi o mjestu gdje se događa poziv funkcije. Primjerice,
void f() {
// ....
}
int main(){
f(); // radi uredno
return 0;
}
U ovom slučaju sve štima jer deklaracija funkcije postoji prije njenog poziva. No primjerice sljedeće je problem:
int main(){
f(); // greška!
return 0;
}
void f() {
// ....
}
Ukoliko se tijelo funkcije piše poslije njenog poziva onda se dobiju ovakve greške. Da bi se to spriječilo može se pristupiti kao u prvom slučaju, ili deklarirati prototip funkcije prije njenog poziva:
void f(); // prototip funkcije f
int main(){
f(); // radi uredno
return 0;
}
void f() {
// ....
}
Obično se prototipi funkcija stave u neku .h datoteku, pa se nju uključi direktivom include. Tada je onda svejedno gdje se nalaze njihova tijela.
Imam jedno pitanje.
Kako tj. na koji način tražiti najveći zajednički podstring iz 3 različita stringa?
Npr. ako su stringovi abcdef, ccbcdcde i bcdbcdbcd, program bi mi trebao naći bcd.
Ne treba mi gotovo rješenje, nego samo ako netko može objasniti kako tražiti taj dio stringa. U funkciju prosljeđujem 3 stringa i ona bi mi trebala vratiti taj zajednički.
Googlao sam zadnjih sat vremena i tamo su većinom rješenja za 2 stringa i ne mogu baš skužiti što se tamo točno radi.
Inače su za ovakve probleme (sa n stringova odjednom) sufiksna stabla odlično rješenje jer je njihova (poprilično kompleksna) izgradnja linearno proporcionalna sa zbrojem duljine nizova.
Pa ono, ako tko želi rješiti sličan problem u optimalnom vremenu (mislim da ne može bolje), neka malo pogleda sufiksna stabla, Ukkonenov algoritam i to.
To ovisi o mjestu gdje se događa poziv funkcije. Primjerice,
</cut>
Obično se prototipi funkcija stave u neku .h datoteku, pa se nju uključi direktivom include. Tada je onda svejedno gdje se nalaze njihova tijela.
Tipični primjer zašto izbjegavam c/c++. Niđe veze zašto ne bi mogao "po defaultu" zvati funkciju prije ili nakon njene definicije. Takvih stvari koje te tjeraju da više razmišljaš o programiranju nego o svrsi programa ima puno previše za moj ukus
Ne vidim u čemu je problem. Source jednostavno treba biti organiziran kroz .h i .c(pp) datoteke. Ukoliko se programer drži pravila da u .h stavlja deklaracije/prototipe a u .c(pp) implementaciju onda je sasvim svejedno kada pozivaš funkciju. To što eventualno neki ne znaju pravilno organizirati code nema veze s C/C++om.
Vidiš, ja imam običaj grupirati funkcije po #region, pogotovo ako rade nešto oko zajedničke stvari tipa add, update, delete ili čine neku logičku cjelinu (skup funkcija za dohvaćanje i obradu podataka?). Osim toga, pisanje tih prototipa mi izgleda kao višak (dvaput "definiram" funkciju).
Drugačiji način organizacije, valjda. Ali i dalje stoji da te "tjera" da ili napišeš prototip i staviš ga u .h pa koristiš funkciju kad god ili jednostavno moraš pisati definiciju funkcije prije njenog poziva.
Vidiš, ja imam običaj grupirati funkcije po #region, pogotovo ako rade nešto oko zajedničke stvari tipa add, update, delete ili čine neku logičku cjelinu (skup funkcija za dohvaćanje i obradu podataka?). Osim toga, pisanje tih prototipa mi izgleda kao višak (dvaput "definiram" funkciju).
Drugačiji način organizacije, valjda. Ali i dalje stoji da te "tjera" da ili napišeš prototip i staviš ga u .h pa koristiš funkciju kad god ili jednostavno moraš pisati definiciju funkcije prije njenog poziva.
C++ uredno podržava namespace-e koji si možeš napraviti pa tako grupirati bilo koji dio coda kako želiš.
namespace MojeDBFunkcije {
void Add(...);
void Delete(...);
...
};
Isto tako, ti namespace-i se mogu nalazi i sami grupirani unutar .h datoteke.
Također, pisanje deklaracija u .h datoteci nije samo stvar stila i ljepote već i praktičnosti. Kada imaš prototipe funkcija u .h datoteci ti ne moraš njihova tijela imati nužno u .cpp datoteci već ih možeš nekome dati compilirane kao .dll. Tako danas rade primjerice većina tvrtki koje prodaju komponente. Daju .h datoteku da vidiš koje funkcije i klase možeš koristiti, no njihova tijela ne daju u .cpp datoteci već u dll-u, tako da code ne vidiš (pa da ga možeš mijenjati i prodati pod svoje) ali ga možeš koristiti.
Drugačiji način organizacije, valjda. Ali i dalje stoji da te "tjera" da ili napišeš prototip i staviš ga u .h pa koristiš funkciju kad god ili jednostavno moraš pisati definiciju funkcije prije njenog poziva.
U biti i nije drugacije: u C# i Javi nema top-level funkcija koje ne pripadaju nekoj klasi, sve metode, pa i main, su dio neke klase. Za metode koje su dio klasa u C++ vrijedi isto pravilo - svejedno je kojim ih redom definiras, a mozes ih i sve stavit u cpp file. Jedino kod non-member funkcija je razlika, no to je usporedjivanje jabuka i krusaka onda.
Evo jedni odlični materijali ako učite C:
https://www.youtube.com/playlist?list=PLF875D917B4F481D0
Sa fakulteta VSITE, predmet im se zove Programske metode i apstrakcije.
.