Gå til innhold

Bone's Offisielle C++ hjelpetråd


Anbefalte innlegg

Videoannonse
Annonse

Hva som helst:

 

wxWidgets

FLTK

GTK

GTKMM

QT

+++

 

Edit:

Forutsetningen er at du kan bruke kompileren din.

 

Og det er greit å ha en fungerende editor:

 

* Dev-Cpp (er ikke verdens beste IDE, men duger i starten)

* Emacs

* ellernoeannetnoe

Endret av søppel
Lenke til kommentar

Ja - det er akkurat det man gjør.

 

Edit:

Men det finnes IDEer (editorer) med RAD-støtte, det vil si at du kan "tegne opp" GUIet; så genererer den kode for deg.

 

Jeg foretrekker å kode selv -- da det blir minst uventet krøll av det, og koden får samme stil som resten av prosjektet.

 

(og ikke minst -- det er når du gjør det selv at du lærer av det, og skjønner noe av det som foregår i koden)

Endret av søppel
Lenke til kommentar
  • 4 uker senere...

Hallo! Dei som har følgt med litt her har fått med seg at eg har begynt å lese i ei bok.

 

Problemet mitt er at eg ikkje er heilt stø på Engelsk. Difor har eg ikkje helt klart å forstå kva enum er god for... Det likna fælt på struct.

 

Og anngåande struct:

 

Eg har jo dreve litt og programmert i PHP og føler at eg beherskar det greit. I PHP har eg vendt meg til å bruke mykje arrays og enkle variablar. F.eks. slik:

array(
   "namn" -> "Klaus Olsen",
   "telefon" -> "58401840",
   "alder" -> 3
);

Dersom eg hadde mange personar ville eg bare ha laga dei i ein slik struktur:

array(
   1 -> array(
       "namn" -> namn
       ....
   )
   2 -> array(
       "namn" ...
       ....
   )
);

Eg forstår jo (trur eg) at det er i slike situasjonar at struct kan være god. Men eg forstår ikkje heilt korleis. Kan eg lage ein struct med struct slik at det blir slik?

string namn = personar.5.namn
string epost = personar.5.epost
osv...

Altså med fleire "ledd". Viss det går ville det jo vore hendig, men eg ser allikevel lite vist i å kutte ut arrayen til slik beandling...

 

Eller forresten. I ein struct kan du jo gjere slik at personar.namn er datatypen string, og personar.alder er int... Dette er jo greit. Men alt er jo mykje greiare i PHP ettersom ein array (og forsåvidt alt) kan innehalde tekst og tal omm ein annan.

 

Det same gjeld vector. Den er jo og like grei og kutte ut. Eg ville som PHP-programmerer heller ha brukt ein array...

 

Som de ser er eg sterkt forvirra etter å ha programmert PHP. I PHP er det jo ikkje vits å tenkje på datatypar (untatt ved sikkerheit ved bruk av SQL). Gidd nokon å prøve å forklare meg litt om desse tinga... Eg forstår kanskje meir når eg har lest ut boka og programmert litt og skaffa meg erfaringar. Men eg vil vite litt no òg. Ellerso forsvinn det bare ut av hjernen igjen...

Lenke til kommentar

enum brukes til å definere en type som kan ha bestemte verdier. Eksempel:

 

enum Day { monday, tuesday, wednesday, thursdag, friday, saturday, sunday };

 

Day brukes som en vanlig type:

Day d = friday;
d = monday;

 

Merk: enum har tallverdier. Det betyr at dersom du skriver ut verdien til d, vil (i dette tilfellet) 0 dukke opp på skjermen. (enums begynner å telle fra 0, og øker etterfølgende verdier med én.)

 

 

 

Det er flere problemer med arrays. Det største problemet er at et array har statisk størrelse: Når et array først er laget, kan det ikke legges til eller fjernes elementer fra det. (Det betyr derimot IKKE at elementer ikke kan slettes/nullstilles.) Et array kan også by på problemer om du skal bruke det som argument til en funksjon. std::vector har ikke disse begrensningene.

 

En struct er det samme som en klasse (class), bortsett fra at struct har public som standard tilgangsnivå. struct benyttes ofte til objekter med kun datamedlemmer (altså ingen funksjoner).

 

Jeg viser en løsning på Person-problemstillingen din med litt kode:

 

#include <iostream>
#include <string>

