[C++] Programmeren Beginnersvraag(en)

Pagina: 1 2 Laatste
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • JMaster
  • Registratie: December 2009
  • Laatst online: 13-07 17:06
Probeer de cout eens boven de return te plaatsen.
De return doet precies wat het woord betekend, hij geeft iets terug en springt dus 'uit' deze functie (maar roept zichzelf een niveau dieper aan).

Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
JMaster schreef op donderdag 31 januari 2019 @ 07:55:
Probeer de cout eens boven de return te plaatsen.
De return doet precies wat het woord betekend, hij geeft iets terug en springt dus 'uit' deze functie (maar roept zichzelf een niveau dieper aan).
Bedankt voor het meekijken en de suggestie :)
Heb eerder de cout op regel 17 gekopieerd naar de lege regel 15 en dan wordt die wel uitgeprint. Maar dat is niet helemaal de bedoeling. Ik wil het aantal jumps weergeven nadat regel 22 is uitgevoerd want pas daarna, oftewel bij het bereiken van Return 1 , gaat die ook daadwerkelijk jumpen.
Heb nog geprobeerd de cout op de lege regel 23 te zetten maar dan verschijnt die maar 1x en niet 5 keer (het aantal jumps).

Het is waarschijnlijk zoals jij zegt, de jump-teller zit een nivo dieper en momenteel weet ik die teller niet te vinden en/of weer te geven.

[ Voor 5% gewijzigd door kitao op 31-01-2019 08:22 ]


Acties:
  • 0 Henk 'm!

  • JMaster
  • Registratie: December 2009
  • Laatst online: 13-07 17:06
Als je wilt weten hoe vaak de functie factorial aangeroepen word dan moet je boven de if een cout statement zetten. Zoek daarna eens uit hoe je dan een teller op die plek zou kunnen ophogen.

De return 1 (had ook a kunnen zijn), komt natuurlijk ook maar 1 keer voor. Dit is de conditie waarbij er uit de recursieve functie gesprongen word. Hiervoor dient de a > 1.

Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
JMaster schreef op donderdag 31 januari 2019 @ 08:45:
Als je wilt weten hoe vaak de functie factorial aangeroepen word dan moet je boven de if een cout statement zetten. Zoek daarna eens uit hoe je dan een teller op die plek zou kunnen ophogen.

De return 1 (had ook a kunnen zijn), komt natuurlijk ook maar 1 keer voor. Dit is de conditie waarbij er uit de recursieve functie gesprongen word. Hiervoor dient de a > 1.
Ja ok, dat begrijp ik wel, trouwens ook net geprobeerd en dat verschijnt netjes in beeld, dat is niet zozeer het probleem.

Ik heb een breakpoint gezet op regel 22, cout << "a in else" en vanaf daar ben ik gaan stappen.
Het programma bereikt dan return 1 en springt naar accolade 34. Vandaar wordt er 5x als een jojo heen en weer gesprongen tussen return op regel 16 en de accolade 34.
Die sprongen wou ik eigenlijk geteld weergeven.

Ik hoop dat de regel nummers in dit verhaal nog kloppen met de originele post, want die zit inmiddels op een pagina terug en heb inmiddels zitten wijzigen in het programma.

Afin, dat kijk ik zo wel na. Ps, klopt nog.

Nog iets, ik heb de functie zelf op de watch gezet.
Dat geeft dit :
factorial(a - 1) This expression has side effects and will not be evaluated.



Laat dat doorgekraste maar zitten, ik dwaal af.

[ Voor 3% gewijzigd door kitao op 31-01-2019 09:19 . Reden: Ps ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Hou je de call stack window wel in de gaten? Die vertelt je namelijk hoe diep je zit en met welke parameters elke functie is aangeroepen. En die kun je ook gebruiken om te kijken waar je was in een aanroepende functie door op een functie te dubbelklikken.

[ Voor 70% gewijzigd door .oisyn op 31-01-2019 09:16 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
.oisyn schreef op donderdag 31 januari 2019 @ 09:11:
Hou je de call stack window wel in de gaten?
nee, nog niet naar gekeken, goeie tip. :)
was ook nog van plan om in disassembly te kijken maar is tijd voor een pauze geloof ik.
Vierkante oogjes heb ik ervan gekregen. Kom er later mss op terug.

Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
.oisyn schreef op donderdag 31 januari 2019 @ 09:11:
Hou je de call stack window wel in de gaten? Die vertelt je namelijk hoe diep je zit en met welke parameters elke functie is aangeroepen. En die kun je ook gebruiken om te kijken waar je was in een aanroepende functie door op een functie te dubbelklikken.
Heb inmiddels de call-stacks erbij gezet en dat hielp goed, tnx. :)

Ik zie het programma, nu volgens het origineel hieronder, eerst 6x 'factorial opbouwen' in de call stack om ze vervolgens weer af te breken. (Breakpoint op main gezet)
Register EAX gaat bij opbouwen van 6 - 5 - 4 - 3 - 2 naar 1.
Register EAX gaat bij afbreken van 1 - 2 - 6 - 18 - 78 - 2DO

Dus bij wat ik jojo noemde gaat die pas rekenen zo te zien, en niet van 6x5x4x3x2x1 maar andersom van 1x2x3x4x5x6 en dat geeft respectievelijk 2-6-18-78 en tenslotte 2D0 als hex eindresultaat in de EAX.

Eerder zag ik dat patroon niet omdat ik er zoveel zelf-verzonnen regels bij gezet had die ook naar de EAX schrijven volgens mij en omdat ik de call stack er nog niet bij had.

Ik laat het hierbij, best veel van opgestoken hoewel een cout van de EAX nog niet gelukt is, schijnt ook niet zo eenvoudig te zijn. Misschien later nog eens naar kijken.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// factorial calculator
#include <iostream>
using namespace std;

long factorial (long a)
{
  if (a > 1)
   return (a * factorial (a-1));
  else
   return 1;
}

int main ()
{
  long number = 6;
  cout << number << "! = " << factorial (number);
  return 0;
}

klik voor groter
Afbeeldingslocatie: https://i.imgur.com/7zhnG2Y.jpg?1

Geraadpleegde video
YouTube: Illustrated Assembly Language Recursion

[ Voor 1% gewijzigd door kitao op 31-01-2019 21:30 . Reden: typo ]


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
Het voorgaande heeft m.i. aangetoond dat enige kennis van assembly geen kwaad kan. Vind het ook leuk om dat naast C++ erbij te doen en besteed daar ongeveer de helft van de tijd aan. Zodoende kwam ik een project tegen van iemand die daar al bijna 20 jaar mee bezig is en dat heet Visual Masm. En iemand anders heeft daar een serie video's over gemaakt met programmeer voorbeelden.
Voor geïnteresseerden in deze post, dat niet zozeer een vraag bevat, een paar verwijzingen.
Allereerst van de maker zelf, op zijn youtube kanaal klik op video's :
YouTube: Thomas Jaeger
Daar staan ze namelijk op volgorde wat op zijn afspeellijst niet het geval lijkt te zijn. Hier is zijn website :
http://www.visualmasm.com/

Een andere serie video voorbeelden staan hier :
YouTube: x86 Assembler using MASM32 Tutorial 5 - IF Statements
Daaronder via meer weergeven kan je een website vinden waar de behandelde codes netjes staan uitgeschreven : https://www.alanphipps.ne...s/IT_Assembler_Tutorial05

