C programiranje
(1 korsinik/a gleda/ju temu) (1) Gost

C programiranje


27.10.2010 | 23:57
Moram priznat da te nisam shvatio Djipi.

Jesi li rekao da Obj-C ima još i više potencijala nego danas, sa nekim budućim Intelovim CPU-ovima, ili upravo suprotno?
28.10.2010 | 00:04
Od svih navedenih C-ova, Obj-C u sebi ima "interpretersku" komponentu (na malo moderniji način: dinamičan je). Njegov run-time ima pune ruke posla s heklanjem linkova u kodu koji upravo izvršava. Pa nije ni čudo da je preporučena konfiguracija za pokretanje TextEdita "barem quad stroj". I da, procesori postaju brži pa se tom overheadu gleda kroz prste (to je onaj dio u kojem Intel trlja ruke). Ali činjenica je da aplikacije koje vrtimo na strojevima zapravo rade bolno sporo u odnosu na raw CPU snagu koju koristimo za njihovo pokretanje.

A potrošnja memorije je priča za sebe.
28.10.2010 | 21:31
Djipi je napisao:
Od svih navedenih C-ova, Obj-C u sebi ima "interpretersku" komponentu ...


Možda si se trebao malo pažljivije izraziti, ljudi će pomisliti da je stvarno u pitanju interpretirano izvođenje programa, a zapravo je to sve kompajlirani i optimizirani kod kao i za običan C.

Razlika je samo u tome da Objective C u toku izvođenja pogleda u internu tabelu za neku klasu da bi pronašao identifikator neke metode i onda je pozvao. Sve ostalo je u svemu identično kao i za normalan C.

To traženje po tabeli uzme neko vrijeme, ali to se sve vrti u nekim normalnim okvirima uspoređivanja inteđera. Koliko mi je poznato to u praksi izgleda kao recimo:

if (msgId == 0x001)
callMsg (procTable[0]);
else if (msgId == 0x002)
callMsg (procTable[1])
...

ili vjerojatnije neka varijanta koja koristi petlju ali zapravo funkcionira na prikazani način. U najgorem slučaju treba za neke kompliciranije klase napraviti stotinjak usporedbi dok ne pronađe metodu. Kad je pronađe, sve dalje ide kao i narmalni C.

Omjer brzine interpretiranih jezika u odnosu na kompajlirane je oko jedan naprema sto, dok je za Obj-C to unutar jedan naprema "jedan zarez nešto", u svakom slučaju ispod dva.

Vrag mi nije dao mira pa sam išao probati kako to u praksi izgleda. Ovo nije definitivni prikaz brzina pojedinih jezika, tek mala ilustracija koliko se vremena gubi na traženje metode u programu koji ne radi bog zna što tako da je većina vremena utrošena upravo na poziv funkcije u C-u, odnosno metode u Objective-Cu.

Prvo skripta koja mjeri vrijeme, usput je opisano kako se kompajliraju ova dva programa:
# gcc -g -Wall -o cprog cprog_test.c

before="$(date +%s)"

./cprog

after="$(date +%s)"
elapsed_seconds="$(expr $after - $before)"
echo Elapsed seconds for code block: $elapsed_seconds

# -----

# gcc -framework Foundation cprog_test.m -o objcprog

before="$(date +%s)"

./objcprog

after="$(date +%s)"
elapsed_seconds="$(expr $after - $before)"
echo Elapsed seconds for code block: $elapsed_seconds


C verzija:
// cprog_test.c

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>

static  int  addOne (int i)
{
   return (i+1);
}

int main (int argc, char *argv[])
{
   int  i = 0;
   while (i<1000000000)
      i = addOne (i);
   printf ("Done in C!\\n");
   
   return (0);
}


I objc verzija:
// cprog_test.m

#import <Foundation/Foundation.h>

@interface CounterClass : NSObject
{
   // no need
}

- (int)addOne:(int)i;

@end

@implementation CounterClass

- (int)addOne:(int)i
{
   return (i+1);
}

@end

int main (int argc, const char * argv[])
{
   int  i = 0;

   NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
   
   CounterClass  *counter = [[CounterClass alloc] init];
   
   while (i<1000000000)
      i = [counter addOne:i];
   printf ("Done in ObjC!\\n");

   [counter release];
   [pool drain];

   return (0);
}


Moj MacBook daje ove brojke:

$ ./script
Done in C!
Elapsed seconds for code block: 6
Done in ObjC!
Elapsed seconds for code block: 9


Dakle, vrlo daleko od 1 naprema 100. Baš me zanima koliko treba za izbrojati ovako kroz poziv funkcije u drugim jezicima do 1.000.000.000 - milijardu. Ako netko ima pri ruci neki interpreter?
28.10.2010 | 21:57
Eh, a onda sam to odlučio malo zakomplicirati, da kao u realnim programima ove funkcije ipak ne budu toliko trivijalne.
static  int  addOne (int i)
{
   if (i)  {
      int  j = i * 2;
      
      i = i + 2;
      if (j)
         i = i - 1;
      j = j / 2;
      if (j)
         i = i - 1;      
   }
   
   return (i+1);
}

