Gå til innhold

Bone's Offisielle C++ hjelpetråd


Anbefalte innlegg

Videoannonse
Annonse

Har litt problemer med å få dette til å kjøre. Jeg fikk det til i stad, men uten at jeg var helt sikker på hva jeg gjorde (så jeg angret litt) og får det ikke til å kjøre. Jeg vet bare at det er veldig lite som skal endres på:

 

//main.cpp
#include <iostream>
using namespace std;
#include "oppg1b.hpp"

int main () {
   const int length=5;
   int phoneNumbers[length] = {1, 2, 3, 4, 5};
   printArray(length, phoneNumbers);
   return 0;
}

 

Får her "undefined reference to printArray" som er forståelig da oppg1b.cpp ikke vil kompilere.

 

//oppg1b.hpp
void printArray(int length, int myArray[]);

 

//oppg1b.cpp
#include <iostream>
using namespace std;
#include "oppg1b.hpp"

void printArray(int length, int myArray[]){
   for (int i=0; i<length; i++){
       cout << myArray[i] << endl;
   }
}

 

Her får jeg "undefined reference to main".

 

EDIT: Får det til å kjøre når jeg samlet filene i et prosjekt, men jeg fikk det til å kjøre som separate filer i stad (som lå i samme mappe).

 

 

I h-fila di, legg inn:

#if !defined(__oppg1b_h)
#define __oppg1b_h
<kode>
...
...

#endif

 

Bruk .h ikke .hpp

Og ja.. Selvfølgelig må du samle det i et prosjekt for å få det til å kjøre. Du kan ikke kompile ei fil uten main. Jmf den siste kodeboksen din.

 

 

 

 

Endret av _Ferrari_
Lenke til kommentar

Den kan kompileres ja, men den kan "ikke kjøres alene uten main."

 

Så skriv nettopp det.

 

For grunnleggende kurs, er det vel greit å forholde seg til at entrypointet skal hete main.

 

For grunnleggende kurs er det også greit å holde orden på terminologien og ikke foreta feilaktige forenklinger.

Lenke til kommentar
Gjest Slettet+987123897

Er det noen som har en link til en side med tekst eller videoer som forklarer c++ godt? Jeg har store problemer med å skjønne hva som blir gått gjennom i timene. Nå er de komt skikkelig langt, men jeg skjønner fremdeles ikke forskjellen på "call by value" og "call by reference".

 

Edit: Jeg skrev koden

 

 

 

	
int iInt = 10;
int &irRefToInt = iInt;

cout << iInt << endl;
cout << irRefToInt << endl << endl;

irRefToInt = 5;

cout << iInt << endl;
cout << irRefToInt << endl << endl;

iInt = 31;

cout << iInt << endl;
cout << irRefToInt << endl << "------------" << endl;


int lol = 11;
int denandre = lol;

cout << lol << endl;
cout << denandre << endl << endl;

denandre = 7;

cout << lol << endl;
cout << denandre << endl << endl;

lol = 34;

cout << lol << endl;
cout << denandre << endl << endl;

 

og fikk output:

10

10

 

5

5

 

31

31

------------

11

11

 

11

7

 

34

7

 

 

 

Slik jeg har skjønt det (jeg bommer nok på rett ordbruk noen plasser, men det får våge seg):

Dersom man deklarer en variabel til å være en annen variabel med CBV, vil den ta verdien (heltallet dersom det er int).

eks:

 

int kek = 42;

int truls = kek;

 

dersom man endrer kek eller truls senere vil ikke den andre variabelen bli påvirket av dette, men dersom det derimot ville stått

 

int kek = 42;

int &truls = kek;

 

Vil de peke på den samme "plassen" i minnet. Konsekvensen av dette er at de vil begge endres dersom man endrer en av den. Kan man da si at de i praksis er det samme?

 