Video 5 ging dus over If-Else en ik had de statements daarvan met de hand uitgetikt en kwam waarschijnlijk via een typefout in een oneindige lus terecht waar slechts met een harde reset van de computer uit te komen was. Na her-opstarten zag ik nog steeds allerlei flitsen voorbij komen en daarom raad ik niet aan dit op een dure, nieuwe en/of enigste PC te downloaden, hoewel alles nu weer goed lijkt te werken.
Ook het saven en openen van projecten, nieuw of bestaand, vond ik niet erg soepel gaan, maar dat kan ook komen omdat ik niet al te goed thuis ben ik het handmatig maken van directory mappen, zoals met msdos of linux. Na een tijd oefenen gaat dit inmiddels wel beter maar zal daar zolang daar geen vraag naar is niet verder over uitweiden. De 100% gekopieerde If-code draaide overigens prima.

Al met al best knap van die meneer om zelf zo'n programma op te bouwen en jammer voor hem eigenlijk dat zijn video's zo weinig bekeken zijn. Mocht iemand dit toevallig eerder zijn tegengekomen en eventueel enkele tips hebben in die richting of van iets soortgelijks, dan hoor ik dat graag. :)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik heb de masm posts even verplaatst naar een apart topic: [MASM] Beginnersvraag(en)

[ Voor 108% gewijzigd door .oisyn op 15-02-2019 16:07 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
.oisyn schreef op vrijdag 15 februari 2019 @ 16:05:
Ik heb de masm posts even verplaatst naar een apart topic: [MASM] Beginnersvraag(en)
Nogmaals bedankt :)
Ben nog wel afwisselend bezig met C++ en was een tijd aan het zoeken om een string naar een functie door te geven. Zoals waarschijnlijk met alle talen, lezen/luisteren is makkelijker als schrijven/spreken.
Kwam daarover een aantal dingen tegen op internet maar niet de m.i. makkelijkste en meest voor de hand liggende. Is waarschijnlijk zo vanzelfsprekend dat niemand er vragen over stelt. Aan de andere kant merk je goed als je dit zelf probeert hoeveel combinaties er mogelijk zijn, een zijdelings voorbeeld daarvan is hier te vinden :
Pointers and const (ergens halverwege op die pagina, m.n. de verschillende schrijfwijzen ervan)
http://www.cplusplus.com/doc/tutorial/pointers/
Dat is trouwens waar ik tot nu toe gebleven ben met die tutorial.

Afin, ik heb nu drie 'string passings technieken' verzameld in een mapje aangezien ik die dingen vrij snel vergeet en is misschien een leuke puzzel op de zondag voor diegeen die het wil aanvullen met een vierde of vijfde versie.
Daarbij opgemerkt dat ik soms tegenkwam dat het ook met vectors kan (moet dat nog verder uitzoeken) maar ben volgens mij in bovenstaande tutorial nog geen enkel vector voorbeeld tegengekomen :?

Deze drie versies heb ik tot nu toe getest.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// passing string T to function
// string T = "Test";

************* Met ombouw herverbouwing **********

#include <iostream>
#include <string>
using namespace std;

void functie(const char *P)
{
        cout << P;
}

int main()
{
    const char *T = "Test";
    functie(T);
    return 0;
}

***************** Valse omweg ********************************

void functie(const char *P)
{
        cout << P;
}

int main()
{
    string T = "Test";
    functie("Test"); // Valse omweg, met T gebeurt niks
    return 0;
}

******************** Makkelijkste *******************************

void functie(string P)
{
        cout << P;
}

int main()
{
    string T = "Test";
    functie(T);
    return 0;
}

***************** Nog meer ? *******************************

functie()
[...]
main()
[...]



Een wat serieuzere vraag als slot toevoeging aan deze post.
Was vandaag dus bezig met dit hoofdstuk
http://www.cplusplus.com/doc/tutorial/pointers/
en helemaal onderaan staan de subonderwerpen void pointer en pointer to function.

Bij de eerste heb ik volgens mij inmiddels door dat ...
void increase (void* data, int psize)
pchar=(char*)data;

.. de void pointer data via pchar omgezet wordt in een char pointer data.

Bij de tweede, pointers to functions, vraag ik me af of (beroepsmatige) programmeurs echt regelmatig die vorm toepassen of laat de tutorial hier enkel zien wat principieel mogelijk is ?
Vind het wel heel erg abstract worden zo maar kan aan mij liggen.

int operation (int x, int y, int (*functocall)(int,int))
int (*minus)(int,int) = subtraction;


en abstract is niet negatief bedoeld, knap juist als iemand dit zonder naslag weet op te schrijven.
.

[ Voor 15% gewijzigd door kitao op 17-02-2019 18:05 . Reden: vraag toegevoegd ]


Acties:
  • 0 Henk 'm!

  • Mijzelf
  • Registratie: September 2004
  • Niet online
Ja hoor, ik gebruik regelmatig functiepointers. Er zijn standaard C libraryfuncties die dat nodig hebben (zoals qsort, bijvoorbeeld). Maar ook daarbuiten wel, als je ergens een variabele functie wil gebruiken of zo.

Acties:
  • 0 Henk 'm!

  • Radiant
  • Registratie: Juli 2003
  • Niet online

Radiant

Certified MS Bob Administrator

Ja hoor, met regelmaat. Voor functies met callbacks of lookup tables bijvoorbeeld. Dat houdt je code modulair (de aanroepende code hoeft niets te weten van de functie die wordt aangeroepen, de aanroepende code definieert slechts de signature) en overzichtelijk (geen enorme switches nodig bijvoorbeeld).

Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
Mijzelf schreef op zondag 17 februari 2019 @ 20:42:
Ja hoor, ik gebruik regelmatig functiepointers. Er zijn standaard C libraryfuncties die dat nodig hebben (zoals qsort, bijvoorbeeld). Maar ook daarbuiten wel, als je ergens een variabele functie wil gebruiken of zo.
Ok, bedankt :)
Is soms lastig vooraf te bepalen voor een leek of iets meer of weinig of geen nadere aandacht nodig heeft.
Kwam laatst iets tegen over het nesten van namespaces maar dat leek mij dus wel echt een theoretisch spelletje.
Niet dat ik zelf van plan was beroeps te worden maar vond het pointers naar functies nogal complex. Maar nu jij aantoont dat het geen uitzondering is, en te verwachten valt dat dit vaker in programma's te zien zal zijn, is het de moeite waard er nog eens nauwkeuriger naar te kijken.
En ik snap wel dat zulke vragen na verloop van tijd zichzelf verduidelijken maar dat vroeg ik mij op dit moment dus af.

Ps/
Idem voor Radiant

[ Voor 4% gewijzigd door kitao op 17-02-2019 21:03 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het is wel meer een legacy ding. In moderne C++ zul je zelden een pointer-to-function tegenkomen. Dan zijn het abstracties als std::function<> wat de klok slaat.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
.oisyn schreef op zondag 17 februari 2019 @ 21:01:
Het is wel meer een legacy ding. In moderne C++ zul je zelden een pointer-to-function tegenkomen. Dan zijn het abstracties als std::function<> wat de klok slaat.
ik geloof dat ik enigzins begrijp wat je bedoelt.
Bij het andere genoemde onderdeel void pointers ging ik zoeken op (char*).
kreeg o.a. dit te zien

Does unnessesary and dangerous c-style cast.
(char*)something is a c-style cast. In C++ you should use static_cast<char*>(something)
http://www.cplusplus.com/forum/beginner/95553/

Acties:
  • +1 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Het concept "callback functie" wordt overal en then some toegepast. (niet alleen in C++)

Een functiepointer is de essentie van een (runtime variabele) callback dus het is (in tegenstelling tot assembly :P) wat mij betreft een must have skill om er mee om te kunnen gaan.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
farlane schreef op zondag 17 februari 2019 @ 21:23:
Het concept "callback functie" wordt overal en then some toegepast. (niet alleen in C++)

Een functiepointer is de essentie van een (runtime variabele) callback dus het is (in tegenstelling tot assembly :P) wat mij betreft een must have skill om er mee om te kunnen gaan.
Bedankt voor de waarschuwing om dit niet zomaar over te slaan.
Ongetwijfeld zal ik die dan ook bij andere websites tegenkomen hoewel ik mij beperkt heb tot slechts een paar daarvan anders wordt het chaotisch.
Is namelijk zo dat als ik door de cplusplus voorbeelden heen stap via de compiler (VS17 gebruik ik), niet automatisch alle aspecten van de variabelen meteen in beeld komen. Zoals bij de void pointer wou ik het adres van char a in beeld krijgen maar daar bleek een cout << static_cast<void *>(&a); voor nodig te zijn.
Uiteindelijk duurt dan zo'n 'inspectie' al gauw een uur, vooral als je het eerst zelf probeert.
Maar ik heb de tijd en geen haast, dat scheelt.
.

[ Voor 15% gewijzigd door kitao op 17-02-2019 23:55 ]


Acties:
  • 0 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 11-09 21:00
kitao schreef op zondag 17 februari 2019 @ 21:08:
[...]


ik geloof dat ik enigzins begrijp wat je bedoelt.
Bij het andere genoemde onderdeel void pointers ging ik zoeken op (char*).
kreeg o.a. dit te zien

Does unnessesary and dangerous c-style cast.
(char*)something is a c-style cast. In C++ you should use static_cast<char*>(something)
http://www.cplusplus.com/forum/beginner/95553/
C-style casts zijn "gevaarlijk" omdat je er gemakkelijk, en vaak per ongeluk, verkeerde casts mee kunt doen zonder dat je dat merkt (tenzij je de compiler stricter instelt). Daarom altijd explicit static_cast, dynamic_cast, reinterpret_cast en static_cast gebruiken.

Stel je heb de volgende code:
C++:
1
2
char const * a = "hello, world!";
char * b = (char *) a;
Hier heb je de const weggecast, en kun je a via b bewerken. Als je dit op de C++ manier zou doen, via bijv. static_cast dan krijg je een foutmelding; omdat een const weg hebt gecast, daarvoor moet je explicit const_cast gebruiken (wat je in 99% van de gevallen juist niet wilt).

[ Voor 3% gewijzigd door ThomasG op 18-02-2019 10:45 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

ThomasG schreef op maandag 18 februari 2019 @ 10:41:
[...]
C-style casts zijn "gevaarlijk" omdat je er gemakkelijk, en vaak per ongeluk, verkeerde casts mee kunt doen zonder dat je dat merkt (tenzij je de compiler stricter instelt)
Welke compiler heeft daar opties voor, dan?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 11-09 21:00
.oisyn schreef op maandag 18 februari 2019 @ 11:27:
[...]

Welke compiler heeft daar opties voor, dan?
In ieder geval gcc en clang. Eerlijk is eerlijk, niet specifiek dat je bijvoorbeeld implicit een const cast doet. Maar wel dat je c-style casts gebruikt, en dus potentieel gevaarlijk. Als je de compiler strict instelt (wat aan te raden is), kun je zulke casts niet compilen.

Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
#ThomasG , bedankt voor je uitleg, ik zal wel eerst het begrip cast beter moeten opzoeken maar las dat jij en oisyn over het instellen van de compiler hebben. Gisteren had ik daar ook een opmerking over :
Is namelijk zo dat als ik door de cplusplus voorbeelden heen stap via de compiler (VS17 gebruik ik), niet automatisch alle aspecten van de variabelen meteen in beeld komen. Zoals bij de void pointer wou ik het adres van char a in beeld krijgen maar daar bleek een cout << static_cast<void *>(&a); voor nodig te zijn.
Nu vandaag kom ik opnieuw iets vergelijkbaars tegen. Is nogal lastig in woorden te brengen dus heb er een plaatje van gemaakt. Gaat nog steeds over hetzelfde onderwerp pointer to function, helemaal onderaan
http://www.cplusplus.com/doc/tutorial/pointers/
dat ik gewijzigd heb tot de kern en een drietal cout regels heb toegevoegd voor de adressen van minus, function_call en subtraction.
Wat mij verbaast is dat cout << &subtraction een ander adres geeft van dezelfde &subtraction die ik had vastgepind in de compiler ?? ??
Het programma is gepauzeerd bij het laatste { van main dus dat blijft zo en verandert niet.

zie de rode pijltjes
https://i.imgur.com/sqmhK12.jpg

vr1. Hoe kan dat ?

vr2. Wat ik me ook afvroeg is waarom in de tutorial (helemaal onderin) gesproken wordt over ...

In the example above, minus is a pointer to a function that has two parameters of type int.

... want is dan bij int operation (int x, int y, int (*function_call)(int,int)) niet ook *function_call een pointer to a function ??

In ieder geval, ik kan het nu beter lezen als gisteren en daar is het mij om te doen, dat ik programma's tenminste kan 'verstaan' zonder persé ze direkt zelf te kunnen schrijven. De interesse voor het programmeren kwam eigenlijk vanuit het bezig zijn met micro-controllers en is dan handig om te weten op welke plaatsen je de code kunt aanpassen dat natuurlijk enkel lukt als je die code een beetje begrijpt anders wordt het lukraak prijsschieten. En de meeste programma's zijn al geschreven dus ik hoef wmb niet meteen alles opnieuw uit te vinden, als ik dat al zou kunnen.

Terug naar de pointer, ik kwam deze nog tegen onder zoekwoorden c++ int (int , int , int(*)(int, int)) :
http://www.cplusplus.com/forum/beginner/67474/
Heeft slechts zijdelings verband met mijn vraag maar gaat wel over precies hetzelfde programma.
Dat zoals gezegd door mij enigzins is aangepast, (dit voor diegeen die mijn eerste vraag wil nabootsen)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// pointer to functions = P_tot_F
#include <iostream>
using namespace std;
int subtraction(int a, int b)
{
    cout << "Adres subtraction   =  " << &subtraction << endl;
    return (a - b);
}
int operation(int x, int y, int(*function_call)(int, int))
{
    cout << "Adres function_call =  " << &function_call << endl;
    int g;
    g = (*function_call)(x, y);
    return (g);
}
int main()
{
    int n;
    int(*minus)(int, int) = subtraction;
    cout << "Adres minus         =  " << &minus << endl;
    n = operation(20, 14, minus);
    cout << n;
    return 0;
}

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

function_call is een pointer met als waarde het adres van subtraction. Maar function_call zelf is ook gewoon een variabele, met een adres. Met &function_call krijg je dus het adres van function_call, niet datgene waar function_call naar wijst.

[ Voor 31% gewijzigd door .oisyn op 18-02-2019 18:00 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
.oisyn schreef op maandag 18 februari 2019 @ 17:05:

1. function_call is een pointer met als waarde het adres van subtraction. Maar function_call zelf is ook gewoon een variabele, met een adres.

2. Met &function_call krijg je dus het adres van function_call, niet datgene waar function_call naar wijst.
Tnx .oisyn, jouw puntje 1 maakt al veel meer duidelijk over mijn vraag 2.

Puntje 2. wist ik al maar dat kon jij niet weten natuurlijk. Ik 'zeg' dit omdat mijn vraag 1. anders in mekaar zit als het verschil tussen pointer adres en adres waar de pointer naar wijst. Dat ging erom waarom ik in de console window voor &subraction een andere waarde krijg als voor &subtraction die vastgepind zit in de compiler , en heb daarom een paar extra cout's toegevoegd.

Want begreep eerst niet waarom het adres waar de pointer *minus naar wijst (en dus ook *function_call), niet overeenkwam met het vastgepinde adres in de compiler van &subtraction, zie plaatje.

https://i.imgur.com/sqmhK12.jpg

Misschien een bug ?
Makkelijk om het zo af te doen natuurlijk, maar zie wel vaker dingen die blijven hangen en pas na een herstart weer enigzins normaal worden, zoals errors warnings van een vorig project. Of dat die bijv. 'string' ineens niet herkent en deze niet blauw wordt. Of dat bij het kopieeren van een 'woord' er rare dingen gebeuren die verdwijnen als je het 'woord' zelf opnieuw uittikt.
VS17 community was gratis dus zal het niet teveel afkraken maar lijkt soms nogal gammel.
Of de bestuurder weet er niet mee om te gaan en dat is waarschijnlijker, maar hoe dan ook, snap niet zo goed dat de window een ander resultaat geeft als de compiler bij &subtraction.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ik snap niet zo goed wat je bedoelt met "vastgepind in de compiler"? Bedoel je de pinning in de editor?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
.oisyn schreef op maandag 18 februari 2019 @ 19:48:
Ik snap niet zo goed wat je bedoelt met "vastgepind in de compiler"? Bedoel je de pinning in de editor?
Kan je het plaatje zien ?
Anders zet ik hem hier
En ja sorry, je hebt gelijk, moet nog thuis worden in de terminologie, het is de editor.

Afbeeldingslocatie: https://i.imgur.com/DEC6qRG.jpg

- adres &subtraction vastgepind geeft 26D0
- adres &subtraction in console geeft 13DE
- pointer *minus en 'pointer' *function_call wijzen naar 13DE

En met vastgepind in de compiler bedoel ik de weergaven die 'naast' het programma staan.

Bij de regel nummers is ook een punaise te zien , die geen betrekking hebben op de regel zelf, maar waar de pin naartoe is gesleept.

Trouwens tof dat je even meekijkt :)
Kan zijn dat het in een andere compiler geen verschil geeft zoals bij mij ?
Onderaan staat de console window.

Herstarten, hoewel niet helemaal 'vers' maar van het opgeslagen project, gaf geen verschil.
&subtraction in watch zetten evenmin.
Zal morgen nog eens dit programma vers erin zetten en kijken of dat verschil maakt.
.
Vers opgeladen, VS17 vers opgestart, code vers gekopieerd uit mijn vorige post zodat er niks blijft hangen en maakt helaas geen enkel verschil, zover ik kan waarnemen.

Afbeeldingslocatie: https://i.imgur.com/0FQiFMx.jpg
.
&subtraction gepind = ....26D0
&subtraction cout = ....13DE
pointer *minus wijst naar ....13DE
.

[ Voor 23% gewijzigd door kitao op 18-02-2019 21:14 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Waarom je IDE &subtraction anders weergeeft in de tooltip me niet duidelijk, maar er zit wel een vaste offset in vergeleken met je vorige screenshot.

[edit]
Ik zeg, plausibel.

[ Voor 9% gewijzigd door farlane op 18-02-2019 21:26 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ok, ten eerste, "de compiler" is het programma dat jouw broncode omzet in machinecode (of een intermediate representatie) en heeft dus weinig relatie met wat je nu aan het doen bent :). Die pins zijn onderdeel van de debugger.

Wat betreft de verschillen, het heeft denk ik te maken met het feit dat je compilet in debug (met ondersteuning voor edit&continue). De functies wijzen dan niet echt naar de functies maar naar een thunk (waar een JMP instructie staat naar het daadwerkelijke functieadres). Tijdens het runnen kan de debugger dan makkelijk de functie vervangen door een nieuwe versie als je tijdens het debuggen de code wijzigt. Ik denk dat hij echter bij het ophalen van het adres van een functie voorbij de thunk kijkt.

Sowieso heeft je programma het altijd bij het rechte eind, niet je debugger ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
farlane schreef op maandag 18 februari 2019 @ 21:23:
Waarom je IDE &subtraction anders weergeeft in de tooltip me niet duidelijk, maar er zit wel een vaste offset in vergeleken met je vorige screenshot.

[edit]
Ik zeg, plausibel.
Dat was mij vaag ook al opgevallen die offset, ik neem aan dat je dit bedoelt :

- plaatje 1 : &subtraction gepind = 010526D0
- plaatje 1 : &subtraction cout ... = 010513DE

na verversing ..

- plaatje 2 : &subtraction gepind = 00A426D0
- plaatje 2 : &subtraction cout ... = 00A413DE
.oisyn schreef op maandag 18 februari 2019 @ 21:23:
Ok, ten eerste, "de compiler" is het programma dat jouw broncode omzet in machinecode (of een intermediate representatie) en heeft dus weinig relatie met wat je nu aan het doen bent :). Die pins zijn onderdeel van de debugger.

Wat betreft de verschillen, het heeft denk ik te maken met het feit dat je compilet in debug (met ondersteuning voor edit&continue). De functies wijzen dan niet echt naar de functies maar naar een thunk (waar een JMP instructie staat naar het daadwerkelijke functieadres). Tijdens het runnen kan de debugger dan makkelijk de functie vervangen door een nieuwe versie als je tijdens het debuggen de code wijzigt. Ik denk dat hij echter bij het ophalen van het adres van een functie voorbij de thunk kijkt.

Sowieso heeft je programma het altijd bij het rechte eind, niet je debugger ;)
Het klopt inderdaad dat in 'run mode' , en trouwens ook in 'debug mode', sowieso de uitkomst hetzelfde blijft, namelijk 20 - 14 = 6.
Dus ondanks mijn geklaag over gammele VS17 lag het toch aan de bestuurder die niet goed uit elkaar weet te houden hoe de verschillende bewerkingen van zo'n programma invloed hebben.
Komt waarschijnlijk omdat ik nooit eerder van thunk had gehoord, dus zal dat eens naslaan.
Bedankt, allebei :)

Ps\
Ik was niet de enige die ging duizelen van de notatie int (int , int , int(*)(int, int)). :/
Hier noemen ze het zelfs ugly en leveren een aantal alternatieven ervoor.
[Function Pointers]
https://www.learncpp.com/cpp-tutorial/78-function-pointers/
Ps2\
Vwb [thunk], paar artikelen daarover bekeken en denk dat deze het duidelijkst is hoewel ik zelf niet helemaal er doorheen gespit ben, is niet echt voor beginners.
https://www.codeproject.c.../27908/Thunk-and-its-uses
.

[ Voor 11% gewijzigd door kitao op 19-02-2019 13:00 . Reden: Ps\ ]


Acties:
  • +1 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

farlane schreef op maandag 18 februari 2019 @ 21:23:
Waarom je IDE &subtraction anders weergeeft in de tooltip me niet duidelijk, maar er zit wel een vaste offset in vergeleken met je vorige screenshot.
Base address randomization :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
Over random gesproken, ben de flow kwijt ... :F

Origineel :
https://www.tutorialspoin.../cpp_copy_constructor.htm
Zelfde maar dan gecomprimeerd en voorzien van blok nummers in de comments
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
using namespace std;
class Line {                    // BLOK 1
public:
    int getLength(void);
    Line(int len);              // simple constructor
    Line(const Line &obj);      // copy constructor
    ~Line();                    // destructor
private:
    int *ptr;
};
Line::Line(int len) {           // BLOK 2    Member functions definitions including constructor
    cout << "Normal constructor allocating ptr" << endl;
    ptr = new int;              // allocate memory for the pointer;
    *ptr = len;
}
Line::Line(const Line &obj) {   // BLOK 3 
    cout << "Copy constructor allocating ptr." << endl;
    ptr = new int;
    *ptr = *obj.ptr; // copy the value
}
Line::~Line(void) {             // BLOK 4
    cout << "Freeing memory!" << endl;
    delete ptr;
}
int Line::getLength(void) {     // BLOK 5
    return *ptr;
}
void display(Line obj) {        // BLOK 6
    cout << "Length of line : " << obj.getLength() << endl;
}
int main() {                    // BLOK 0
    Line line(10);
    display(line);
    return 0;
}

Main bevat enkel regel R33,34,35 en slot haakje } op R36

