2D en 3D problemen

Status
Niet open voor verdere reacties.
Ik krijg dit (gecompileerd met g++):

Code:
Is uw figuur 2D of 3D? [2/3] 2
Geef de lengte: a
Geef de breedte: 1 van de maten is kleiner dan 1 en is bijgevolg niet geldig

Nu zijn mijn vragen:

Code:
1) Waarom laat ie me niet eerst de breedte ingeven en dan pas die controle? Hij stopt midden in de functie eigenlijk om de volgende al te beginnen. Kan je even uitleggen?

vraag ik me ook af , :P sorry


Code:
2) Als je met OOP werkt, moet je dan wat anders omgaan met pointers?

niet bepaald. een pointer naar een class kan ook ,net zogoed als een pointer naar een
int char float of welk type dan ook.

Code:
3) Kan je de operators new en delete even uitleggen? Ik zag die in classes, maar wat doen ze?

new en delete alloceren en dealloceren dynamisch geheugen.

als je bijvoorbeeld in een programma een array hebt, waar een naam in moet komen van een "gebruiker" je weet zelf niet hoegroot de array zal moetten zijn, doe je array[10]
heb je de kans dat er teweinig plaats is en dan crashed je programma, doe je array[40]
dan heb je de kans dat een groot deel van die gereserveerde plaatsen niet gebruikt gaan worden, dan verbruik je geheugen zonder dat je er iets mee doet. met new en delete voorkom je dat, new en delete reserveren geheugen tijdens runtime in de heap ( vrije ram)
en als ze er klaar mee zijn (ergens in het programma als je zijn naam niet meer nodig hebt) dan kan je die terug geven als vrij geheugen.

eigenlijk is een string een char array die dynamisch gealloceerd is met als laatste het '\0' teken, dat duid op het einde van de string.

bv, string x;

cin >> x;
( je kan zoveel letters typen als je wil, tot je geheugen op is natuurlijk. een char is 1 byte een string is een character array, een computer met 512 mb dus kan jij, 512 000 000 letters typen ( natuurlijk lopen er op je computer nog programmas die elk ook geheugen verbruiken, dus het zal nooit zoveel zijn )

doe je nu , string x = "hallo" , dan heb je de grote van je string al bepaalt die is 6 bytes groot ( vergeet de '\0' niet )
;)
doe je nu , cin >> x; en je geeft meer als 5 letters in dan overschrijf je data buiten de array! wat dus in ernstige systeemfouten kan uitlopen, stel dat de geheugenplaats achter jou string nou net gebruikt word door één of ander systeemprocces, en jij overschrijft die dan gaat dat systeemprocces crashen, en je computer misschien ook



een voorbeeldje van hoe dat je new kunt gebruiken.

stel dit voor als een programma op de server van je school, die leerlingengegevens bijhoud, je school heeft dit programma pas gekocht en wilt nu zijn 1400 leerlingen ingeven in het systeem, als je nu een array gebruikt , hoegroot moet die dan zijn? evengroot als het aantal leerlingen, weet jij al hoeveel leerlingen er op de school zijn?
neen, ideaal dus voor dit dynamisch op te lossen met new



Code:
#include <iostream>
using std::cout;
using std::endl;
using std::cin;
using std::getline;

class student
{
    static int leerlingennummer;
    const int leerling;
public:
    student() : leerling(leerlingennummer)
    {
      ++leerlingennummer;
    }

    int id() const;
};

int student::leerlingennummer = 1;

int student::id() const
{
    return leerling;
}





int main ()
{
  int i = 0;

  cout <<"hoeveel leerlingen zijn er?" << endl;
  cin  >> i;

  student *pointer  = new student [i]; // wij willen i aantal studenten! (dit is een array van "i" studenten groot) 
                                                     // zou je hier een gewone array voor gebruiken geeft je compiler een fout.

  for (int x  = 0; x < i; x++)
  {
    cout << (pointer[x]).id()<<"\t";  // geef het nummer van elk student
    if  ( (pointer[x]).id()%10 == 0)  // lege lijn na 10 studenten 

    {
      cout << "\n";
    }
  }
  //als je deze leerlingen of één van de leerlingen niet meer nodig hebt:
  
  delete [] pointer; // geeft alle ruimte gebruikt terug aan als vrij geheugen
  // dus alle "i" leerlingen worden gewist
  // nu zie je al dat dit voor een memory leak kan zorgen, stel dat iemand bijv
  // 700000000000000000000000000000000000 voor "i" ingeeft, en je pc
  // heeft daar niet genoeg plaats voor, boem, crash 
  

  cin.get();
  return 0;
}