- (int)addOne:(int)i
{
   if (i)  {
      int  j = i * 2;
      
      i = i + 2;
      if (j)
         i = i - 1;
      j = j / 2;
      if (j)
         i = i - 1;      
   }
   
   return (i+1);
}


Obije ove funkcije zapravo rade što i prije, samo sam ih zaposlio sa nepotrebnim obračunima tek toliko da nešto računaju. Dobivena vremena izvršavanja:

$ ./script
Done in C!
Elapsed seconds for code block: 16
Done in ObjC!
Elapsed seconds for code block: 17


Dakle, isto.
28.10.2010 | 22:23
Ne sporim brojke do kojih si došao u gornjim testovima, ali primjeri konkretnog softvera kojeg svakodnevno koristimo (i s pravom zovemo bloatware), za razliku od ovdje testirane situacije koriste gomile različitih metoda (koje moraju polinkati), kreiraju objekte (što znači beskonačno pozivanje malloca ili nečeg sličnog što radi alokaciju komadića memorije - tu treba biti objektivan pa priznati da je to način na koji OOP "penalizira", bez obzira na jezik koji koristimo - ali kad si već načeo Obj-C vs. C testiranje... ) i, ne manje bitno, dodaj u jednadžbu još id tip podataka s kojim se run-time također mora pozabaviti. S te tri komponente eto mu punih ruku posla u tipičnoj Cocoa aplikaciji.
28.10.2010 | 22:42
> beskonačno pozivanje malloca ili nečeg sličnog što radi alokaciju komadića memorije - tu treba biti objektivan pa priznati da je to način na koji OOP "penalizira", bez obzira na jezik koji koristimo - ali kad si već načeo Obj-C vs. C testiranje...

Ali za razliku od jave i Sharpa, Objective C u 99% slučajeva šalje objekte okolo by reference iz metode u metodu. Ostali OO jezici iz nekog razloga preferiraju slanje kopija tih objekata okolo što onda uključuje malloc vamo, malloc tamo.
22.11.2010 | 19:09
Programiranje je svakim danom sve zabavnije, pogotovo kad se skuzi stos

Kaj se tice Xcode-a, kako mogu napraviti da unutar jednog projekta imam vise fileova. Kada pokusam runnati drugi file, uvijek javlja neku gresku.
  • User
  • Posjetitelj
22.11.2010 | 20:56
nabaci output pa cemo ti lakse znat pomoc
22.11.2010 | 21:24
c++ je u stanju bit temeljito gori od C-a, kad ga udjeneš u templejte... i ako se zaglaviš u castove ... no istina, typedef je svakom prijatelj.
meni je c++ drag jer nije java, ne tjera te iritantno u oop "ommm" mantru, nije oop baš za sve najbolji... recimo standard template library nije baš oop. pa je dobar.



kad sam već počeo čekajuć da se tu nešto skompajlira, eo par onako bez reda, iskrcavanje informacija... lupio sam tebi odgovor al nema veze.

na PMFu (u Zagrebu, onaj splitski je noviji pa valjda i još napredniji) na matematici se uči C, kasnije i C++. Fortrana - barem na neprogramerskim smjerovima - gotovo više i nema, tako je već sigurno 10 godina. IFC kompajler za Fortran sam iskopavao samo za neke kolege fizičare.



danas se meni rokenrol čini - Python. cross platform, praktičan i solidan dinamički jezik, nekoliko "interpretacija", ima i za .net ...
na MIT-u ga uče i čak su napustili lisp (!) u nekim početničkim predmetima i nadomjestili ga pythonom.

meni se u mojoj praksi pokazao strašan za prototyping i "proof of concept". plus, ima gotovih izvrsnih librarya (numpy, scipy, matplotlib i N sličnih) i odlično sučelje spyder (spyderlib.google.com) mislim da će, što se mene tiče, stati na kraj i MATLABu i njegovoj iritantnom nekomukativnosti s ostatkom svijeta...

bacite oko na sveskupa: www.pythonxy.com

za učenje je simpatičan, podržava više paradigmi programiranja: hoćeš običnu skripticu: more. hoćeš objektno: ide... kruh zarađujem baš pythonom, i to kad ide ruku pod ruku sa C++om: točno kako treba, imam "best of both worlds". što je sporo ili imam libove ide u c++, što više paše u python - ide u pythonu. čak i klase u pajtonu nasljeđuju c++ i sve šljaka tip top.

najtoplija preporuka: tko radi u C++u ako ne koristi ništa sa www.boost.org onda je negdje nešto zaboravio. Boost je cool.




Liku koji je pitao što da instalira za programiranje u C++ - mislim da nije loš izbor Eclipse i CDT, plus gcc kompajler kojeg bi već trebao imati na Macu. je malo glomazno, ali to mi se čini najbolje: Eclipse je badava, a teško da će ga prerasti, a kao programerska okolina od jezika podržava sve živo, od Pythona i Jave, preko R (onog statističkog čudovišta) do krajnje opskurnih stvari. Plus, i Ekliptika je "cross platform".
22.11.2010 | 21:25
iiii zaradios am nagradu za iskopavanje threada iz bezdana.
nema veze...

morebit nekome posluži, ćo.
22.11.2010 | 23:58
Kaj se tice Xcode-a, kako mogu napraviti da unutar jednog projekta imam vise fileova. Kada pokusam runnati drugi file, uvijek javlja neku gresku.

Pobriši vrijednost Prefix Headera (GCC_PREFIX_HEADER) koju target template defaultno postavi na "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h". Taj default obično rezultira s peteroznamenkastim brojem compile errora.

A sad isto to, ali u malo više koraka, za svaki slučaj:
1. Kreiraš novi Xcode projekt - odabereš Mac OS X template -> Command Line Tool -> Type = C. Snimiš kao "MojProjekt".
2. Xcode je kreirao main.c za MojProjekt i u Targets (u Groups & Files) je vidljiv samo jedan target - MojProjekt. Build&Run... sve radi.
3. Desni klik na Targets, Add New Target (Mac OS X -> Cocoa -> Shell Tool). Ovdje počinju problemi jer će Xcode u nastavku podrazumijevati korištenje AppKit APIja. Nazovi novi target "NoviExe".
4. Pojavit će se Target "NoviExe" Info. Lociraj setting "GCC_PREFIX_HEADER", dvoklikni na value i OBRIŠI "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h" - nakon toga klikni "OK", GCC_PREFIX_HEADER će ostati "prazan".
5. Odabereš Source folder (u Groups & Files), desno dugme, Add New File (Mac OS X -> C and C++ -> C File). Snimiš kao "glavni.c", Xcode će defaultno stvoriti "glavni.h" (možeš i isključiti kreiranje headera, nebitan je za ovo). Xcode će "glavni.c" (i "glavni.h", ako ga je kreirao) automatski dodati u Compile Sources targeta "MojProjekt" - obriši ga od tamo (desno dugme, Delete - time ne brišeš fajl na disku već samo referencu na fajl) i odvuci ga iz Source foldera u Compile Sources targeta "NoviExe".
6. Kopiraj u "glavni.c" sadržaj "main.c", tek toliko da imamo što kompajlirati - pritom promijeni "Hello, World!" u "Zdravo, svijete!" da budemo sigurni da smo kompajlirati "glavni.c" (u sljedećem koraku).
7. Promijeni Active target iz "MojProjekt" u "NoviExe". Buildaj, pokreni. Radi.

Da ne bude nepoznanica: u postojeći projekt smo dodali novi "target", što nam omogućava da buildamo više od jednog (targeta). Problem je u tome što Cocoa Shell Tool podrazumijeva korištenje AppKit APIja kojeg tvoji C programi (pretpostavljam) ne koriste (pa tako ni ne importaju/linkaju...). Zavrzlamo se može i skratiti tako da se NE dodaje Cocoa Shell Tool target već BSD Shell Tool. Ali korisno je znati kako riješiti zavrzlamu ako ipak krenemo s Cocoa Shell Toolom.
23.11.2010 | 23:37
Malo sam se izgubila kod 5 koraka. Odvukla sam ga u noviExe i izbriala referencu na njega iz source-a. gdje ga mogu opet naci? kako da promjenim ovaj active target?

ima li neki kraci nacin da jednostavno pri vjezbanju za zadatake, kreiram novi file i runnam ga, a ne da za svaki novi zadatak radim novi projekt i radim sve ovo? naime u code blocks-u (koji mi cesto crasha na macu) to ide puuuuuno jednostavnije. otvori, save-aj, napisi, provjeri, i otvori novi file.
24.11.2010 | 00:14
Malo sam se izgubila kod 5 koraka. Odvukla sam ga u noviExe i izbriala referencu na njega iz source-a. gdje ga mogu opet naci? kako da promjenim ovaj active target?

Nisi trebala brisati referencu iz Sources nego iz Compile Sources (Targets/MojProjekt).

Ako si obrisala REFERENCU iz Sources, onda ti je originalni fajl i dalje na disku, u folderu projekta ("MojProjekt", vjerojatno u njegovom rootu). Dovuci ga (drag&drop) iz tog foldera nazad u Sources i pusti da ga Xcode ubaci u projekt kao referencu (u većini slučajeva kad se nešto ubacuje u projekt, odabere se "Copy", tako da kopira to što ubacuješ u folder projekta - što je ovdje besmisleno jer bi pokušao kopirati fajl preko samog sebe).

Ako si pak obrisala fajl ("Also Move to Trash" opcija kad pozoveš Delete) onda si ga bacila u smeće - od tamo ga možeš vratiti nazad u Xcode tako da napraviš ovo što sam opisao u gornjem odlomku, ali uz odabranu Copy opciju (da kopira iz smeća, a ne da napravi referencu na fajl u smeću jer će "nestati" čim isprazniš smeće).

Ajmo se vratiti još korak nazad pa možda sve bude jasnije.

Kad kreiraš PROJEKT, Xcode stvori osnovni TARGET u koji će kompajlirati tvoj projekt. Taj target je ono što će na kraju postojati na disku, kao izvršna datoteka.

Ako se projekt zove "MojProjekt", Xcode će pod Targets kreirati "MojProjekt" target i (s obzirom da kompajliraš shell tool), to će ti omogućiti da kasnije iz terminala pozoveš (izvršiš) MojProjekt (kao "naredbu" ). No, koliko sam shvatio, ti ne izvršavaš to što buildaš iz terminala nego isključivo iz Xcodea pa pustimo sad terminal po strani.

Nazad u Xcode. Xcode podrazumijeva da ono što "ubacuješ" u njega (ili kreiraš u njemu, poput novih .c fajlova), nakon kompajliranja, linkanja ili jednostavnog kopiranja (koje se koristi za slike, ikone...) mora "spakirati" u target. U shell tool targete "pakira" samo izvršni fajl, ali u aplikacije pakira puno toga (Mac aplikacija je bundle, odnosno folder). Preskočimo priču o bundlovima, bitno je samo da nakon kompajliranja, rezultat završi u targetu, na disku, kao izvršna datoteka.

Ako želiš iz jednog projekta buildati više izvršnih datoteka (ili čega god - jer možeš buildati pluginove, biblioteke...), moraš imati više targeta.

Kad kreiraš projekt, aktivan je target koji se kreirao skupa s projektom. Primjetit ćeš da ima mali zeleni checkbox (ikonica targeta pod Targets). Kad kreiraš NOVI target, taj neće imati checkbox. Xcode defaultno kompajlira samo aktivni target (dakle, onaj koji ima checkbox). Zato moraš novom targetu (u primjeru je to "NoviExe" ) reći da je on aktivan target. Ima više načina za to učiniti, ali poslužit će glavni izbornik: Project -> Set Active Project -> NoviExe. Xcode će "NoviExe" označiti zelenim checkboxom kao aktivan target i kad klikneš na Build and Run, njega će kompajlirati/izvršiti.

Postoji i način za kompajlirati SVE targete istovremeno, ali to ćemo također preskočiti.

Zvuči kao "puno posla", ali zapravo nije. Samo zapamti da za napraviti NOVU izvršnu datoteku iz postojećeg projekta moraš kreirati NOVI target i u njegov Compile Sources dodati onaj source (ili više njih, nemam pojma što pokušavaš kompajlirati) koji kompajliraš u tu izvršnu datoteku. Nakon toga switchaš aktivni target u taj novi i pripaziš da je Prefix Header setting "prazan" (ili pak kreiraš BSD shell tool target pa će sigurno biti "prazan" i imaš korak manje za obaviti).

ima li neki kraci nacin da jednostavno pri vjezbanju za zadatake, kreiram novi file i runnam ga, a ne da za svaki novi zadatak radim novi projekt i radim sve ovo? naime u code blocks-u (koji mi cesto crasha na macu) to ide puuuuuno jednostavnije. otvori, save-aj, napisi, provjeri, i otvori novi file.

Ako ti je terminal "prijatelj", možeš kod pisati u kojem god želiš text editoru i kompajlirati iz terminala s

gcc -o MojProgram MojProgram.c

Brže ne može.

Ajde sad pliz podijeli s nama o kakvim je programima riječ pa možda netko ima praktičan savjet kako s njima najbrže baratati.
24.11.2010 | 09:58
Hvala na uputama, probat cu navecer kada se vratim doma pa javim rezultate.

Radi se o jednostavnim matematickim zadatcima za vjezbanje, nikakvi programi s kilometarskim linijama (ako vas zanimaju --> degiorgi.math.hr/prog1/materijali/p1-zad...akticni_kolokvij.pdf) no stvar je da mi ide na zivce sto uvijek moram raditi novi projekt za novi zadatak pa sam ih mislila sve strpati pod jedan projekt.
24.11.2010 | 12:51
Gledam zadatke. S obzirom da kompajliranje iz terminala nije komotno u smislu debuggiranja, Xcode je definitivno sretnija opcija. Ovo s više targeta u projektu bi trebalo poslužiti i to je definitivno najuredniji put ako ti treba 48 (koliko ima zadataka) različitih izvršnih datoteka.

No, ja bih (jer mi se, kao ni tebi, ne bi dalo kreirati 48 targeta) na tvom mjestu napravio nešto drugo: svaki zadatak bih riješio kao FUNKCIJU koju potom pozivam iz main. Dakle, imaš JEDAN projekt, u njemu jedan main.c (koji defaultno nastane) i u njemu samo mijenjaš pozive funkcija. Po potrebi toj funkciji (koja je rješenje zadatka) proslijediš i argumente komandne linije (argc/argv). Tako imaš samo jedan target, sourceove skupljaš u projektu (makar se zvali zadatak1.c, zadatak2.c...), a razlika je samo u tome što svaki source nije "spakiran" u vlastitu main() funkciju nego, primjerice, zadatak1 u funkciju zadatak1() koju će pozvati main() funkcija iz main.c. I opet zvuči kompliciranije nego što je. A i dobro je za vježbati funkcije.
  • User
  • Posjetitelj
24.11.2010 | 19:52
Inače meni nikad nije bio problem na vježbama u Visual Studiu napravit novi projekt za svaki novi zadatak, isto tako ni s Xcode-om.

Po meni je jednostavnije i to nego pisat zadatke kao funkcije, al dobro sve je stvar kako si ko voli izorganizirat
27.11.2010 | 20:11
Danas sam uhvatila vremena pa sam ponovno probala postupak i uspio je ovaj put. Hvala na pomoci!

Kuzim na kaj mislis, svakako je dobra vjezba za funkcije!
27.11.2010 | 21:01
Napisati program koji ucitava matricu A i ispisuje je na ekran, zatim funkcija koja vraca vrijednost determinante matrice A, kao i transponiranu matricu. Pa nova matrica B, program treba da izvrsi sabiranje, oduzimanje, mnozenje matrica A i B.
Ispisati inverzni za B, kao i adjungovanu matricu matrice A.
Moze li neko rijesit...
18.03.2011 | 22:06
Pozdrav forumašima... Može li me netko uputiti na neki link ili neku literaturu o klasama, povezanim listama u c++-u? Tražila sam po net-u ali sve što sam našla nije mi baš pomoglo... Ili ako ima netko voljan da mi objasni kako da u dvostruko povezanu listu ubacim element x na početak liste. Kužim da tu treba pokazivač koji pokazuje na prvi element u listi postaviti tako da pokazuje na taj element x, pokazivač elementa x postaviti da pokazuje na element koji je prije bio prvi, a taj element pokazuje na element x jer se radi o dvostruko povezanoj listi... Ali problem je što ne znam kako da to iskodiram... To bi išlo nešto kao head.next = x;? ili head->next = x? Molim vas da mi pomognete...
Unaprijed zahvalna...
18.03.2011 | 22:57
Da. Za početak, ne znam kakve ti posebne veze imaju klase s vezanim listama.

Ali, recimo ovako. Imaš klasu "element" koja ima osobine

.value - vrijednost
.next - idući član u vezanoj listi
.previous - prethodni član u vezanoj listi

zadnji element ima .next postavljen na null, a prvi element ima .previous postavljen na null

ako je prvi element pohranjen u varijabli (objektu) koji se zove head, a novi u varijabli x i želiš x dodati na početak liste, onda to izgleda ovako

head.previous=&x
x.next=&head
x.previous=null

jesi li to htjela?

C++ nisam koristio od faksa i nemam literature pri ruci pa nisam siguran da li je x.next ili je x->next, ali probaj pa vidi.
18.03.2011 | 23:07
Probala sam to ovako kako ste mi rekli... I ne radi...
Evo koda da pa ako netko vidi što bih trebala napravit...

#include<iostream>
using namespace std;

class Element // definicija klase Element koja cini element liste
{
 public:
  int key;
  Element* prev ;
  Element* next ;
  Element(int key) // konstruktor
  {
    this->key = key;
    prev = NULL; // pokazivac na prethodni clan liste
    next = NULL; // pokazivac na sljedeci clan liste
  }
};

class DLList
{
 protected:
  Element* head;
  Element* tail;

 public:
  DLList () // konstruktor liste
  {
     head = NULL;
     tail = NULL;
  }
  ~DLList() // destructor liste
  {
    Element* tmp = head;
    while (tmp = NULL)
    {
           Element* tmpDelete = tmp;
           tmp = tmp->next;
           delete tmpDelete;
    }
    head=tail=NULL;
  }

  void insert(int k) // ubacivanje elementa na pocetak liste
  {
    Element *node = new Element(k);
    head->prev=&k;
    k->next=&head;
    k->prev=NULL;
  }


  Element* search(int k) // -- pretraživanje elementa s ključem k u listi
  {
      Element *tmp = head;
      
      while (tmp != NULL)
      {
             if (tmp->key == k)
             {
                 return tmp;
             }
             tmp = tmp->next;
      }
      return NULL;
  }

  void Delete(int k) // procedura koja briše prvi element iz liste s kljucem k
  {
      Element *tmp = head;
      
      while (tmp != NULL)
      {
             if (tmp->key == k)
             {
                 delete tmp;
             }
             tmp = tmp->next;
      }
      return;
  }

  void print() // procedura za ispis elemenata liste
  {
     Element *tmp = head;
     cout << head << " ---> " ;
     while (tmp != NULL)
     {
            cout << "|" << tmp->key << "|" << tmp->next << " ---> ";
            tmp = tmp->next;
     }
     cout << endl;
     return;
  }

  void printReverse() // procedura za obrnuti ispis elemenata liste
  {
     Element* tmp1 = tail;
     cout << tail << " ---> " ;
     while (tmp1 != NULL)
     {
            cout << "|" << tmp1->key << "|" << tmp1->prev << " ---> ";
            tmp1 = tmp1->prev;
     }
     cout << endl;
     return;
  }

  void deleteList() // brisanje cijele liste
  { 
      head=tail=NULL;
  }

  bool empty() // provjeri je li lista prazna
  {
     int counter = 0;

     Element* tmp = head;
     while (tmp != NULL)
     {
            counter++;
            tmp = tmp->next;
     }
     if (counter == 0)
     {
         return 1;
     }else
      {
          return 0;
      }
  }

  unsigned int size() // funkcija koja vraca trenutni broj elemenata u listi
  {
    int counter = 0;
    Element* tmp = head;

    while (tmp != NULL)
    {
           counter ++;
           tmp = tmp->next;
    }
    return counter;
  }
};

int main()
{
  DLList Lista;

  Lista.insert(2);
  Lista.insert(17);
  Lista.insert(99);
  Lista.insert(20);
  Lista.insert(34);
  Lista.insert(24);

  cout << "Ispis liste: " << endl;
  Lista.print();

  cout << "Ispis liste od zadnjeg elementa prema prvom: " << endl;
  Lista.printReverse();

  cout << "U listi ima " << Lista.size() << " elemenata. " << endl;

  if (Lista.empty()==1)
  {
      cout << "Lista je prazna." << endl;
  }else
   {
       cout << "Lista nije prazna." << endl;
   }

return 1;
}
18.03.2011 | 23:57
Stvarno sam zahrđao s C++, ali prilično sam siguran da kod deklaracije pointerskih varijabli treba pisati

Element *ime

a ne

Element* ime

Iako je moguće da griješim. C zaista nije "my cup of tea".

Kakve točno greške prilikom kompilacije dobivaš?
19.03.2011 | 00:07
Hm... Što se tiče pointera tu mi smo to radili na oba načina... Pa sad... Probat ću i tako kako ste mi rekli...
Evo grešaka:

/scriptrunner4/sr_Temp_17081437094d83e42462e91: In member function 'void DLList::insert(int)':
/scriptrunner4/sr_Temp_17081437094d83e42462e91:45: error: cannot convert 'int*' to 'Element*' in assignment
/scriptrunner4/sr_Temp_17081437094d83e42462e91:46: error: base operand of '->' is not a pointer
/scriptrunner4/sr_Temp_17081437094d83e42462e91:47: error: base operand of '->' is not a pointer
19.03.2011 | 00:24
C ne radi razlike u poziciji zvjezdice, ali za C++ ne znam
19.03.2011 | 03:28
Ovo je "popravljen" kod tvog zadatka, pa ga pogledaj. Pretpostavljam da radi ono što želiš.

#include<iostream>
using namespace std;

class Element // definicija klase Element koja cini element liste
{
 public:
  int key;
  Element* prev ;
  Element* next ;
  Element(int _key) : key(_key) // konstruktor
  {
    prev = NULL; // pokazivac na prethodni clan liste
    next = NULL; // pokazivac na sljedeci clan liste
  }
};

class DLList
{
 protected:
  Element* head;
  Element* tail;

 public:
  DLList () // konstruktor liste
  {
     head = NULL;
     tail = NULL;
  }
  ~DLList() // destructor liste
  {
    Element* tmp = head;
    while (tmp != NULL)
    {
           Element* tmpDelete = tmp;
           tmp = tmp->next;
           delete tmpDelete;
    }
    head=tail=NULL;
  }

  void insert(int k) // ubacivanje elementa na pocetak liste
  {
    Element *node = new Element(k);
    if(head == NULL) 
    { 
	head = node;
    }
    else
    {
	head->prev=node;
    	node->next=head;
    	node->prev=NULL;
    	head = node;
    }

    if(tail == NULL) tail = head;
    if(tail->prev == NULL && tail != head) tail->prev = head;
  }


  Element* search(int k) // -- pretraživanje elementa s ključem k u listi
  {
      Element *tmp = head;
      
      while (tmp != NULL)
      {
             if (tmp->key == k)
             {
                 return tmp;
             }
             tmp = tmp->next;
      }
      return NULL;
  }

  void Delete(int k) // procedura koja briše prvi element iz liste s kljucem k
  {
      Element *tmp = head;
      
      while (tmp != NULL)
      {
             if (tmp->key == k)
             {
		 if(tmp->prev != NULL) tmp->prev->next = tmp->next;
		 if(tmp->next != NULL) tmp->next->prev = tmp->prev;
                 
		 delete tmp;
		 return;
             }
             tmp = tmp->next;
      }
    
  }

  void print() // procedura za ispis elemenata liste
  {
     Element *tmp = head;

     while (tmp != NULL)
     {
            cout << "|" << tmp->key << "|";
            tmp = tmp->next;
     }
     cout << endl;
     return;
  }

  void printReverse() // procedura za obrnuti ispis elemenata liste
  {
     Element* tmp1 = tail;
    
     while (tmp1 != NULL)
     {
            cout << "|" << tmp1->key << "|";
            tmp1 = tmp1->prev;
     }
     cout << endl;
     return;
  }

  void deleteList() // brisanje cijele liste
  { 
    Element* tmp = head;
    while (tmp != NULL)
    {
           Element* tmpDelete = tmp;
           tmp = tmp->next;
           delete tmpDelete;
    }
    head=tail=NULL;
  }

  bool empty() // provjeri je li lista prazna
  {
     return (head == NULL) ? 1 : 0;
  }

  unsigned int size() // funkcija koja vraca trenutni broj elemenata u listi
  {
    int counter = 0;
    Element* tmp = head;

    while (tmp != NULL)
    {
           counter ++;
           tmp = tmp->next;
    }
    return counter;
  }
};

int main()
{
  DLList Lista;

  Lista.insert(2);
  Lista.insert(17);
  Lista.insert(99);
  Lista.insert(20);
  Lista.insert(34);
  Lista.insert(24);

  cout << "Ispis liste: " << endl;
  Lista.print();

  cout << "Ispis liste od zadnjeg elementa prema prvom: " << endl;
  Lista.printReverse();

  cout << "U listi ima " << Lista.size() << " elemenata. " << endl;

  if (Lista.empty())
  {
      cout << "Lista je prazna." << endl;
  }else
   {
       cout << "Lista nije prazna." << endl;
   }

return 0;
}


Što se tiče osnovne literature iz C++, preporučio bih ovu knjigu "Demistificirani C++", 3. izdanje od J. Šribara i B. Motika. Za algoritme (one osnovne) svakako jedna od cijenjenih knjiga je "Algorithms in C++" od Roberta Sedgewicka. Eto.
19.03.2011 | 13:55
Hvala na preporučenoj literaturi i na popravljenom kodu. Napravila sam još neke izmjene kod ispisa i radi ono što treba raditi, jedino što sad ima nešto što nisam radila na faksu i ne bih htjela to napisati a da ne razumijem što je... Pa ako biste mi mogli objasniti ovaj dio u klasi Element:

Element(int _key) : key(_key) // konstruktor


Mislim na ovo : key(_key)...

Onda mi nije jasno zašto se ovaj dio koda nalazi u metodi za brisanje određenog elementa u listi:

 if(tmp->prev != NULL) tmp->prev->next = tmp->next;
 if(tmp->next != NULL) tmp->next->prev = tmp->prev;


To bi bilo ono što mi nije jasno... Ako mi možete pomoći... Ako ne, hvala puno na dosadašnjoj pomoći
19.03.2011 | 14:27
Ovo prvo pitanje sam riješila na način kako smo mi radili, pa je sad ok... Ostaje još ovo drugo...
19.03.2011 | 14:42
Ako element tmp ima prethodni element (dakle, ako mu prev pointer nije null) onda postavljaš next pointer od tog prethodnog elementa da pokazuje na element koji slijedi tmp elementu. Dakle izbacuješ tmp element iz lanca.

Kužiš? (tmp->prev) je element koji prethodi tmp elementu, a (tmp->prev)->next je next pokazivač tog prethodnog elementa.

Isto tako i drugi redak: ako element tmp ima sljedeći element, onda prev pokazivač tog sljedećeg elementa postaviš da pokazuje na prethodni element tmp elementa. Dakle, izbacuješ tmp iz lanca i u drugom smjeru.
19.03.2011 | 15:27
Kužim Hvala
Moderatori: Bertone

Vikalica™

Zadnja poruka: pred 6 sati, 49 minuta
  • ZeljkoB: smayoo, odakle ti ova informacija za SMS?
  • smayoo: SMS poruke su phase-out. Znači, neki ih operateri više ne nude, niti omogućavaju njihovo slanje. Određen je neki krajnji rok, nakon kojeg više nijedan operater u EU nije dužan osigurati propagiranje SMS poruka. Probaj ručno promijeniti operatera (pretpostavljam da si u roamingu)
  • Matija klc: Ekipa, pomoc. Nalazim se u Rumunjskoj. Primam poruke normalno, no ne mogu poslati poruku. Pricam o obicnoj. Sve drugo radi najnormalnije. Sta napraviti?
  • MoschuS: Ma svugdje ali sve neka mala mjesta ili sela po Hr ili Slo
  • JOHN: Jesu to oni iz Imotski?
  • MoschuS: Ako netko kupuje rabljeno racunalo pripazite se prevaranata na Njuskalu i Bolhi. Otkrio sam ih par, slicni oglasi i kada ih kontaktirate salju iste/slicne racune i serijske brojeve kao potvrdu i onda odjednom obrisu oglas, naprave novi account i pokusavaju dalje uloviti nekoga.
  • Zdravac: :) Na kraju će ispasti da nas ima dosta koji vozimo motore!
  • rkrosl: prodao triumpha, kupio triumpha
  • JOHN: Honda CB650R
  • FiFi: Skoro sam ga jednom zamijenio za Bandita 1200 , ali sam ipak odustao.
  • Zdravac: ...ili Suzuki Bandit :)
  • Zdravac: E, taj motor je nekad bio moj san, da nije uletila yamaha, sigurno bih toga sad vozio :)
  • FiFi: Honda CB900F2 Hornet, 2002. Evo radim servis i nadam se registraciji prvi put nakon tri godine stajanje (djeca ti promijene raspored vožnje)
  • Riba: Problem je sto "sezona" u Irskoj trtaje tjedan dana. :-D Moram vidjeti ima li kakav nacin da ga registriram u Hr.
  • Zdravac: @ZeljkoB Odličan motor, takvi motori su baš po mom guštu! Lijep i ugodan za voziti.
  • Zdravac: @Riba Pa što čekaš, daj, zamjeni ulje, filtere i svječice, napuni bateriju, i lagano pranje. To će biti dovoljno, siguran sam! :)
  • Zdravac: Ajd, super, nisam jedini! Sad ide sezona, i gušt! Polako plan za moto trip na more...
  • ZeljkoB: Honda NC750X, ali sve manje vremena imam za voznje.....
  • Riba: Imam ja BMW 650CS, mozda ga reaktiviram nakon 10 godina stajanja u garazi. A imam i Vespu iz 1959, ta malo duze stoji. :)
  • Zdravac: Evo, ja ću prvi: YAMAHA XJ900 S Diversion, classic iz 1998., ide ko švicarski sat, čista mehanika, pouzdano do bola! :)
  • Zdravac: Jel imamo ovdje kolega ili kolegica, da voze motor? Ako da, koji?
  • zoranowsky: @air, u biti isti je pricnip, samo si sam sebi target :)
  • Air: Polako, polaku, kuda žurba, daj mi prvo link na to kako pročitati vlastite misli :)
  • smayoo: Za one koji ne znaju čitati misli - [link] :D
  • Borisone: Za one koji ne znaju čitati misli, koja je konfiguracija?
  • VanjusOS: pozdrav, treba li netko Mac mini M2, nekorišteno?
  • kupus: Ima takvih naravno. Iz mog skromnog iskustva takvi su u manjini.
  • smayoo: većina online trgovaca odbija slati na poste restante pa čak i na poštanski pretinac
  • kupus: zasto na osobnu adresu*
  • kupus: Zasto na adresu? Naruci na adresu postanskog ureda, tamo ce te cekat
  • drlovric: Imamo li koga iz Zupanje na forumu da bih mogao naruciti paket na njegovu adresu? :)
  • ecvis17: ok, tnx
  • smayoo: Piši u forum
  • ecvis17: pozdrav svima, imam stari MBP koji maksimalno moze voziti BigSur ... malo nisam vise u toku, gdje se danas mogu pronaci Combo installeri? Tnx
  • cariblanco: Čekao je da Hajduk osvoji prvenstvo i na kraju je odustao ;)
  • Yonkis: Od sada ćemo mjeriti vrijeme pre-JM and post-JM time
  • JOHN: Ako je vjerovao, neka mu dragi Bog pomogne i uzme sebi. Ako nije, opet nema veze……sve u svemu mislim da je živio dobar život!
  • smayoo: Ljudi... ode nam Joža Manolić... Nije šala.
  • accom: ne nadjem...
  • accom: jel postoji tema "must have apps"?
  • Riba: Vjerojtano koliko je Apple mapa detaljna.
  • Yonkis: Ili da otvorim temu u forumu?
  • Yonkis: Jedna osoba dok je bila u Beču, mogao sam vidjeti njenu lokaciju točno na kojem je katu i u kojem dijelu zgrade je bila (iPhone 14 u pitanju). Zna li netko koji su preduvjeti za takvo točno lociranje jer u Hrvatskoj to još nisam nigdje doživio? Vidim lokaciju ali ne u 3D.
  • m@xym: Uostalom, palčevi su na ovom forumu odavno prestali biti relevantni, a nama koji smo redovito ovdje niti ne trebaju da bi smo znali kakav je tko.
  • m@xym: Nerviraj se samo zbog onih koji su ti bitni, a nebitne ignoriraj, inače ćeš ostati bez živaca.
  • Vanjuška: Nema nervoze m@xym, ali da javno prozovem malog žapčića da bog sve vidi i sve zna :D
  • smayoo: Ja nemam.
  • zvone: Servisom naime...
  • zvone: ljudi ima li tko iskustva sa sercisom iklinika?
  • m@xym: Čemu nervoza zbog palčeva?! Evo ti još jedna gore ako te to baš toliko muči.

Za vikanje moraš biti prijavljen.

Prijava

Prisutni jabučari

cariblanco, Gjuroo, tino1, Anonimci (627)

Novo na Jabučnjaku

Teme

Poruke

Anketa

Kupujete li profesionalni Mac?

Čekam novi modularni Mac Pro - 48.5%
Novac nije problem, kupujem iMac Pro - 0.7%
Kupujem Valjak, baš je lijep i tih! - 0%
Kupujem polovni Mac Pro tower - 11.8%
Nadogradit ću postojeći Mac Pro tower - 2.9%
Običan iMac 27" mi je dovoljan za posao - 5.9%
Skromnih sam potreba, Mac mini je zakon! - 7.4%
Radim na terenu, mora biti MacBook Pro - 3.7%
Ne diram ništa, stari Mac služi me odlično - 10.3%
Kupujem PC kantu i prelazim na Windowse! - 8.8%

Ukupno glasova: 136
Anketa je završena dana: 08 Svi 2018 - 12:17
Page Speed 1.75 Seconds

Provided by iJoomla SEO