Jeg fant også en video som forklarte det, men jeg setter likevel stor pris på flere tips (også videoer _uten_ bakgrunnsmusikk fra 80tallsporno.

 

http://www.youtube.com/watch?v=LwAPKuJpvmA&playnext=1&list=PLA68C1F33757B4A38

Endret av Slettet+987123897
Lenke til kommentar

jeg skjønner fremdeles ikke forskjellen på "call by value" og "call by reference".

 

Konseptet er egentlig veldig enkelt, men likevel har folk en tendens til å forklare det vanskeligere enn det er.

 

"by value" betyr at man lager en kopi av det man skal benytte, og endringene man gjør på dataene reflekteres ikke der de kopieres fra.

"by reference", på den andre siden, betyr at man 'gir' funksjonen en referanse, som egentlig bare sier "hei, dataene du trenger er her". Endrigene du gjør på datasettet vil derfor reflekteres også utenfor funksjonen.

 

I C, pointer..

void by_value(int x)
{
x = 0;
}

void by_reference(int* x)
{
*x = 0;
}

int main()
{
int 	x = 0xFF;

by_value(x);		// Endringen gjenspeiles ikke i x, fordi den ble utført på en kopi.
by_reference(&x);	// Endringen gjenspeiles i x.

}

 

I Cpp, reference.


void by_value(int x)
{
x = 0;
}

void by_reference(int &x)
{
x = 0;
}

int main()
{
int 	x = 0xFF;

by_value(x);		// Endringen gjenspeiles ikke i x, fordi den ble utført på en kopi.
by_reference(x);	// Endringen gjenspeiles i x.

}

 

'&' betyr skaff peker, mens '*' betyr følg peker, so to say.

 

 

EDIT: Jeg skriver egentlig ikke Cpp, men såvidt jeg forstår er en referanse (reference) det samme som en peker, bare at man behandler den som en normal variabel. Alså man endrer variablen den peker tid med x = val, istedenfor *x = val.

 

Mulig jeg ender opp å bli korrigert på det, men so be it.

 

EDIT2: Endret litt på eksemplet med pekere, og la til ett med referanser.

Endret av ze5400
Lenke til kommentar

Vil de peke på den samme "plassen" i minnet. Konsekvensen av dette er at de vil begge endres dersom man endrer en av den. Kan man da si at de i praksis er det samme?

 

Nei. En referanse er en peker til den originale variablen. Om du fjerner den originale variablen vil referansen bli invalid, men om du fjerner referansen vil ikke variablen bli invalid.

 

Om en variabel ligger på addresse 0xA og inneholder 4, så er variablen fire.

Om en peker ligger på 0xB og inneholder 0xA så kan du følge den med en dereferanse og hente og endre verdien i 0xA.

En peker 'peker' til det stedet i minnet som er interresant.

 

En referanse er en peker som er dereferert (*) hver gang den brukes.

 

Fra wikipedia:

There is a simple conversion between pointers and references: the address-of operator (&) will yield a pointer referring to the same object when applied to a reference, and a reference which is initialized from the dereference (*) of a pointer value will refer to the same object as that pointer, where this is possible without invoking undefined behavior. This equivalence is a reflection of the typical implementation, which effectively compiles references into pointers which are implicitly dereferenced at each use.

Endret av ze5400
Lenke til kommentar

Den viktigste grunnen til å bruke referanser over pekere i C++ er at en referanse kan aldri peke til NULL (såfremst man ikke gjør noen trikserier D:), og det er mye vanskeligere at segfaults oppstår ved bruk av dem. De kan oppstå hvis objektet det refereres til blir destruert, dog.

 

Med god bruk av referanser og smart pointers kan man skrive ganske mye kode uten å bruke pekere direkte en eneste gang, som gjør koden ganske mye tryggere.

 

Referanser har noen begrensninger, som at de ikke kan endres. Blir som en const pointer (ikke pointer to const!).

Lenke til kommentar
  • 1 måned senere...
Gjest Slettet+987123897

Jeg holder på ned linked list og lurer på hvordan jeg skal skrive ut listen på skjermen. Her er koden:

 

 

#include <iostream>
#include <string>

using namespace std;

struct ListNode {
string item;
int count;
ListNode *link;
};

typedef ListNode* ListNodePtr;


class IntNode{
private:
int data;
IntNode *link;

public:
IntNode () {}
IntNode(int theData, IntNode* theLink) : data(theData), link(theLink){}
IntNode* getLink () const {return link; }
int getData () const {return data; }
void setData (int theData) {data = theData;}
void setLink (IntNode* pointer) {link = pointer;}

};

typedef IntNode* IntNodePtr;

void headInsert (IntNodePtr& head, int theData);
void insert (IntNodePtr afterMe, int theData);


int main () {

ListNodePtr head;
head = new ListNode;
head->count = 12;
head->item = "a";
cout << (*head).count << endl << (*head).item << endl;
cout << head->count << endl << head->item << endl;
head = new ListNode;
(*head).count = 11;
(*head).item = "b";
cout << (*head).count << endl << (*head).item << endl;

IntNodePtr head;
head = NULL;
head = new IntNode;
head->setData(3);
head->setLink(NULL);

headInsert(head, 4);
headInsert(head, 5);
headInsert(head, 6);
headInsert(head, 7);
insert(head, 8);



   return 0;
}

void headInsert (IntNodePtr& head, int theData){

head = new IntNode(theData, head);

void insert (IntNodePtr afterMe, int theData){
afterMe->setLink(new IntNode(theData, afterMe->getLink()));
}

}

 

 

 

Må jeg lage en egen voidfunksjon for dette, eller? Og hvordan vil denne se ut?

Lenke til kommentar

Den koden der er bare rot...

Forøvrig: hvorfor bruker du ikke templates?

 

temlate<tyename T> class LinkedList
{
protected:
 struct Node
 {
   T data;
   Node* next;
 };
 int count;
 Node* head;


public:

 // Funksjoner for å legge til, fjerne etc. fra listen.


 // Iteratoren
 class iterator
 {
   const Node* current;
 public:
   iterator(const Node* node)
   {
     current = node;
   }
   iterator operator++ (int) const
   {
     return iterator(current->next);
   }
   T& value() const
   {
     return current->value;
   }
   bool end() const
   {
     return current != NULL;
   }
 }  

 iterator get_iterator() const
 {
   return iterator(head);
 }
};

Kjenner det er litt lenge siden jeg drev med C++ (bare C og C# i jobben min) så husker ikke helt hvordan iterators ble implementert... så jeg gjorde det etter beste hukommelse.

 

Da skal det bli noe slikt:

 

LinkedList<int> MyList;

// Add data

for(auto it = MyList.iterator(); !it.end(); ++it)
{
 cout << it.value() << endl;
}

Lenke til kommentar
Gjest Slettet+987123897

Takk, GeirGrusom. Koden er skrevet av noe fra boken vi har i c++, så jeg står ikke for den selv. Jeg skal ta en titt på det du skrev imorgen :)

Lenke til kommentar

Hei

 

Hold litt på med C++ for en stund siden, men har uheldigvis ikke fått jobbet så mye med det i det senere. Jeg startet for noen dager siden et prosjekt i C++, og kom over et problem. Jeg skal ha et Char array (C string?), men jeg vet ikke hvor lang denne stringen må være før programmet faktisk kjøres. Jeg har kommet frem til to muligheter:

1. Lage arrayet så stort at jeg med god margin, og undødvendig stort minne bruk at det går bra

2. Lage en funksjon som er noe som:

char function makeChar(int length){
    char charArray(lengt+1);//+1 for /0
    return charArray;
}

 

Jeg vil vell tro at sistnevnte kanskje er best, men jeg synes det høres litt tungt ut. Er det noe jeg har oversett?

 

Jeg kan bruke strings, men i og med at jeg programerer med WinSock er det enklest å bruke chars siden WinSock krever det.

Ser at jeg kanskje kan bruke strings allikevell, skal se mer på det nå. Er allikevell nyskgjerrig på dette :)

Endret av Rockie
Lenke til kommentar

Kikk på STL.

std::deque eller std::vector kan være av interesse.

 

Du burde ikke gjøre sånn du har skrevet uansett. Jeg ihvertfall er av den mening at en IKKE skal allokere minne i funksjoner generelt, med mindre du bruker et eller annet bibliotek som håndterer minnebehandling for deg. Funksjoner burde heller ikke mutere programmet på noen måte (med mindre funksjonen har nettopp til hensikt å gjøre det), men det er en litt annen diskusjon.

 

To problemer med å allokere minne i en funksjon:

- Under Windows: Du kan ikke free() et minneområde som er malloc()-et av en annen modul (.dll eller .exe) av en eller annen grunn. (erstatt med new og delete for C++) så dersom du skriver et bibliotek kan dette være en ganske alvorlig feil som gjør at programmet ditt ikke fungerer i det hele tatt.

- Minnelekasje! Et minneområde pekt til av en peker som faller ut av scope vil forbli utilgjengelig for programmet ditt så lenge programmet kjører!

Endret av GeirGrusom
Lenke til kommentar

Det stemmer vell det du sier. Fant også ut av at spørsmålet mitt egentlig ikke var noe relevant i det hele tatt, det var mer et resultat av hvordan jeg trodde dette skulle gjøres ut i fra hva jeg har gjort før i andre språk, lest osv.

 

Jeg skal uansett se mer på vectors og deque. Tror dette er en problemstilling jeg kommer til å møte igjen. Husker jeg leste om dette da jeg lærte meg C++, men har desverre glemt alt for mye. Må få tak i en bok om dette i gjen, tror det vil spare meg for mye tid.

 

Takk for svar i allefall :)

Endret av Rockie
Lenke til kommentar
  • 3 uker senere...

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å
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...