Code:
4) Heb ik nu pointers onder de knie of moet ik nog veel leren voor ik die pointers goed zal kunnen?

dat weet ik niet, dat zou jij moetten weten :P

Code:
5) Ik kan string.h niet gebruiken omdat g++ alles haalt uit:
/usr/include/c++/4.1.2/backward/
Maar string (zonder .h) en andere staan in deze dir:
/usr/include/c++/4.1.2/
Maar in /usr/include/c++/4.1.2/backward/ staan er dan als: "algobase.h" en "algo.h" die in /usr/include/c++/4.1.2/ niet staan.

geen idee.. ik gebruik g++ niet

Hoe los ik dit allemaal op?

Code:
6) De .h bestanden die je zelf schrijft, waarvoor dienen die? Waarom kan dat niet in die .cpp? Bijna elk .cpp bestand heeft een gelijknamig .h bestand, waarvoor is dat goed?


deze bestanden (.h) zorgen voor orde en overzicht . je kan bijvoorbeeld je class en zijn functie prototypen in een .h bestand typen en de "body" de code tussen de { } in een .cpp
file schrijven, dan zet je in je .cpp file #include "file.h" en in je main.cpp zet je dan
#include "file.h"

Ook zorg je er zo voor dat je dit bestand (class) terug kunt gebruiken in andere programmas! door deze te includen

dit zorgt ook voor veiligheid, als je bijvoorbeeld samen met iemand anders een programma schrijft , en hij wil niet zijn functie code laten zien, alleen hetgeen wat zijn functies nodig hebben (parameters) dan kan hij jou bijvoorbeeld het .h bestand sturen, waar alle prototypes van functies instaan, en zonder dat jij weet hoe de functie omgaat met de data kan jij er toch verder aan programmeren.
 
Laatst bewerkt:
over h's en cpp's

als je kleine progjes maakt past alles in 1 cpp....
maak je hele projecten wordt het een ******* lange cpp.....
zodoende maak je headers... de .h files
en deze kan je includen met #include "header.h"
waar je maar wilt, in cpp's of in h's.

bv je werkt veel met vectoren, dus je schrijft s een vector class die dat goed kan. Nu werk je waarschijnlijk in meerdere projecten en plaatsen in een project met vectoren, bv in je main.cpp

nu kun je je definities kopieren en plakken in je main en t werkt. maar als je ook een andere cpp hebt waarin je ook met vectoren werkt, kun je ze daar ook heen kopieren en plakken.
niet efficient.

zodoende maak je voor je vector.cpp een vector.h waarin je je class uitwerkt. de functies definieer je in de cpp.
zodoende kun je overal waar je vector nodig hebt simpelweg #include "vector.h" intypen en je definities gelden daar ook.
dit is een portability / modulair id als je snapt wak bedoel.
cpp's kan je niet includen, alleen h's.

een simpel vb. maak een h met slecht #define PI 3.14
nu kun je die overal includen en heb je altijd je PI waarde zonder dat je die overal expliciet hoeft te noemen.

******************************************************************************************
over pointers new/delete
dit is dynamische allocatie

normaal gesproken heb je bv
int x;
of
int x[10] als je 10 ints wilt.
maar 10 staat niet altijd vast. soms moet je in de code bepalen hoe lang je array moet worden. bv als je de gebruiker iets laat invullen. als je bv vraagt naar adressen oid dergelijks weet je niet hoeveel adressen erin gaan komen. dus kun je 2 dingen doen.
je kunt een restrictie toepassen door te zeggen ik buffer ruimte voor maximaal X adressen
en ergens in je code staat
adres Adressen[X]

dit is erg lelijk en niet efficient....
bv als je veel adressen wilt aankunnen moet X groot zijn, dus buffer je altijd veel ruimte ook al wordt er maar 1 adres ingevoerd...
en je kunt nooit meer dan X adressen aan, wat niet gebruikersvriendelijk is.

zodoende kun je dynamisch alloceren. heel simpel je vraagt de gebruiker om hoeveel adressen er komen, bv X.