// Dette representerer en person. Alle tre medlemsvariablene er tilgjengelig for alle.
struct Person {
    std::string name;
    std::string phone;
    int age;
};

// Det meste her burde være opplagt...
int main()
{
    using namespace std;

    Person p = { "Yoda", "5334627837", 800 };
    cout << "Navn: " << p.name << "\nNummer: " << p.phone;
    cout << "\nAlder: " << p.age << endl;

    p.age++;
    cout << "Navn: " << p.name << "\nNummer: " << p.phone;
    cout << "\nAlder: " << p.age << endl;

    p.name = "Darth Vader";
    cout << "Navn: " << p.name << "\nNummer: " << p.phone;
    cout << "\nAlder: " << p.age << endl;
 return 0;
}

 

Eller en litt bedre løsning, vha. class:

#include <iostream>
#include <string>

// En person-klasse.
class Person {
public: // Følgende er tilgjengelig for alle
    // En konstruktør ("constructor"). Brukes for å lage en Person, og for å 
    // sette verdiene den initialiseres med.
    Person(const std::string& name, const std::string& phone, int age)
        : person_name(name), person_phone(phone), person_age(age) {}
    // En destruktør ("destructor"). Kalles automatisk når Personen dør. 
    // Denne destruktøren gjør ingenting.
    ~Person() {}

    // Funksjoner for å lese personens informasjon
    const std::string& name() const { return person_name; }
    const std::string& phone() const { return person_phone; }
    int age() const { return person_age; }

    // Funksjoner for å sette personens medlemsvariabler til nye verdier
    void set_name(const std::string& new_name) { person_name = new_name; }
    void set_phone(const std::string& new_phone) { person_phone = new_phone; }
    void set_age(const std::string& new_age) { person_age = new_age; }

    // Deklarasjon for en funksjon som skriver ut informasjon om personen
    void print() const;

private: // Følgende er tilgjengelig bare for klassen selv
    std::string person_name;
    std::string person_phone;
    int person_age;
};

// Definisjon av print()
// Legg merke til at den her heter "Person::print()".
// Dette er for å indikere at det er en medlemsfunksjon
void Person::print() const
{
    using namespace std;
    cout << "Navn: " << person_name << "\nNummer: " << person_phone;
    cout << "\nAlder: " << person_age << endl;
}


int main()
{
    Person p("Yoda", "5334627837", 800);
    p.print();

    p.set_age(p.age()+1); // I et virkelig tilfelle ville vi laget en "Person::increase_age()"-funksjon.
    p.print();

    p.set_name("Darth Vader");
    p.print();
return 0;
}

 

 

Om du vil ha flere personer, bør du bruke en av konteinerne du finner i standardbiblioteket, f.eks. std::list eller std::vector.

 

Et raskt eksempel med std::vector (selv om std::list ville vært like bra, eller bedre, i dette tilfellet):

 

#include <iostream>
#include <vector>

class Person {
    // Samme som ovenfor
};

int main()
{
    using namespace std;

    // Lag en vector med personer i
    vector<Person> person_list;

    // Legg til noen folk i listen
    person_list.push_back(Person("Yoda", "53340627837", 800));
    person_list.push_back(Person("Darth Vader", "384507484", 40));

    // Tante og onkel til Luke...
    person_list.push_back(Person("Owen Lars", "12345678", 52));
    person_list.push_back(Person("Beru Lars", "12345678", 48));

    // Skriv ut personene (du kan også bruke en av algoritmene i standardbiblioteket
    // for å gjøre dette, men det blir litt mye nytt på en gang, så jeg tar det letteste).
    vector<Person>::iterator pers; // Denne brukes til å bla gjennom personene

    // Blar gjennom alle personene i person_list.
    for (pers = person_list.begin(); pers != person_list.end(); pers++) {
         pers->print(); // Skriv ut personen vi er hos i øyeblikket
    }

    // La oss utvide familien litt...
    person_list.push_back(Person("Chewie", "", 25));
    person_list.back().print(); // Skriver ut siste personen i person_list (Chewie)

    // Fjerner den siste personen igjen
    person_list.pop_back();

    // Skriver ut de gjenværende personene på den "ukorrekte" måten
    // (Så vidt jeg vet virker ikke denne metoden med std::list)
    for (int i = 0; i < person_list.size(); i++) {
         person_list[i].print();
    }
return 0;
}

 

 

Tilsvarende med array:

 

#include <iostream>

class Person {
    // ...
};

int main()
{
    using namespace std;

    Person person_list[4];
    int list_size = 4;

    // Legg til noen folk i listen
    person_list[0] = Person("Yoda", "53340627837", 800);
    person_list[1] = Person("Darth Vader", "384507484", 40);

    // Tante og onkel til Luke...
    person_list[2] = Person("Owen Lars", "12345678", 52);
    person_list[3] = Person("Beru Lars", "12345678", 48);

    // Skriv ut personene (du kan fortsatt bruke algoritmen...)

    // Blar gjennom alle personene i person_list.
    for (int i = 0; i < list_size; i++) {
         person_list[i].print();
    }

    // La oss utvide familien litt...
    person_list[4] = Person("Chewie", "", 25); // Error! Arrayet er fullt!

return 0;
}

 

 

(Jeg har ikke kompilert noe av koden, og tar forbehold om skrivefeil o.l.)

Lenke til kommentar

Ja! Etter å ha lest nøye gjennom det med arrays har eg forstått litt kva arrays er i C++. Det er visst store forskjellar mellom arrays i PHP og arrays i C++. Faktisk minner vector meir om PHP-array enn array sjølv... Array er jo bare teit i C++...

 

Men tilbake til enum. Dersom du har den lista med vekedagar som du hadde. Korleis kan du då finne ut at du har satt vekedagen til mandag? Er det slik?

enum Day { monday, tuesday, wednesday, thursdag, friday, saturday, sunday };
Day d;
d = friday;

switch(d) {
   case(0):
       cout << "Det er mandag!!";
   break;
   case(1):
       cout << "Det er tirsdag!!!";
   break;
   case(2):
       cout << "Det er onsdag!!";
   break;
   ....
   ....
   case(4):
       cout << "Det er fredag!!";
   break;
   ....
   ....
   ....
}//end switch

I så fall ser eg ingen vits i det...

Lenke til kommentar

enum Day { monday, tuesday, wednesday, thursday, friday, saturday, sunday };

void check_day(Day d)
{
    using namespace std;
    switch (d) {
    case monday:
        cout << "Monday!\n"; 
        break;
    case tuesday:
        cout << "Tuesday!\n"; 
        break;
    case wednesday:
        cout << "Wednesday!\n"; 
        break;
    case thursday:
        cout << "Thursday!\n"; 
        break;
    case friday:
        cout << "Friday!\n";
         break;
    default:
         cout << "Not a weekday!\n";
         break;
    }
}

 

 

Man ser som oftest bort fra en enums tallverdi. Jeg påpeket verdien bare for å understreke at du ikke får monday om du skriver Day d = monday; cout << d;.

 

Edit: Man glemmer code-tagger.

Endret av Myubi
Lenke til kommentar
  • 4 uker senere...

Om man bare skal skrive ut navnet på dagen (og ikke foreta branches/hopp i programmet) kan man benytte nettopp tallverdien:

#include<iostream>

using namespace std;

int main(){
       enum Day { monday=0, tuesday, wednesday, thursdag, friday, saturday, sunday };
       const char *day_name[7]= {"mandag","tirsdag","onsdag","torsdag","fredag","lørdag","søndag"};
       cout << day_name[friday] << " " << day_name[sunday] << endl;
}

Lenke til kommentar

Eksempel på unødvendig tungvindt programmering, men alt for å unngå if og switch. :lol:

 

Eksempelet benytter seg av pekere til funksjoner i klassen.

 

Muligens vil denne kjøre raskere enn tilsvarende med bruk av if/switch o.l

 

#include<iostream>

using namespace std;

class Day{
public:
enum Days { monday=0, tuesday, wednesday, thursday, friday, saturday, sunday };

private:
void mon(){cout << "Monday" << endl;}
void tue(){cout << "Tuesday" << endl;}
void wed(){cout << "Wednesday" << endl;}
void thu(){cout << "Thursday" << endl;}
void fri(){cout << "Friday" << endl;}
void sat(){cout << "Saturday" << endl;}
void sun(){cout << "Sunday" << endl;}

private:
static void (Day::*actionp[7])(void);

public:
void action(Days day){
 (this->*Day::actionp[day])();
}
};

void (Day::*Day::actionp[7])(void) = {& Day::mon,& Day::tue,& Day::wed,& Day::thu,& Day::fri,& Day::sat,& Day::sun};

int main(){
Day d;
d.action(Day::monday);
d.action(Day::friday);
d.action(Day::thursday);
}

Lenke til kommentar
  • 2 måneder senere...

Switcher med caser der tallene ligger nært hverandre blir som regel optimalisert til "jump tables" uansett, som vanligvis er noe raskere enn funksjon-pekere fordi du unngår "dereference" og funksjonskall-overhead.

Lenke til kommentar
  • 4 uker senere...

Har tenkt å prøve meg litt på C++, og lastet ned "Dev-c++", leste litt i "hjelp-manualen", etter å ha lest en liten stund nå er jeg kommet til der hvor jeg skal lage det "hello world"-programmet, men jeg har et lite problem.

 

Jeg har skrevet alt riktig, lagret det som en .c fil, har kompilert det og skal "linke" det, hvordan i alle dager gjør jeg det?

Jeg har... glemt hva jeg skulle skrive akkurat her

Lenke til kommentar
Jeg har skrevet alt riktig, lagret det som en .c fil, har kompilert det og skal "linke" det, hvordan i alle dager gjør jeg det?

Jeg har... glemt hva jeg skulle skrive akkurat her

Linkingen er vel en del av kompileringsprosessen i Dev-C++? Og uansett trenger du nok ikke å linke hvis du bare kompilerer en kildekodefil.

Lenke til kommentar
Har tenkt å prøve meg litt på C++, og lastet ned "Dev-c++", leste litt i "hjelp-manualen" [...]

Les en bok. Accelerated C++ er anbefalt av mange som den beste boken for nybegynnere.

 

 

Jeg har skrevet alt riktig, lagret det som en .c fil [...]

Til C++ er det vanlig å bruke kildefiler med filendelse .cpp, .cxx eller .cc. Spar .c til C-utviklere.

 

 

Linkingen er vel en del av kompileringsprosessen i Dev-C++? Og uansett trenger du nok ikke å linke hvis du bare kompilerer en kildekodefil.

Det Gimper mener er at linkingen blir foretatt automatisk, med mindre du spesifiserer noe annet. Du trenger altså ikke å bekymre deg om dét.

Lenke til kommentar

Her er et program jeg jobber med..

#include <iostream>

int main()

{
 using namespace std;
 int hemmeligTall = 1 + (rand()%10);
 int gjettetTall = 111;

 while (hemmeligTall != gjettetTall)
 {
   cout << "Hvilket tall tenker jeg paa?";
   cin >> gjettetTall;
   cout << "\n";

   if (gjettetTall == hemmeligTall)
   {
     cout << "Riktig!!";
   }
   else if (gjettetTall > hemmeligTall)
   {
     cout << "For stort!!";
   }
   else 
   {
     cout << "For lavt!!";
   }

   cout << "\n\n\n";
 
 }

return 0;

}

Problemet mitt er at hemmeligTall blir 3 hver gang.

 

PS. Feil i undertittlen, det heter nybegynnerspørsmål, ikke nybegynner spørsmål.

Endret av nahoy
Lenke til kommentar
  • 4 uker senere...

Kult med sånne faste tråder som alltid ligger øverst. Man legger ikke uten videre merke til når det skjer noe i dem. Derfor meget sen reply.

 

Som hotstian indikerer må du sette seed'en til pseudorandom rutina som generer tallene. Men problemet er at setter du samme seed, så får du samme rekke med pseudo-tilfeldige tall. Den vanligste metoden er å sette seed'en basert på klokka, siden klokka har endret seg fra en gang til neste gang du kjører rutina. Dette er greit nok for de aller fleste formål, med unntak av sikkerhetsapplikasjoner.

 

Edit: For øvrig bør du ikke bruke rand() og srand(), men lrand48() og srand48(), da de førstnevnte har svakheter i algoritmen som brukes.

Endret av JBlack
Lenke til kommentar
  • 1 måned senere...

Hvorfor blir det

+23 mva %.1f Kr

skulle jo hatt mva summen der isteden for %.1f.

hva har jeg fjort feil?

 

 

 float netto;
       float brutto;
       float mva;
       float i=0.23;

       while (netto>=0)
       {
          printf("Nettopris           ");
          scanf("%f", &netto);
          mva = netto * i;
          printf("\n\n+ 23% MVA            %.1f Kr\n\n",mva);
          printf("----------------------------\n\n");
          brutto = mva + netto;
          printf("bruttopris           %.1f Kr\n",brutto);
          printf("============================\n\n\n\n\n");
       }

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...