Main() = Blok 0

Wat bepaalt de programma flow ?
Met een breakpoint op main() en vervolgens step into zie ik dit :

R33 >>jmp...>> Blok2 ..........zoals te verwachten
Blok2 >>return>> R33 .............zoals te verwachten
R33 ...>>naar...>> R34 .............zoals te verwachten
R34....>>jmp...>> Blok3 ..........?? volgens welke logica, waarom niet naar Blok6 ??

En kan hier al stoppen voor het geoefende oog, hoewel het nog verder gaat maar hoop dat mijn vraag duidelijk is, wat bepaalt hier nu eigenlijk de programmaflow ? Zijn het de pointers en hoe dan, is het de 'inwendige' structuur van Classes oftewel een mij onbekend protocol zeg maar, of de volgorde waarin de blokken achter elkaar staan ?

Gister kwam ik er niet uit bij hoe de debugger zn pointer-adressen bijhoudt en dat is bij dit voorbeeld wmb al bijna helemaal een onbegonnen zaak, maar daarbovenop lijkt het nog erger te worden.
Kan nu al niet meer herkennen hoe het programma zn jumps en returns maakt ?
Tot nu toe was dat altijd wel duidelijk.

Nogmaals kort(er) samengevat , wat laat regel 34 nu eigenlijk springen naar blok 6? EDIT = BLOK3

32. int main() { // BLOK 0
R33. Line line(10); // jumps naar blok 2
R34. display(line);
R35. return 0;
R36. }

12. Line::Line(int len) { // BLOK 2 Member functions definitions including constructor
13. cout << "Normal constructor allocating ptr" << endl;
14. ptr = new int; // allocate memory for the pointer;
15. *ptr = len;
16. }

// Blok 2 returns naar R33
// R33 gaat naar R34
// R34 JMP naar BLOK3 ?? ?? ??

17 Line::Line(const Line &obj) { // BLOK 3

********************

Hieronder dan de rest van de programmaflow in debug mode, maar is waarschijnlijk onnodig om de vraag verder te verduidelijken.

B=BLOK

B3>>returns>>R34
R34>>JMP>>B6 ............zoals te verwachten
B6>>JMP>>B5...............zoals te verwachten
B5>>returns>>B6.............zoals te verwachten
B6>>JMP>>B4 ............. ?? volgens welke logica ??
B4>>returns>>B6 ........... ok
B6>>returns>>R34
R34>>naar>>R35
R35>>JMP>>BLOK4 .... ?? volgens welke logica ??
B4>>returns>>R35
R35>>naar>>R36...........eindeprogramma


Ik vermoed dat deze vraag misschien weer net zo'n tamelijk harde noot wordt als gisteren en alvast mijn excuses daarvoor. Ben net met classes begonnen en zou beter nog iets verder daarin duiken in de hoop dat dit vanzelf duidelijker wordt. Probleem is echter dat ik zo gauw geen andere manier zie om dit enigzins onder de knie te krijgen zonder 'erdoorheen te stappen' met de debugger. Is dus in feite een kip-ei verhaal.
.

[ Voor 0% gewijzigd door kitao op 19-02-2019 20:15 . Reden: EDIT BLOK6 MOEST BLOK 3 ZIJN ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Je geeft het object by value door aan display(...) dus maakt de compiler een copy voor je gebruik makend van de copy-constructor.

Wil je dat niet, moet je een pointer gebruiken of by (const) reference doorgeven.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Even een simpel antwoord op mijn mobiel, maar de copy constructie wordt aangeroepen omdat display een eigen kopie verwacht.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
Heb een nogal slordige fout met een edit-wijziging gecorrigeerd in mijn vorige post maar knap dat jullie het desondanks toch weten uit te leggen. Was er al bang voor dat ik in mijn post al die nummers door elkaar zou halen.
Maar ok, het principe is duidelijk en de antwoorden ook enigzins, voor nu, en zal er nog eens naar kijken.
Om nog meer geklungel en verwarring van mijn kant te voorkomen zal ik er later met frissere blik naar kijken en erop terugkomen.
Kan wel alvast zeggen dat in blok 6, zoals jullie aanstippen, er een obj genoemd wordt , waardoor het inderdaad begrijperlijker wordt dat R34 ipv naar blok6 toch naar blok 3 springt.

Is ook niet zo dat ik te ver in het diepe ben gedoken, hoewel niemand dat heeft beweerd.
De tutorial begon namelijk vrij makkelijk te begrijpen
https://www.tutorialspoin...s/cpp_classes_objects.htm
Pas onderaan via de subsecties Classes and Objects in Detail werd het een graadje te moeilijk.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Het is niet veel anders dan wanneer je een int parameter hebt; van die int wordt ook een kopie gemaakt op de stack als de functie wordt aangeroepen.

Nu dus ook voor je Line parameter, waarbij in C++ (als je die zelf geimplementeerd hebt) de copy constructor wordt gebruikt om een kopie van je object te maken. Als je er niet een specifiek implementeert genereert de compiler er een voor je die in feite niet meer doet dan een member wise copy. Omdat dat soms niet werkt mag je deze copy constructor ook zelf implementeren.

Ook bij initialisatie in de vorm van Line a = b; of Line a(b); wordt diezelfde constructor aangeroepen. ( Het eerste geval is misschien wat verassend)

Zie ook https://en.cppreference.com/w/cpp/language/copy_constructor

[ Voor 8% gewijzigd door farlane op 19-02-2019 23:01 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
farlane schreef op dinsdag 19 februari 2019 @ 22:59:
Het is niet veel anders dan wanneer je een int parameter hebt; van die int wordt ook een kopie gemaakt op de stack als de functie wordt aangeroepen.

Nu dus ook voor je Line parameter, waarbij in C++ (als je die zelf geimplementeerd hebt) de copy constructor wordt gebruikt om een kopie van je object te maken. Als je er niet een specifiek implementeert genereert de compiler er een voor je die in feite niet meer doet dan een member wise copy. Omdat dat soms niet werkt mag je deze copy constructor ook zelf implementeren.

Ook bij initialisatie in de vorm van Line a = b; of Line a(b); wordt diezelfde constructor aangeroepen. ( Het eerste geval is misschien wat verassend)

Zie ook https://en.cppreference.com/w/cpp/language/copy_constructor
Ja bedankt, dacht eerst dat ik het mezelf te moeilijk maakte maar na het zien van jouw link is het dus gewoon moeilijk. Heb besloten om terug te keren tot de basis van classes om eerst te wennen aan de syntax want ben nog niet toe aan de details van classes blijkbaar. Niet dat ik het niet geprobeerd heb, zat eerst zelf met pen en papier de flow te volgen, heb op dissambly gekeken maar dat ken ik nog minder als c++ en daar zijn het aantal stappen x10 en een ander nadeel is, je kunt bij debuggen niet terugstappen zover ik weet en bij herstarten heeft alles weer een ander nummertjes adres.

Wat mij wel opviel nadat jij en .oisyn het over object hadden gisteren, heb ik het adres daarvan kunnen achterhalen via een cout << &obj.
Vanuit main de eerste regel 33 Line line(10); gaat die naar blok 2, zoals verwacht en er komt dan al (vantevoren) een this. Die this staat voor this pointer geloof ik, ben althans die term eerder tegengekomen maar nog niet op ingezoomd. In ieder geval , die this pointer pakt dan al het adres op van &obj.
Hier een drietal afbeeldingen op volgorde van de pagina's van een documentje waarin ik de stappen heb gekopieerd, plus de locals en de regelnummers :

https://i.imgur.com/QIcFKrY.jpg
https://i.imgur.com/2bhRAeU.jpg
https://i.imgur.com/5NdkvTA.jpg

Nou kan ik me zo voorstellen dat een overzichtje van de stappen flow dat ik nou zelf heb geprobeerd te maken, misschien geautomatiseerd kan zijn in een debugger, al dan niet in bijv. een pro versie ?
Dus dat je een soort listing file kan uitdraaien, maar dan van de flow, een flow file zeg maar.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
kitao schreef op woensdag 20 februari 2019 @ 13:32:
[...]
Ja bedankt, dacht eerst dat ik het mezelf te moeilijk maakte maar na het zien van jouw link is het dus gewoon moeilijk.
C++ is niet de makkelijkste taal, maar op dit niveau is het nog niet echt moeilijk nog volgens mij. Koop eens een boek om de basis uit te leren en houd je breakpoints en debugger in de buurt.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
farlane schreef op woensdag 20 februari 2019 @ 19:15:
C++ is niet de makkelijkste taal, maar op dit niveau is het nog niet echt moeilijk volgens mij.
Koop eens een boek om de basis uit te leren en houd je breakpoints en debugger in de buurt.
Ieders nivo en talent verschilt per persoon natuurlijk, de ene heeft meer aanleg voor taal, de ander voor rekenen en weer een ander voor voetbal en alles wat daartussen zit. Ben er paar uur mee bezig geweest, incl. breakpoints en debugger, zoals je zag heb ik iedere losse stap gekopieerd en alle localen erbij geplakt maar feit blijft dat ik het nog steeds niet zie en pretenderen alsof dat wel zo is heeft ook geen nut.

Er zijn een aantal blokken

Line::Line(int len) { .................................... // BLOK 2
Line::Line(const Line &obj) {...................... // BLOK 3
Line::~Line(void) {...................................... // BLOK 4
int Line::getLength(void) { ..........................// BLOK 5
void display(Line obj) {............................... // BLOK 6

en in main deze twee regeltjes

33 Line line(10);
34 display(line);

Regel 33 roept Blok 2 aan, dat zie ik dan nog wel in maar dat regel 34 Blok 3 roept had ik niet verwacht. Dit omdat Blok 6 qua syntax namelijk veel meer op regel 34 lijkt. Ok, er staat in Blok 6 een obj en in Blok3 staat een &obj maar in regel 34 zie ik geen obj maar een line met kleine letter.

Wat het leren van de basis betreft, begin vorige maand een keuze gemaakt hoe ik dat leren zou aanpakken en heb toen ervoor gekozen om deze drie aan te houden
http://www.cplusplus.com/doc/tutorial/
https://github.com/TPayneExperience/Lets_Learn_Cpp
https://www.tutorialspoint.com/cplusplus/index.htm

en volg die die vanaf de hoofdstukken 1 tot waar ik nu ben en dus zouden er in principe geen gaten gevallen moeten zijn waardoor ik iets gemist heb om bovenstaand te kunnen begrijpen. Slechts 1 van die drie heb ik nu Classes zien behandelen dus hopelijk wordt via die andere twee tzt meer duidelijk. En ondertussen kan ik in jouw boek dat onderwerp nalezen, waarvoor bedankt. :)

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 11-09 21:00
Dat regel 34 blok 3 aan roept is eenvoudig te verklaren. Jouw functie display is namelijk: void display(Line obj). Je geeft een Line object mee, maar als je goed kijkt zie je dat het geen pointer en ook geen reference is*. Dit betekend dat er dus een kopie gemaakt wordt.

Wil je geen kopie, dan kun je een pointer of een reference van maken. Echter, pointers wil je gaan zoveel mogelijk vermeiden omdat je dan te maken krijg met allemaal kopzorgen (wie is de eigenaar, wie ruimt het geheugen op, e.d.). Een reference is dan de beste keuze. Je zult zien dat de copy-constructor dan niet meer wordt aangeroepen, en de destructor slechts eenmalig (want maar een object).

[small]* (en ook geen move, maar dat laten we even achterwegen voor nu)[]

Acties:
  • +1 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

Waar het volgens mij vooral mis gaat is dat je nu heel erg de diepte in aan het gaan bent zonder de hogere abstractieniveaus te begrijpen. Het lijkt me handig om eerst onder de knie te krijgen hoe dat precies gaat met objecten en hun constructors en destructors.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
ThomasG schreef op donderdag 21 februari 2019 @ 10:50:
Dat regel 34 blok 3 aan roept is eenvoudig te verklaren. Jouw functie display is namelijk: void display(Line obj). Je geeft een Line object mee, maar als je goed kijkt zie je dat het geen pointer en ook geen reference is*. Dit betekend dat er dus een kopie gemaakt wordt.

Wil je geen kopie, dan kun je een pointer of een reference van maken. Echter, pointers wil je gaan zoveel mogelijk vermeiden omdat je dan te maken krijg met allemaal kopzorgen (wie is de eigenaar, wie ruimt het geheugen op, e.d.). Een reference is dan de beste keuze. Je zult zien dat de copy-constructor dan niet meer wordt aangeroepen, en de destructor slechts eenmalig (want maar een object).

(en ook geen move, maar dat laten we even achterwegen voor nu)
Dat regel 34 blok 3 aan roept is eenvoudig te verklaren. Jouw functie display is namelijk: void display(Line obj). Je geeft een Line object mee

Zoals ik dit lees, wat natuurlijk niet hetzelfde hoeft te zijn als jij bedoelt, kom ik tot de volgende interpretatie :

34 display(line); >>>> via het woord display wordt de functie in Blok6 aangeroepen
29 void display(Line obj) { // BLOK 6 >>> en via Line obj wordt Blok3 aangeroepen
17 Line::Line(const Line &obj) { // BLOK 3

Ik zou hier graag genoegen mee nemen en omdat ook eergisteren .oisyn en farlan het over de obj hadden zie ik wel enig verband, maar ik zie de debugger zo niet stappen.
Dit komt bij mij in beeld : (edit : waarbij regel 14 per ongeluk dubbel is gefotografeerd)

Afbeeldingslocatie: https://i.imgur.com/PzbG9Cl.jpg
Afbeeldingslocatie: https://i.imgur.com/FGBMFOX.jpg
Afbeeldingslocatie: https://i.imgur.com/pyMmzo3.jpg

Hele code staat hier
kitao in "[C++] Programmeren Beginnersvraag(en)"

Ik zie dus als locale een this verschijnen, vanuit het niets, die toevallig, al voordat 34 display(line); wordt bereikt, hetzelfde adres aanneemt opneemt als obj.
Dit ging mij pas achteraf opvallen anders had ik mij eerst verdiept in wat de this voorstelt voordat ik deze vraag ging stellen. Ik vermoed namelijk dat die invloed heeft op de stapvolgorde, maar kan me vergissen.

Ik geef .oisyn mede daarom groot gelijk dat dit voor mij nog een dieptelaag te ver is , iets wat ik zelf al aangaf, maar de bereidheid om te helpen is groot, waarvoor hartelijk dank en wou dat niet zomaar zonder antwoord laten.
.

[ Voor 8% gewijzigd door kitao op 21-02-2019 16:38 . Reden: typo's + edit ]


Acties:
  • +1 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
kitao schreef op donderdag 21 februari 2019 @ 10:20:
[...]
Ieders nivo en talent verschilt per persoon natuurlijk, de ene heeft meer aanleg voor taal, de ander voor rekenen en weer een ander voor voetbal en alles wat daartussen zit. Ben er paar uur mee bezig geweest, incl. breakpoints en debugger, zoals je zag heb ik iedere losse stap gekopieerd en alle localen erbij geplakt maar feit blijft dat ik het nog steeds niet zie en pretenderen alsof dat wel zo is heeft ook geen nut.

Er zijn een aantal blokken ....
Mijn laatste tip: Ga met behulp van een/het boek C++ stapje voor stapje eigen maken, en stop met het analyseren van CPU registers en assembly instructies. Sla geen delen over die je nog niet begrijpt; de meeste dingen die je vraagt zijn met wat basiskennis C++ prima uit te leggen.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
Ok, bedankt voor het advies farlane.
Zal dat boek bij mijn schema opnemen, dat wordt dan object 4 kwa C++.
Zal niet snel gaan maar kan geen kwaad als herhaling om opnieuw bij een hfdstk 1 te beginnen.

Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
Correctie vorige post, dat boek blijkt geen herhaling te zijn en heeft een vrij andere insteek als de overige tutorials, bedankt voor de tip. Heb gisteren hfdst2 afgerond.
Vind ergens wel dat in een beginnerstopic vragen vrij zou moeten staan, ook al blijkt hieruit dat de vraagsteller zn lesje niet goed heeft begrepen, tenzij overduidelijk blijkt dat de vraagsteller te lui is om zelf te zoeken.
Uiteindelijk valt vrijwel alles te vinden maar dan gaat het vaak gedeeltelijk via andere forums/websites en dat lijkt me ook niet de bedoeling.
In ieder geval, nogmaals, bedankt voor de boektip, komt goed van pas :)

Deze vraag gaat trouwens niet over dat boek maar komt via deze :
http://www.cplusplus.com/doc/tutorial/structures/

Er staan een drietal voorbeeld-programma's in maar dit gaat enkel over de eerste twee.
Ik vroeg me namelijk af waarom sstream erbij werd gehaald.
In het 1e voorbeeld heb ik een wijziging aangebracht, namelijk dit :
code:
1
2
3
4
5
6
    cout << "Enter title: ";
    getline(cin, yours.title);
    cout << "Enter year: ";
    cin >> yours.year; // deze regel is door mij erbij gezet
    //getline(cin, mystr); // deze regel is door mij tot comment gemaakt
    //stringstream(mystr) >> yours.year; // deze regel is door mij tot comment gemaakt

Die wijziging had geen enkele invloed op het eindresultaat.
Het 2e voorbeeld bevat echter een loop, om veel woorden te vermijden een plaatje van mijn zelfde soort wijziging die nu wel (erg) veel invloed heeft op het eindresultaat :

Afbeeldingslocatie: https://i.imgur.com/URISdIH.jpg


Te zien valt dat bij de 1e iteratie alles nog goed gaat, maar bij de tweede en laatste iteratie wordt regel 22 met getline(cin, yours.title); mysterieus en glashard overgeslagen. Mysterieus voor mij althans.

Iemand enig idee waardoor dat komt ?

Acties:
  • +1 Henk 'm!

  • hazzytje
  • Registratie: September 2014
  • Laatst online: 27-04 11:18
kitao schreef op maandag 4 maart 2019 @ 17:48:

Iemand enig idee waardoor dat komt ?
Als ik het goed lees staat onder het kopje notes op deze pagina het probleem dat je hebt.
https://en.cppreference.c...ring/basic_string/getline
Het komt er op neer dat de cin >> films[n].year de newline nog in stdin laat zitten, en daardoor de getline alleen die ene newline ziet en dus denkt dat je zonder iets te typen op enter hebt gedrukt.

Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
hazzytje schreef op maandag 4 maart 2019 @ 18:32:

Als ik het goed lees staat onder het kopje notes op deze pagina het probleem dat je hebt.
https://en.cppreference.c...ring/basic_string/getline
Het komt er op neer dat de cin >> films[n].year de newline nog in stdin laat zitten, en daardoor de getline alleen die ene newline ziet en dus denkt dat je zonder iets te typen op enter hebt gedrukt.
Je hebt het goed gelezen, knap hoor, ik raak zelf meestal nog de weg kwijt in dit soort 'datasheets'.
Maar nu je het zegt, ik ben zoiets dergelijks wel eens eerder tegengekomen met een 'haperende' cin.
Heb regel 25 toegevoegd uit jouw verwijzing naar notes en dit is het eindresultaat :

Afbeeldingslocatie: https://i.imgur.com/1PFMbfV.jpg


Helemaal prima dus :)

Niet dat ik het nu echt 100% begrijp maar er zit vooruitgang in.
Ook is het mij nog niet helemaal duidelijk waarom in http://www.cplusplus.com/doc/tutorial/structures/ sstream erbij wordt gehaald maar dat is voor een andere keer.

Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
In het ene geval lees je een int direct uit de input stream (cin) en het laatste lees je eerst een string (getline) en zet je die string om naar een int mbv een s(tring)stream.

De eerste versie laat een '\n' in je input stream staan, de tweede niet zoals je gemerkt hebt.

[ Voor 5% gewijzigd door farlane op 04-03-2019 23:07 ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
farlane schreef op maandag 4 maart 2019 @ 23:06:
In het ene geval lees je een int direct uit de input stream (cin) en het laatste lees je eerst een string (getline) en zet je die string om naar een int mbv een s(tring)stream.

De eerste versie laat een '\n' in je input stream staan, de tweede niet zoals je gemerkt hebt.
Bedankt voor de toelichting farlane,
Heb het nog eens opgezocht en sstream bleek te staan in het hoofdstukje basic input and output.
http://www.cplusplus.com/doc/tutorial/basic_io/

Had er zelfs een aantekening van maar mijn geheugen is niet meer wat het geweest is, en bovendien ben ik het daarna (vrijwel) niet meer tegengekomen.
Er staat bijvoorbeeld dit :
The standard header <sstream> defines a type called stringstream that is most useful to convert strings to numerical values and vice versa.

Ik kan best begrijpen dat dit nuttig is in bepaalde gevallen maar zag er niet het voordeel van in bij genoemd voorbeeldprogramma // example about structures op pagina http://www.cplusplus.com/doc/tutorial/structures/

In dat programma kunnen 4 regels worden verwijderd en door slechts één regel toe te voegen blijft het eindresultaat toch hetzelfde.
Dus deze 4 regels kunnen weg :

4. // #include <sstream>
16. // string mystr;
24. //getline(cin, mystr);
25. //stringstream(mystr) >> yours.year;

En dan slechts één regeltje erbij :

26. cin >> yours.year;

Vroeg me daarom af waarom cplusplus zo omslachtig doet, maar waarschijnlijk alvast één reden valt in dezelfde basic pagina terug te vinden : you should always use getline to get input in your console programs instead of extracting from cin.

In het tweede programma op de structures webpagina, met het voorbeeld // array of structures , wou ik dezelfde vereenvoudiging toepassen maar liep zoals beschreven tegen een cin-probleem aan en helaas herkende ik het niet als zodanig en dacht (gemakshalve) dat dit in verband stond met de stringstream verwijdering.

[Cin-ignore]
daar kom ik later in een edit op terug om het voor mezelf nog eens op een rijtje te zetten en voor eventuele andere geïnteresseerden en is natuurlijk niet als uitleg aan jou bedoeld.
Pas na het antwoord van hazzytje besefte ik dat ik een geskipte cin al eerder had meegemaakt en daar zelfs drie uur mee bezig was en is dan best teleurstellend dat er in mijn gaten geheugen geen lampje ging branden.

kitao in "[C++] Programmeren Beginnersvraag(en)"

Als zijspoor detail , daar staat vermeld dat bij gebruik van
cin.ignore(numeric_limits<streamsize>::max(), '\n');

er een #include <limits> vermeld moet staan boven main.
Had dat niet zelf verzonnen maar blijkt dus niet te kloppen (?).

Een andere (zeer) uitgebreide uitleg heb ik hier na lopen testen, het gedeelte over ene Wlodarczyk :
https://stackoverflow.com...gnore-after-reading-input

Ik begrijp nu beter de oorzaak, de spatie veroorzaakt (zonder een aanwezige getline) in feite twee stringen.
Ik concludeer hieruit dat een 'enter' , zoals in mijn voorbeeld, hetzelfde effect heeft als zo'n spatie (?).

Om deze lange post af te sluiten nog één plaatje waar ik de complexe zin cin.ignore(numeric_limits<streamsize>::max(), '\n');
heb vervangen door het eenvoudigere cin.ignore();

#include <sstream> en string mystr; heb ik verwijderd uit het voorbeeld // array of structures plus de twee regels 27 en 28 die zichtbaar zijn in de afbeelding.

Afbeeldingslocatie: https://i.imgur.com/EKlUI4l.jpg

[ Voor 26% gewijzigd door kitao op 05-03-2019 15:10 ]


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
farlane schreef op woensdag 20 februari 2019 @ 19:15:
C++ is niet de makkelijkste taal, maar op dit niveau is het nog niet echt moeilijk nog volgens mij. Koop eens een boek om de basis uit te leren en houd je breakpoints en debugger in de buurt.
Ja nogmaals bedankt, ben inmiddels halverwege hfdst 3.
Zag in dat boek steeds verwijzingen naar zijn website maar is niet te doorzoeken.
Uiteindelijk deze gevonden
https://archive.org/details/TICPP2ndEdVolOne
Hele zip-files vol met alle voorbeelden en oefeningen in het boek.

Voor de duidelijkheid, dit is legaal, meneer schrijft zelf dat het boek free evailable is.
Worden wel hele stukken overgeslagen, dit noemt hij een 'simple example'
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//: C03:reinterpret_cast.cpp
#include <iostream>
using namespace std;
const int sz = 100;
struct X { int a[sz]; };
void print(X* x) {
for(int i = 0; i < sz; i++)
cout << x->a[i] << ' ';
cout << endl << "--------------------" << endl;
}
int main() {
X x;
print(&x);
int* xp = reinterpret_cast<int*>(&x);
for(int* i = xp; i < xp + sz; i++)
*i = 0;
// Can't use xp as an X* at this point
// unless you cast it back:
print(reinterpret_cast<X*>(xp));
// In this example, you can also just use
// the original identifier:
print(&x);
} ///:~

Kan zijn dat ik wat vergeten ben want ben niet constant met eenzelfde boek bezig, maar kan me niet herinneren dat bijvoorbeeld structs al vóór hoofdstuk 3 zijn doorgenomen. Hoop dat het gaandeweg wat minder snel gaat.
.

[ Voor 41% gewijzigd door kitao op 16-04-2019 06:24 ]


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Het boek gaat er van uit dat de lezer enige C kennis heeft, dat is voor de absolute beginner een nadeel. Als je met enige programmeerconcepten bekend bent lijkt het me geen probleem.

Die bende die je post kan met een beetje formatting heel wat leesbaarder worden:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//: C03:reinterpret_cast.cpp
#include <iostream>

using namespace std;

const int sz = 100;

struct X
{
    int a[sz];
};

void print(X* x)
{
    for (int i = 0; i < sz; i++)
        cout << x->a[i] << ' ';

    cout << endl << "--------------------" << endl;
}

int main()
{
    X x;
    print(&x);

    int* xp = reinterpret_cast<int*>(&x);

    for (int* i = xp; i < xp + sz; i++)
        *i = 0;

    // Can't use xp as an X* at this point
    // unless you cast it back:
    print(reinterpret_cast<X*>(xp));

    // In this example, you can also just use
    // the original identifier:
    print(&x);
} ///:~

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
@farlane
In VS17 was het prima leesbaar maar bedankt voor de tip, zal er volgende keer een code=c++ van maken. :)

En je hebt gelijk, het boek veronderstelt enige basiskennis en daarom heb ik het tot nu toe nog niet afgedaan, bovendien ging hij het subhoofdstukje erna toch in op structs. Misschien te vroeg gejammerd.
Maar had enig nut, andere geïnteresseerden hoeven nu niet meer de codes uit een pdf te kopiëren.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 11-09 19:58

.oisyn

Moderator Devschuur®

Demotivational Speaker

kitao schreef op woensdag 17 april 2019 @ 15:47:
@farlane
In VS17 was het prima leesbaar maar bedankt voor de tip, zal er volgende keer een code=c++ van maken. :)
Het gaat vooral om de indenting en wat witregels hier en daar, daar gaat code=c++ je niet bij helpen ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • kitao
  • Registratie: Juli 2012
  • Laatst online: 05-09 16:01
Mijn neus bloedde :+
Pagina: 1 2 Laatste