nu kun je NIET zeggen
adres Adressen[X] waar X geen CONSTANTE is...dan krijg je compile fouten. dus je kunt zo niet vragen naar een willekeurig VARIABELE X.

je moet nu zeggen
adres* Adressen = new adres[X]; waar X wel variabel mag zijn. (technische redenen)

wat je nu doet is een pointer declareren
adres* Adressen;
de pointer is van het type geheugenadres van 'adres' type (beetje ambigu, maar dat had ik nog niet bedacht toen ik met adres begon, maar goed)

met new maak je in een pointeradres een daadwerkelijk object van dat type aan.
bv
int* getal = new int;
is feitelijk gelijk aan
int getal;
alleen dat je nu dynamisch alloceert en niet meer met de objecten zelf werkt maar met hun geheugen adressen
enkele objecten is niet interessant (vaak) maar wel de arrays
int* getallen = new int [X] mag nu ook waar je X int's aanmaakt die beginnen in het adres van getallen...

hopelijk is het zo duidelijk dat het verschil in variabel en constant ligt. normale array definities kan je niet met een variabele declareren. dynamisch alloceren kan dat wel.

aangezien je nu in runtime geheugen aan het vrijmaken bent, moet je boel ook weer opruimen (dit wordt anders voor je gedaan, maar nu weet het programma natuurlijk ook niet meer waar je geheugen aanmaakt en hoeveel etc.)
een extra verantwoording :) waar memory leaks om de hoek komen kijken..
maak je veel new aan dan kost dat je ook veel geheugen. ruim je dat niet op, krijg je geheugen problemen

hou als regel dat tegenover elke new een delete moet voorkomen. alles wat je dynamisch alloceert, zul je ook moeten opruimen.

int * getal = new int; -> delete getal;
int * getallen = new int[X]; -> delete[] getallen

en that's it..

wat betreft NULL.
initialiseer pointer altijd op NULL ( = 0x0000000 ) oftewel een leeg adres. doe je dit niet, dan wijzen ze naar ongedefinieerde adressen, en krijg je ongedefinieerd vreemde fouten in je programmma.
tegen NULL kan je checken, wat je ook zeker moet doen
een NULL pointer kan je niet deleten
dus

if ( pointer ) delete pointer;
en
int x;
int* getal = NULL;
if(!getal) getal = &x;
etc.

pas als je dit allemaal goed doorhebt, constant vs variabel, adressen en objecten, NULL, new vs delete, heb je pointers door.
MAAR t neemt heel wat crashes en heel wat tijd voordat je er lekker mee werkt. Als het idee doordringt kun je int begin enkel verklaren waarom dingen mis gaan wanneer t gaat.
t houdt niet op bij pointer naar simpele ints.......een pointer naar een class kan je gebruiken om de functies in de class aan te roepen, maar een bad pointer laat de boel crashen....pointers gebruik je in lijsten, en elk ander opslag voormaat van serieuze grote en structuur. Het neemt een hele zooi exception handling wat een vak apart is.....
Daarnaast werken de [] operators wellicht afleidend aangezien het niet meteen prijs geeft dat het om pointers gaat....
al met al zijn pointers de grootste bron van bugs en crashes....
maarja, ze laten ook veel toe wat je zeker nodig gaat hebben
 
technisch is het mogelijk cpp's te includen
technisch kan je alles includen, ook webpagina's....
MAAR NIET DOEN
het is niet zoals void main int main. das iets heel anders, namelijk de structuur restrictie van je project.

noem het conventie, als je iets include, dan noem je dat een h (header), anders een cpp
als je een cpp include, is het eigenlijk gewoon een header geworden....en omdat aan te duiden noem het geen cpp meer maar een h.
maar ja ok.... je kunt er van maken wat je wilt....als je ervoor kiest cpp's te includen en uitwerkingen in h's te zetten, kun je dat doen....als je maar 1 extensie wilt gebruiken, waarom niet...
wordt het overzichtelijker ervan?.... geloof t niet

hou ook in gedachten dat je in h's
#ifndef _SOMETHING_
#define _SOMETHING_
... je body
#endif
moet gebruiken om ervoor te zorgen dat je h's meerdere keren kan includen. doe je dit niet krijg je errors over dubbele definities...
 
er staat ergens "bool check:" , die ":" moet je vervangen door ";"
zonder quotes
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan