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.
Bedankt, dat is een goeie tip, het blijft staan en ik kan tijdens het 'steppen' mee blijven kijken.Mijzelf schreef op zaterdag 12 januari 2019 @ 11:25:
[...]
Het makkelijkst is een dual monitor setup.
Had ik eigenlijk zelf al moeten opkomen om te proberen want is niet voor het eerst dat ik twee programma's naast elkaar zet.

Nadeel is enigzins dat alles stuk kleiner wordt, ik zocht eigenlijk een manier om de output window vast te pinnen terwijl het visual studio scherm maximaal blijft.
Kwam dan o.a. hier uit
https://visualstudio.user...o-stay-open-on-off-settin
Toegepast en cons.window blijft na einde dan wel open maar met 'steppen' helaas niet en een makkelijke oplossing hiervoor heb ik niet gevonden.
Zoals op deze manier blijft het namelijk niet staan :

Bij klik op step into verdwijnt de window naar taskbar.
Desondanks prima verbetering met duo-monitor, tnx.
Op zich had deze vraag niet veel met programmeren te maken maar wou je toch even laten weten wat het resultaat is geworden.
Kan wel een programmeer vraagje verzinnen maar het is niet zo dat ik er door 'vast loop'.
Ik zie voorbeelden waar geen using namespace std; wordt gebruikt en dan in plaats van bijvoorbeeld gewoon cout is het nodig om std::cout te gaan schrijven.
Dus vroeg me af waarom niet iedereen using namespace std gebruikt.
Ik bedoelde eigenlijk letterlijk 2 monitors.kitao schreef op zaterdag 12 januari 2019 @ 15:38:
Nadeel is enigzins dat alles stuk kleiner wordt, ik zocht eigenlijk een manier om de output window vast te pinnen terwijl het visual studio scherm maximaal blijft.
Namespaces hebben een functie, namelijk om collisions in naamgeving te voorkomen. Met 'using namespace std' mag je zelf geen 'cout' meer aanmaken. Nou is dat niet zo'n probleem, maar wat als een van jouw globale functies/variabelen in een latere versie van de standard libraries ook in std zit? Dan heb je een conflict en compileert het niet meer.Ik zie voorbeelden waar geen using namespace std; wordt gebruikt en dan in plaats van bijvoorbeeld gewoon cout is het nodig om std::cout te gaan schrijven.
Dus vroeg me af waarom niet iedereen using namespace std gebruikt.
Ja dat dacht ik al maar mijn financiële situatie is bedroevend. Maar jouw tip werkte prima, tnx.Mijzelf schreef op zaterdag 12 januari 2019 @ 18:30:
[...]
Ik bedoelde eigenlijk letterlijk 2 monitors.
Om die reden ben ik ook met een gratis internet cursus bezig die af en toe wat stappen overslaat.
Omdat ik nog niet naar de antwoorden had gekeken onstond eerder in dit topic mijn aanname dat het returnen van een string nogal ingewikkeld is (uren mee zoet geweest)
Heb inmiddels mijn uitwerkingen van les 9 nagekeken en blijkt het heel simpel te wezen.
Het 'voorvoegsel' int Functie() veranderen naar string Functie() en return myString; gaat ineens zonder problemen.
Hier is de les 9 te vinden voor wie het interesseert.
http://www.ronkes.nl/oldprogrammeren/antwoorden.html
Had die vraag erbij verzonnen en nog niet zelf opgezocht, trefwoord 'using namespace disadvantage' levert o.a. dit op : https://www.geeksforgeeks...-considered-bad-practice/Namespaces hebben een functie, namelijk om collisions in naamgeving te voorkomen. Met 'using namespace std' mag je zelf geen 'cout' meer aanmaken. Nou is dat niet zo'n probleem, maar wat als een van jouw globale functies/variabelen in een latere versie van de standard libraries ook in std zit? Dan heb je een conflict en compileert het niet meer.
Dat is de lange versie van jouw antwoord zeg maar.
Toch was het niet enkel luiheid om die vraag te stellen, ik zat namelijk te tobben met waarom std::cout wel vervangen kan worden door cout mits 'using' wordt gebruikt , terwijl string::npos niet vervangen kan worden door string npos hoewel #include<string> toch boven main() staat.
Of logischer een andere variant die ik probeerde:
std::cout kan met 'using' wel cout worden
maar
string::npos kan met #include<string> geen npos worden.
En opvallend is dat in het antwoord van les 9 (mapje Aeneas) maar liefst drie keer dit voorkomt :
if (myIndex != string.npos)
Hetgeen bij mij dus een error oplevert.
Heb inmiddels gevonden dat dit wel gaat :
string string = "Hallo";
if (myIndex != string.npos)
Maar zo heeft de cursus auteur het m.i. niet bedoeld aangezien hij geen string met de naam string heeft geïni-tialiseerd en 3x dezelfde schrijffout lijkt me ook onwaarschijnlijk.
Ik vermoed hier een verouderde schrijfwijze ?
Deze vraag is lastig te vinden, zoeken op string.npos levert maar één resultaat, de rest is allemaal string::npos.
Lijkt triviaal maar met zulk soort dingetjes kan ik me een tijd mee bezighouden.
[ Voor 3% gewijzigd door kitao op 13-01-2019 16:55 . Reden: spelfouten ]
Verder is string::npos een static member, geen namespace.
Zie voor gebruik:
http://www.cplusplus.com/reference/string/string/npos/
http://www.cplusplus.com/forum/beginner/233668/
Bij een kringloop winkel zie je vaak 'oude' 3:4 LCD monitoren voor 1 of 2 tientjes.mijn financiële situatie is bedroevend.
Nee klopt, maar het ligt voor de hand (en is mijn ervaring) dat alle relational operators dan op die manier geschreven gaan worden..oisyn schreef op vrijdag 11 januari 2019 @ 21:33:
Maar bij < en > (en <= en >=) hoeft het natuurlijk ook niet hè. Maar ik ben ook geen fan. Ik kan me de laatste keer niet heugen dat ik deze fout heb gemaakt, dus dan vind ik leesbaarheid een belangrijker punt.
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.
Dat valt zeker te overwegen, bedankt.Mijzelf schreef op zondag 13 januari 2019 @ 20:34:
Bij een kringloop winkel zie je vaak 'oude' 3:4 LCD monitoren voor 1 of 2 tientjes.
Ja bedankt, die twee begrippen moet ik inderdaad nog uitzoeken, had inmiddels wel de verschillen in schrijfwijze gezien van het aanroepen van #include en namespace.EddoH schreef op zondag 13 januari 2019 @ 19:19:
Een include is iets anders dan using. Zie documentatie.
Verder is string::npos een static member, geen namespace.
Zie voor gebruik:
http://www.cplusplus.com/reference/string/string/npos/
http://www.cplusplus.com/forum/beginner/233668/
Eigenlijk stond er ook geen string::npos maar std::string::npos in het example.
Maar vind het verder nog steeds een raadsel waarom de cursus auteur if (myIndex != string.npos) heeft toegepast want dat compileert bij mij niet.
Ben inmiddels bij les 10 met titel Verzamelingen: http://www.ronkes.nl/oldprogrammeren/les10.html
Deze oefening zit erbij :
2. Maak een vector met daarin een vector, zodat je een tabel krijgt.
Schrijf de tabel naar het scherm.
Hieronder zie je hoe je zo'n twee-dimensionale vector moet declareren.
vector<vector<int> > myTable;
Bovenstaande hint bleek iets te summier, eerst geprobeerd met enkel die info de oefening te maken maar dat lukte niet. Dus ben elders gaan spieken. Het principe heb ik geloof ik redelijk door nu, maar nog niet dat ik het zonder naslag zo op kan schrijven. Er is wel iets dat ik enigzins teleurstellend vind.
Dit programma levert als resultaat een rijtje van 6 getallen op :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| #include<iostream> #include<vector> using namespace std; int main(){ vector<int>Vector; int N = 0; cout << "Voer 6 getallen in \n\n"; for (int i = 0; i < 6; i++) { cin >> N; Vector.push_back(N); } cout << "\n\nDit is de getallen Verzameling :\n\n"; for (int i = 0; i < 6; i++) { cout << Vector.at(i) << "\t"; } cout << "\n\n"; system("pause"); } |
Onderstaand programma levert als resultaat een tabel op met twee rijen en drie kolommen :

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
| //https://www.quora.com/How-do-I-create-a-2D-vector-array-using-std-vector // http://www-h.eng.cam.ac.uk/help/tpl/languages/C++/vectormemory.html #include<iostream> #include<vector> using namespace std; int main(){ vector<vector<int> > VectorVector; int k; cout << "Voer 6 getallen in \n\n"; for (int i = 0; i < 2; i++) { VectorVector.push_back(vector<int>()); for (int j = 0; j < 3; j++) { cin >> k; VectorVector[i].push_back(k); } } cout << "\n\nDit is de getallen Verzameling :\n\n"; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { cout << VectorVector[i][j] << "\t"; } cout << endl; } cout << endl << endl; system("pause"); } |
Maar dat resultaat staat of valt met het wel of niet aanwezig zijn van regel 23, cout << endl;
Haal ik die namelijk weg dan is het resultaat van prog2 identiek aan prog1.
Toen ik dat voor het eerst merkte had ik het gevoel van valsspelen.
Ik zie wel het nut in van cout << VectorVector[i][j] , zo kan je bepaalde gedeeltes uit de verzameling opvragen en printen. Maar had ergens verwacht dat er een soort van allesomvattende cout << VectorVector; zou zijn waardoor de verzameling in zn geheel meteen in tabelvorm zou worden geprint.
Die is er waarschijnlijk niet ?
Zelf heb ik geen programmeurs in mijn kennissenkring en als hobbyist ook geen scholing voor gedaan.
Merk nu wel dat ik aan het kopie/plak blokkendoos programmeren ben en eigenlijk puur afgaand van wat er op het output schermpje verschijnt.
Kopie/plak uit voorbeelden die zo weinig mogelijk voor mij nieuwe dingen bevatten en het vinden daarvan kan soms enige tijd duren.
En veel geschuif binnen het programma als het resultaat afwijkt van hetgeen er moet komen.
Met daarbij soms verrassende dingen, zo verwachtte ik dat Vector.at(0) de eerste letter zou geven maar in plaats daarvan werd het eerste woord geprint.
Voorbeeld van bij elkaar geblokt programmaatje uit drie verschillende websites :
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
| /* 4. Schrijf een programma dat een zin vraagt aan de gebruiker, alle woorden in de zin stuk-voor-stuk in een vector zet en daarna de woorden genummerd onder elkaar op het scherm zet. */ #include<iostream> #include<string> #include<vector> #include <sstream> using namespace std; string zin; int y; vector<string>Vector; int main() { cout << "schrijf een zin \n\n"; getline(cin, zin); cout << endl << endl; system("pause"); cout << endl; istringstream ss(zin); // gevonden op http://www.cplusplus.com/faq/sequences/strings/split/ while (!ss.eof()) // blijf splitten tot einde string { string x; // here's a nice, empty string getline(ss, x, ' '); // splits de string op de spaties // cout << x << endl; // print it out, EVEN IF WE ALREADY HIT EOF Vector.push_back(x); // zet iedere aparte split in vector // gevonden op http://www.ronkes.nl/oldprogrammeren/les10.html y += 1; // y wordt gebruikt als display nummertje voor de woorden for (int i = 0; i < Vector.size(); i++) // doorloop vector // ieder woord krijgt blijkbaar eigen positie in de Vector { cout << y << " " << Vector.at(i) << endl; // print het woord op positie i Vector.erase(Vector.begin()); // maak de Vector leeg voor het volgende woord // gevonden op http://www.cplusplus.com/reference/vector/vector/erase/ } } cout << endl; system("pause"); } |
met deze output :

Ik vraag me nu af of anderen op deze manier ook programmeren hebben geleerd en of de kopie/plak methode gangbaar gebruik is ?
Zou misschien beter zijn een basis setje 'steentjes' te hebben en dan eerst daarmee wat gaan schuiven voordat er een nieuw setje bij komt ?
Probleem is dat bij deze korte en gratis online cursus er m.i. te weinig steentjes zijn om de oefening mee te voltooien. Iemand die uit ervaring een meer gestructureerde, goedkope (en legale) cursusboek of online tutorial weet , dan hoor ik dat graag.
[ Voor 1% gewijzigd door kitao op 15-01-2019 15:04 . Reden: code iets overzichtelijker gemaakt ]
Die for-lus is ook raar. Je verwijdert steeds het eerste element bij elke iteratie (waardoor het element op plek 1 natuurlijk op plek 0 terecht komt), maar je gebruikt wel steeds i om de vector te indexeren. Dan ga je natuurlijk elementen missen als er daadwerkelijk meerdere elementen in staan.
En waarom verwacht je dat Vector.at(i) het i'de teken teruggeeft? Het is toch een vector van woorden?
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.
Ja, dat vond ik ook..oisyn schreef op dinsdag 15 januari 2019 @ 14:04:
Ik vind je code maar raar.
Elke iteratie van de buitenste while ga je een woord toevoegen aan de vector, vervolgens loop je binnen die iteratie over de elementen van de vector en verwijder je de elementen. Je vector bevat dus altijd hooguit maar 1 element.
Maar kan niet alles reproduceren wat ik daarvoor heb geprobeerd.
Kijkend op de output window zag ik dat zonder leegmaken bij iedere while loop er een woord bijkwam.
dus bij while loop 0 werd er 1 Goede geprint
en bij while loop 1 werd er 2 Goede middag geprint etc.
Heb bovendien moeite met het begrip iteratie.
Dat bedoelde ik dus met puur op output window afgaan.Die for-lus is ook raar. Je verwijdert steeds het eerste element bij elke iteratie (waardoor het element op plek 1 natuurlijk op plek 0 terecht komt), maar je gebruikt wel steeds i om de vector te indexeren. Dan ga je natuurlijk elementen missen als er daadwerkelijk meerdere elementen in staan.
Heb willekeurig ergens een lange zin geplukt, die als invoer geplakt maar toch werd ieder apart woord op nummervolgorde geprint. Had niet het idee dat er iets gemist werd ? Of bedoel je iets anders ?
Moet er wel bij zeggen dat ik mijn uitwerking nog niet met het antwoord heb vergeleken.
http://www.ronkes.nl/oldprogrammeren/antwoorden.html
Maar ja, de volgende twee en laatste lessen hebben geen antwoorden en mede daarom was mijn vraag of iemand nog een goede tutorial kan aanraden.
niet bij declaratie vector<int>Vector; meen ik ?En waarom verwacht je dat Vector.at(i) het i'de teken teruggeeft? Het is toch een vector van woorden?
heb er zelf als vermoeden maar vector<string>Vector; van gemaakt zonder eigenlijk te weten wat er dan gebeurt.
Omdat je bij ieder woord over de hele vector heenloopt. Waarom loop je niet gewoon pas over de vector heen als je alle woorden hebt verzameld, dus buiten de while loop?kitao schreef op dinsdag 15 januari 2019 @ 15:24:
[...]
Ja, dat vond ik ook.
Maar kan niet alles reproduceren wat ik daarvoor heb geprobeerd.
Kijkend op de output window zag ik dat zonder leegmaken bij iedere while loop er een woord bijkwam.
dus bij while loop 0 werd er 1 Goede geprint
en bij while loop 1 werd er 2 Goede middag geprint etc.
Heb bovendien moeite met het begrip iteratie.
Een vector<int> is een vector van ints. Nu gebruik je een vector van strings. En wat je eraan toevoegt met push_back() is ook een string, namelijk het woord dat je toevoegt.niet bij declaratie vector<int>Vector; meen ik ?
Misschien moet je eerst proberen de code te begrijpen ipv gewoon maar wat bij elkaar copy-pastenheb er zelf als vermoeden maar vector<string>Vector; van gemaakt zonder eigenlijk te weten wat er dan gebeurt.
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.
ja, dat idee had ik ook al.oisyn schreef op dinsdag 15 januari 2019 @ 15:32:
Misschien moet je eerst proberen de code te begrijpen ipv gewoon maar wat bij elkaar copy-pasten
beetje erop los knippen en plakken totdat het output schermpje de gewenste vorm aanneemt is dus niet de juiste methode.
"Snap het dan" helpt daarentegen ook niet veel.
Maar bedankt voor je tips .oisyn ,zal ze morgen nog eens goed doorlezen.
Weet niet of het kwartje inmiddels gevallen was, maar std::string::npos is een static member van de class string (die in de std namespace leeft).kitao schreef op dinsdag 15 januari 2019 @ 05:58:
[...]
Maar vind het verder nog steeds een raadsel waarom de cursus auteur if (myIndex != string.npos) heeft toegepast want dat compileert bij mij niet.
Static members kunnen met <classname>::<membername> worden aangesproken ( hier dus string::npos ) wat wat mij betreft de cleanste manier is, maar ook via een object van dat type (my_string.npos) wat jij dus doet als je je std::string object 'string' gaat noemen.
Je voelt aan je water dat dat laatste geen goed idee is neem ik aan?
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.
Dat was om te testen farlane, de auteur gaf namelijk dit in zn antwoord : if (myIndex != string.npos).farlane schreef op dinsdag 15 januari 2019 @ 22:33:
Weet niet of het kwartje inmiddels gevallen was, maar std::string::npos is een static member van de class string (die in de std namespace leeft).
Static members kunnen met <classname>::<membername> worden aangesproken ( hier dus string::npos ) wat wat mij betreft de cleanste manier is, maar ook via een object van dat type (my_string.npos) wat jij dus doet als je je std::string object 'string' gaat noemen.
Je voelt aan je water dat dat laatste geen goed idee is neem ik aan?
maar dat draait bij mij niet, dus was er (tijdelijk) over verbaasd.
Op deze manier bedoel je ?.oisyn schreef op dinsdag 15 januari 2019 @ 15:32:
Omdat je bij ieder woord over de hele vector heenloopt. Waarom loop je niet gewoon pas over de vector heen als je alle woorden hebt verzameld, dus buiten de while loop?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #include<iostream> #include<string> #include<vector> using namespace std; string Zin, Zin2; vector<string>Vec; int main(){ cout << "geef zin " << endl; getline(cin, Zin); getline(cin, Zin2); Vec.push_back(Zin); Vec.push_back(Zin2); // laad eerst de vector op // doe er pas na het opladen bewerkingen mee, zoals bijvoorbeeld .. for (int i = 0 ; i < Vec.size() ; ++i) { cout << Vec[i] << endl; } system("pause");} |
Nog even terugkomend op mijn opmerking dat ik mijn code ook maar vreemd vond, dat was meer in de zin van dat het vast niet de bedoeling was om in het antwoord allerlei dingen erbij te plukken die nog niet behandeld waren in die lessen serie. Voor mij zijn de meeste codes nog hiërogliefen waarvan lastig te zien is of zo'n code elegant of geforceerd is. Heb inmiddels wel het antwoord van de auteur bekeken en deze gecompacteerd
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
| // les 10 oef 4 http://www.ronkes.nl/oldprogrammeren/oefeningen10.html // les 10 antw 4 http://www.ronkes.nl/oldprogrammeren/antwoorden.html #pragma warning ( disable : 4786 ) // schakel waarschuwing 4786 uit #include <iostream> #include <string> #include <vector> using namespace std; int main() { string myZin; // vraag om invoer cout << "Voer een zin in: "; getline(cin, myZin); vector<string> myWoorden; // doorloop zin letter voor letter int myBegin = 0; for (int i = 0; i < myZin.length(); i++) { if (myZin.at(i) == ' ') // is dit een spatie? { string myWoord = myZin.substr(myBegin, i - myBegin); // ja, haal woord uit zin myWoorden.push_back(myWoord); // sla woord op in vector myBegin = i + 1; // onthoud begin van volgende woord } } myWoorden.push_back(myZin.substr(myBegin, myZin.length() - myBegin)); // voeg laatste woord toe aan vector for (int j = 0; j < myWoorden.size(); j++) // doorloop vector { cout << j + 1 << ". " << myWoorden.at(j) << endl; // schrijf woord naar scherm } cout << endl; // wacht op enter system("pause"); return 0; } #pragma warning ( default: 4786 ) // schakel waarschuwing 4786 weer in |
Bij deze heb ik dan vanwege regel 24 e.v. (laatste woord opvegen) wel het gevoel van gekunsteld maar heb nog niet zelf geprobeerd om met de beschikbare 'steentjes' het beter te doen, als dat al mogelijk is, want wil tegelijkertijd ook graag verder met het volgende hoofdstuk.
Dit komt eruit :

Vanwege dubbele spatie een lege lijn op 3. Maar dat gebeurt ook met mijn programmaatje.
Ik merk trouwens op (zonder bijdehand te willen doen) dat de vector in regel 20 ook binnen 2 loops wordt gevuld ?
En nog hartelijk bedankt trouwens voor de moeite die jij en anderen nemen en/of genomen hebben om dit even door te nemen.
O ja nog iets
de #pragma regels (?) op 3 en 33, die kunnen weg, had bij mij tenminste geen invloed.
Dat was me duidelijk, maar de test die je deed gaf (impliciet) aan dat je niet de betekenis ken(t/de) van een static member.kitao schreef op woensdag 16 januari 2019 @ 14:23:
[...]
Dat was om te testen farlane, de auteur gaf namelijk dit in zn antwoord : if (myIndex != string.npos).
maar dat draait bij mij niet, dus was er (tijdelijk) over verbaasd.
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.
Dat klopt, en ik beheers dat begrip nog steeds niet goed. Static Members of a C++ Class doorgelezen maar op dit moment wacht ik nog even met classes, na wat meer basis komt dat vast nog voorbij neem ik aan.farlane schreef op woensdag 16 januari 2019 @ 18:55:
Dat was me duidelijk, maar de test die je deed gaf (impliciet) aan dat je niet de betekenis ken(t/de) van een static member.
Kwam vandaag while (cin.good()); tegen en is op zich best te bevatten totdat ik probeerde die op de watchlist te krijgen. Dat lukte maar er kan daarvan geen waarde in beeld worden gebracht ?
Heb twee pagina's doorgelezen, hfdst 1.11 en 1.11a van https://www.learncpp.com/ en hier en daar wat rondgekeken maar ben er op dit punt niet verder mee gekomen.
Visual Studio snip

1
2
3
4
5
6
7
8
9
10
11
12
13
| #include <iostream> using namespace std; void main() { int myInput; do { cin >> myInput; } while (cin.good()); // cin.good() geeft false als de invoer ongeldig is. system("pause"); } |
Ps/
Liep vervolgens tegen een geskipte cin aan, heeft me drie uur gekost
Fragmentje met oplossing, via http://www.cs.technion.ac...q/istream-and-ignore.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| cout << "toets b om opnieuw te beginnen \n"; cin >> d; // cin doet het hier prima !!!!!! if (d == "a") { cout << "toets een niet-getal om naar het menu te gaan \n"; do { cout << "geef getal "; cin >> Input; // Input is een Int. Som += Input; cout << "De som = " << Som << endl; } while (cin.good()); } cout << "geef je nieuwe keuze : a of b ? \n"; // cin >> d; wordt geskipt ????????????????? // Oplossing : // How can I get cin to skip invalid input characters? // http://www.cs.technion.ac.il/users/yechiel/c++-faq/istream-and-ignore.html // #include <limits> moet vermeld staan boven main cin.clear(); cin.ignore(numeric_limits<streamsize>::max(), '\n'); cin >> d; |
Hier stond nog een suggestie maar die deed het niet :
You can only input one word into a cin. Instead, use getline(cin, string name); If it still doesn't work, add a cin.ignore(); before your getline(cin, string name);, like this:
string country;
cout << "Now please enter the country you are in at the moment:\n\n";
cin.ignore();
getline(cin, country);
This will now definitely work.
Waarom dat laatste niet lukt weet ik echter niet.
Ps2/
Mijn vraag over een passende cursus is inmiddels gevonden. Ik had wel iets duidelijker kunnen zijn, ik bedoelde eentje met oefeningen én antwoorden.
Voorlopig kan ik met deze drie verder :
Cursus
http://liacs.leidenuniv.nl/~kosterswa/lst/lst.pdf
http://liacs.leidenuniv.nl/~kosterswa/lst/
antwoorden
http://liacs.leidenuniv.nl/~kosterswa/lst/uitw.txt
Video Cursus
https://github.com/TPayne...ee/master/LLCPP_Solutions
Let's Learn C++ ~ Basics: 1 of 14
YouTube: Let's Learn C++ ~ Basics: 1 of 14 ~ Visual Studio Setup + My First ...
Vampire Studios (snelcursus, zonder oef en antw)
http://members.chello.nl/~s.pampiermole/index.html
en
http://www.ronkes.nl/oldprogrammeren/index.html
[ Voor 53% gewijzigd door kitao op 18-01-2019 02:26 ]
Kwam onderstaande functie tegen in hfdst. 3.3 van http://liacs.leidenuniv.nl/~kosterswa/lst/lst.pdf
Is lesmateriaal dat nogal grote stappen neemt en gaat nu over call-by-value en call-by-reference.
Dit is de code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| void Alias (int r, int & s ) { int t; t = 3; r = r + 2; s = s + r + t; t = t + 1; r = r - 3; cout << r << s << t << endl; } int main ( ) { int t = 12; Alias (t,t); cout << t << endl; return 0; } |
Dit is de functie : void Alias(int r, int s) { }
De bedoeling was om na te gaan wat er gebeurt met het toevoegen van een &.
Er zijn dan vier mogelijkheden
1. void Alias(int r , int s)
2. void Alias(int & r , int s)
3. void Alias(int r , int & s)
4. void Alias(int & r , int & s)
Vanuit main wordt deze functie aangeroepen met Alias (t,t);
De 'return' van functie Alias in main wordt resp.
1. geen 'return' , t main blijft t main
2. t in main wordt r
3. t in main wordt s
4. t in main wordt ...... r of s ? (<<<<< dit is mijn vraag)
Is voor mij niet te zien en weet ook niet hoe dit zichtbaar te maken op dit moment.
Terwijl ik aanneem dat r en s toch aparte geheugenlocaties hebben.
Hieronder staat mijn test code voor wie het zelf wil nagaan :
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
| #include <iostream> using namespace std; void Alias(int r, int s) { cout << "Alias(int r, int s) " << endl << endl; int t; t = 3; r = r + 100; cout << "Tussenresultaten in Alias \n\n Ar = " << r; cout << " As = " << s; s = s + r + t; cout << " Ar = " << r; cout << " As = " << s; t = t + 1; cout << " At = " << t; r = r - 10; cout << " Ar = " << r ; cout << " As = " << s; s = s + 300; cout << " Ar = " << r; cout << " As = " << s << endl << endl; cout << "Eindresultaat van Alias \n\n " ; cout << "Ar , As , At respectievelijk = " << r << "\t" << s << "\t" << t << endl << endl; // return 0; } int main() { int t = 20; Alias(t, t); cout << "Eindresultaat van t in main \n\n "; cout << "Main t = " << t << endl; cout << endl << endl; system("pause"); return 0; } |
Ik wou de testcode eigenlijk onder een spoiler zetten om de post (visueel) te verkorten maar dat gaat niet geloof ik ?
Eerder had ik het over de 'return' van de functie Alias.
Maar weet niet of dit terecht is, geeft namelijk ''return value does not match the function type c++''.
Probeer maar eens:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| #include <iostream> using namespace std; void Test(int &r, int &s) { r = 10; cout << s << endl; } int main() { int t = 20; Test(t, t); system("pause"); return 0; } |
Ok, dus mijn aanname van verschillende geheugenplekken was verkeerd, ik ging aanvankelijk uit van 4 geheugenplekken, namelijk t main , t Alias , r Alias en s Alias.Daos schreef op zaterdag 19 januari 2019 @ 23:06:
In geval 4 zijn r en s allebei een referentie naar t in main. Verander je r, dan verandert t in main en dus ook s. Het is een en hetzelfde plekje geheugen.
Probeer maar eens:
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #include <iostream> using namespace std; void Test(int &r, int &s) { r = 10; cout << s << endl; } int main() { int t = 20; Test(t, t); system("pause"); return 0; }
En ik kwam pas na het plaatsen van mijn vraagpost op het idee om de variabelen op de watchlist te zetten.
Ben er inmiddels meermaals doorheen gestapt en zie dan het volgende :
Variabele t blijft zowel in main als in Alias hetzelfde (hetgeen betekent dat ik de scope van een lokale variabele minder goed begrepen heb als gedacht, zoals hier een voorbeeld daarvan :
https://cscircles.cemc.uwaterloo.ca/11b-variable-scope-nl/
maar dat is ander onderwerp)
Want de beide t's bewegen met elkaar mee.
Variabelen r en s zijn wel verschillend totdat dit (int &r, int &s) wordt opgenomen in de code.
Pas dan worden r en s één geheugenplaats begrijp ik eruit.
Hartelijk dank
[ Voor 4% gewijzigd door kitao op 20-01-2019 00:19 . Reden: typ ]
Als je zoiets doet:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| #include <iostream> using namespace std; void Test(int &r, int &s) { r = 10; cout << s << endl; } int main() { int t = 20; int u = 30; Test(t, u); system("pause"); return 0; } |
dan verwijst r naar t en s naar u. Verander je r in de functie Test, dan verandert s deze keer niet omdat die naar een ander plekje in het geheugen verwijst; namelijk u in main.
edit:
Ik denk dat je het principe van references nog niet helemaal begrijpt. Een reference heeft geen eigen opslag. Het is een verwijzing naar een andere plek. (Onder de motorkap wordt er wel wat opgeslagen: het adres van die andere plek, maar daar kan je niet bijkomen vanuit je programma)
1
2
3
4
5
6
7
8
| // reserveert in het geheugen ruimte voor een int en stopt daar 10 in. int a = 10; // maakt een verwijzing naar a; b heeft geen eigen opslag. int &b = a; // omdat b naar a verwijst, verandert a ook naar 20. b = 20; |
Parameters bij functies werken op ongeveer dezelfde manier:
1
2
3
4
5
6
7
8
9
10
11
| void TestValue(int x) { // x heeft eigen opslag in het geheugen. De waarde wordt er in gekopieerd // bij het aanroepen van de functie. x = 10; } void TestReference(int &x) { // x is een verwijzing naar de variabele die meegegeven wordt bij het // aanroepen van de functie; x heeft geen eigen opslag. x = 10; } |
[ Voor 43% gewijzigd door Daos op 20-01-2019 01:17 ]
Ik denk dat je het principe van references nog niet helemaal begrijpt.Daos schreef op zondag 20 januari 2019 @ 00:40:
Dat in jouw voorbeeld bij (int &r, int &s) r en s naar hetzelfde geheugenplekje verwijzen komt door de aanroep Alias(t, t). r en s zijn dan allebei een referentie naar t in main.
Als je zoiets doet:
C++:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> using namespace std; void Test(int &r, int &s) { r = 10; cout << s << endl; } int main() { int t = 20; int u = 30; Test(t, u); system("pause"); return 0; }
dan verwijst r naar t en s naar u. Verander je r in de functie Test, dan verandert s deze keer niet omdat die naar een ander plekje in het geheugen verwijst; namelijk u in main.
edit:
Ik denk dat je het principe van references nog niet helemaal begrijpt. Een reference heeft geen eigen opslag. Het is een verwijzing naar een andere plek. (Onder de motorkap wordt er wel wat opgeslagen: het adres van die andere plek, maar daar kan je niet bijkomen vanuit je programma)
C++:
1 2 3 4 5 6 7 8 // reserveert in het geheugen ruimte voor een int en stopt daar 10 in. int a = 10; // maakt een verwijzing naar a; b heeft geen eigen opslag. int &b = a; // omdat b naar a verwijst, verandert a ook naar 20. b = 20;
Parameters bij functies werken op ongeveer dezelfde manier:
C++:
1 2 3 4 5 6 7 8 9 10 11 void TestValue(int x) { // x heeft eigen opslag in het geheugen. De waarde wordt er in gekopieerd // bij het aanroepen van de functie. x = 10; } void TestReference(int &x) { // x is een verwijzing naar de variabele die meegegeven wordt bij het // aanroepen van de functie; x heeft geen eigen opslag. x = 10; }
Een reference heeft geen eigen opslag.
Het is een verwijzing naar een andere plek.
Dat verklaart al veel, bedankt.
Het klopt, ik ben nog niet zover. De pdf hfdstk 3.3 waar ik het uithaalde verwijst naar inhoud van een boek dat ik niet heb. Is misschien beter om dat lesmateriaal even te laten voor wat het is, maakt te grote stappen.
Heel lang geleden ben ik ooit eens met deze bezig geweest

Vandaar mijn interesse welke geheugenadres, r of s, nu zn inhoud overdroeg aan t in geval &r én &s.
Ook na plaatsing op de watchlist was dit niet te zien.
Maar ik begrijp nu beter wat je bedoelt , het zijn referenties en heb op dit moment even geen andere vragen, want dit verklaart dan waarschijnlijk ook meteen waarom het verhaal van de scope van een lokale variabele (t in main en t in Alias) niet op ging.
De eerder genoemde video serie ben ik aan het volgen en dat gaat beter zonder hiaten.
@Daos
Ben inmiddels tegen het onderwerp aangelopen, call by value, pointer en reference met een paar voorbeelden hier https://www.tutorialspoint.com/cplusplus/cpp_functions.htm. Echt helemaal helder is het nog niet en vereist nog wat oefeningen, waar deze video over reference goed van pas komt, maar het vorige draadje was wel aanleiding om te kijken naar machinetaal. Kwam daarbij nasm en masm tegen. Nasm heeft een mooie tutorial op dezelfde site maar vereist Linux zover ik begrepen heb. Had eerder Mint op een lap staan, heb die achteraf van de partitie verwijderd en lap ligt nu in coma dus heb daar van afgezien en voor masm gekozen.
Voor wie dat als beginner ook wil proberen met Visual Studio raad ik een installatie video van professor Hank aan :
YouTube: Assembly Tutorial: Compiling Your First Assembly Program Using Visu...
In zijn afspeellijsten zijn zover ik gezien en doorlopen heb echter maar 6 vervolgvideo's over masm.
Zoeken binnen dit forum op nasm en masm levert wel resultaten maar zijn minstens een jaar oud.
Die programmeertalen schijnen dus niet erg te leven. Weet iemand daar misschien een reden voor ?
[ Voor 3% gewijzigd door kitao op 22-01-2019 23:45 . Reden: video over reference toegevoegd ]
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.
Ik zat te denken om ze gelijk op te laten lopen, net als in de schoolbanken, het ene uur rekenen en het andere geschiedenis. Maar met mijn vraag bedoelde ik eigenlijk of het geen onnodige moeite is om een beter begrip te krijgen van C++ onder de motorkap en waarom er zo weinig belangstelling voor lijkt te zijn. Want als ik erop zoek dan zie ik het eerste topic over Nasm ergens in feb 2016 en Masm was nog verder terug geloof ik (afgezien van Devschuur). En op internet vergeleken met C++ is het lesmateriaal ook lang niet zo vers en niet zo veel heb ik het idee. Een echt technische vraag heb ik nu niet, mijn vorige post was ook bedoeld dat als een bezoeker zoekt binnen dit forum op masm dat er dan een m.i. goede en actuele, maar beknopte instructie video-serie is om mee te starten.farlane schreef op dinsdag 22 januari 2019 @ 23:19:
Que? Wat wil je leren dan, C++ of assembly? Wat is de moeilijkheid waar je tegenaan loopt?
@Radiant hierna
Ik heb na een tijd zoeken (en vergelijken) inmiddels iets gevonden waar ik voorlopig mee vooruit zou kunnen. Heb nog niet helemaal getest of het goed gaat draaien op mijn versie van ide, vs17, maar het lijkt wel dezelfde syntax te hebben. Is ook een serie van video's , welke methode mij meer schijnt te liggen als tekstmateriaal. Eerste twee video's zijn geluids-kwalitatief pet maar wordt daarna stuk beter.
YouTube: x64 Assembly and C++ Tutorial 0: Setting Up x64 Assembly in Visual S...
Bedankt voor je tips, zal ze eens opzoeken.
[ Voor 27% gewijzigd door kitao op 23-01-2019 10:20 ]
Persoonlijk heb ik assembly geleerd door juist te gaan reverse engineeren en (binary) CTFs te doen in mijn vrije tijd, daar leer je tegelijkertijd assembly maar ook secure coding, exploits schrijven, de Windows/Linux API van, etc. Er is ook een hoop goede literatuur over (Reverse Engineering for Beginners van Yurichev, RE101 van Malware Unicorn, Practical Malware Analysis, Azeria Labs (voor ARM), etc).
De basics zijn handig om te kennen (voor alle talen) omdat je dan bepaalde concepten sneller kunt plaatsen, maar daar hoef je geen x86 assembly voor te kunnen.kitao schreef op woensdag 23 januari 2019 @ 00:04:
Ik zat te denken om ze gelijk op te laten lopen, net als in de schoolbanken, het ene uur rekenen en het andere geschiedenis. Maar met mijn vraag bedoelde ik eigenlijk of het geen onnodige moeite is om een beter begrip te krijgen van C++ onder de motorkap en waarom er zo weinig belangstelling voor lijkt te zijn.
Assembly leren als je het concept pointers/references voor jezelf niet duidelijk krijgt, tja ...... /shrug
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.
ik kwam nog een ander forum tegen, zit in mapjefarlane schreef op woensdag 23 januari 2019 @ 19:00:
De basics zijn handig om te kennen (voor alle talen) omdat je dan bepaalde concepten sneller kunt plaatsen, maar daar hoef je geen x86 assembly voor te kunnen.
Assembly leren als je het concept pointers/references voor jezelf niet duidelijk krijgt, tja ...... /shrug
A protected forum where programmers learning assembler can ask questions in a sensible and safe atmosphere without being harassed or insulted. This is also targetted at experienced programmers from other languages learning assembler that don't want to be treated like kids.
zie ook http://masm32.com/board/index.php
Vind prima dat je reageert, krijg ik tenminste niet het idee tegen een muur aan te lullen , maar om dan te beweren dat ik hazen hoeken sla omdat ik het niet onder de knie krijg, is allicht iets een te snelle conclusie.
Voor mij is het hobby, maakte op mn 12e een radiootje van een wc-rol kokertje en ben een aantal jaren daarna verder gegaan met weerstand , fietslampje en batterij. En voor je het weet ben je toe aan de 1e chip met 3 and poortjes. En daarna is het geen electronica meer maar zit je codes bij elkaar te schrapen. Waaronder machinetaal, zoals ook af te leiden was van mijn vorige post over de z80.
Dus heb wel enig idee wat er aan de gang is, ben niet helemaal nieuw op deze e-wereld. Probleem met mij is dat ik steeds mn aandacht verlies en er gaten vallen van een jaar of 5. Niet helemaal stilstand maar andere interesses, maar wel als gevolg dat ik vrijwel vanaf 0 weer moet herbeginnen.
Een prof-programmeur zal ik nooit worden maar heb best wel enige vooruitgang geboekt met references.
Niet dat ik het perse heb opgezocht nav de vorige post maar omdat het voorbij kwam in mijn voorgenomen te volgen websites. (stuk of 4 inmiddels, incl assembler)
Kan echter geen huizen bouwen binnen een dag.
En word ook een dagje ouder dus alles is niet zo scherp meer.
#Radiant, zie edit vorige post
[ Voor 5% gewijzigd door kitao op 23-01-2019 22:37 . Reden: typ ]
Je lijkt te impliceren dat ik je mentale capaciteiten in twijfel trek. Dat is in zijn geheel niet aan de orde.kitao schreef op woensdag 23 januari 2019 @ 21:30:
[...]
Vind prima dat je reageert, krijg ik tenminste niet het idee tegen een muur aan te lullen , maar om dan te beweren dat ik hazen hoeken sla omdat ik het niet onder de knie krijg, is allicht iets een te snelle conclusie.
Ik trek wel je leermethode in twijfel. Je hebt vragen over references in C++ en dwaalt af naar assembly, dat lijkt mij niet efficient.
Case in pointProbleem met mij is dat ik steeds mn aandacht verlies en er gaten vallen van een jaar of 5.
Niet helemaal stilstand maar andere interesses
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.
ok,farlane schreef op woensdag 23 januari 2019 @ 22:37:
Je lijkt te impliceren dat ik je mentale capaciteiten in twijfel trek. Dat is in zijn geheel niet aan de orde.
Ik trek wel je leermethode in twijfel. Je hebt vragen over references in C++ en dwaalt af naar assembly, dat lijkt mij niet efficient.
Case in point
het is waar, ik vroeg of erbij nemen van assembly geen verspilde moeite was
mov aex, a8h of int a = 1; verbeteren beiden geen begrip, dat is wel zo.
hoop enkel dat c++ (of andere talen) niet al te abstract raken en iedere connectie met de 'chip' vervaagt.
ben momenteel niet aan het solderen of knopen, maar wil het electronica deel ook niet helemaal uit het zicht raken.
Als je doel is om C++ te leren programmeren is het dat wel, bijna.
Bij C (en in misschien wat mindere mate C++) sijpelt nog genoeg van de machine door (leaky abstractions anyone) om niet de verbinding met die hardware te laten 'vervagen' als je het mij vraagt, zeker als je het combineert met microcontrollers.
Denk je zelf van niet ook prima, houd het dan lekker bij assembly en voel je niet bezwaard
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.
Wat je misschien beter kan doen is references even wegleggen en je concentreren op pointes. Onder water zijn ze exact hetzelfde, alleen zijn de operaties die je ermee doet veel explicieter. En voor de low-level inzichten kun je ook gewoon de debugger erbij pakken. Open een memory view in Visual Studio en ga kijken naar hoe variabele in het geheugen staan.
Als je pointers onder de knie hebt is de stap naar references een hele kleine; het is niets anders dan syntactische suiker om niet steeds die * (dereference) en & (adress of) operatoren te hoeven gebruiken.
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.
Dat is zo, gaat natuurlijk ook om het plezier en dat heb ik er momenteel wel in.farlane schreef op woensdag 23 januari 2019 @ 22:55:
"Verspilde moeite" is het sowieso niet als je het leuk vind; je leert wat en dat is altijd nuttig.
Als je doel is om C++ te leren programmeren is het dat wel, bijna.
Bij C (en in misschien wat mindere mate C++) sijpelt nog genoeg van de machine door (leaky abstractions anyone) om niet de verbinding met die hardware te laten 'vervagen' als je het mij vraagt, zeker als je het combineert met microcontrollers.
Denk je zelf van niet ook prima, houd het dan lekker bij assembly en voel je niet bezwaard
En afgezien van basic op de C64 ben ik idd via micro's bij programmeren beland , en gestrand eigenlijk. Was eens bezig met een rf-kaart en daar hing best een complexe code aan vast en om enigzins dingen in te kunnen stellen (hetgeen pas lukte na andere Tweakers te vragen) is het wel handig om meer kennis vh programma te hebben. De mC ligt in de kast maar kan ook vrij uitgebreid virtueel (simulatie) gebruikt worden zag ik.
Ok, goede tips, bedankt. Ipv de volgende stap nemen eerst nog even blijven concentreren op pointers. De memory view was mij tot nu toe onbekend dus dat is meteen mooi meegenomen..oisyn schreef op woensdag 23 januari 2019 @ 23:24:
Assembly leren om references te leren begrijpen lijkt mij ook niet bijzonder nuttig. Het zal je ongetwijfeld de gewenste inzichten geven, maar dat leidt op dit moment gewoon teveel af.
Wat je misschien beter kan doen is references even wegleggen en je concentreren op pointers. Onder water zijn ze exact hetzelfde, alleen zijn de operaties die je ermee doet veel explicieter. En voor de low-level inzichten kun je ook gewoon de debugger erbij pakken. Open een memory view in Visual Studio en ga kijken naar hoe variabelen in het geheugen staan.
Als je pointers onder de knie hebt is de stap naar references een hele kleine; het is niets anders dan syntactische suiker om niet steeds die * (dereference) en & (adress of) operatoren te hoeven gebruiken.

Heb in visual het keuze menu links naast de startknop Loc Win Debugger al van x86 op x64 gezet maar leek niet veel verbetering daarin te geven.
Ps/
Bovenstaande is inmiddels opgelost, in dat zelfde keuze menu veldje zit een config manager, in video 0 vd serie meer uitleg (rond min 5).
Bovenstaand plaatje komt van deze web, gaat over mixen van C en Assembly
https://picoledelimao.git...27/mixing-assembly-and-c/
Zit nog een verwijzing in naar een online pdf, ziet er ook best goed uit
http://download-mirror.sa...GroundUp-1-0-booksize.pdf
[ Voor 16% gewijzigd door kitao op 24-01-2019 10:56 ]
Was aan het oefenen met het volgende :
https://erlerobotics.gitb...s/exercises_pointers.html
1
2
3
4
5
6
7
8
9
10
| int n; cout<<"Enter number of values:"; cin>>n; cout<<"Enter values in array:\n"; int arr[n]; for(i=0;i<n;i++) { cin>>arr[i]; } |
dit geeft een error op lijn int arr[n];
Error (active) E0028 expression must have a constant value
Via deze kunnen oplossen met
1
2
3
| int n; cin >> n; int *array = new int[n]; |
https://stackoverflow.com...create-an-array-of-size-n
Maar kwam (ook elders) opmerkingen tegen dat het per C++ versie verschilt , en zelfs per compiler, of er wel of niet VLA's zijn toegestaan.
https://www.geeksforgeeks...length-arrays-in-c-and-c/
Een microsoft overzicht ...
https://support.microsoft...ported-visual-c-downloads
.. zegt dat Visual Studio 2013 versie C++ 12.0 heeft, achter VS15 staat niks, maar dat is volgens mij versie 14.0 en achter VS17 staat ook niks (heb zelf de community versie). Welke C++ versie is dat ?
En vallen dit soort dingen vaker te verwachten bij meerdere commando's of is deze VLA (variabele lengte array) een uitzondering ?
VLA's zijn geen onderdeel van C++, maar wel C(99). Een van de aspecten van C die niet zijn overgenomen in de C++ standaard. Ze worden wel door de GCC (en misschien andere compilers) als extensie ondersteund in C++kitao schreef op vrijdag 25 januari 2019 @ 10:27:
In welk jaar leven wij ?
Was aan het oefenen met het volgende :
https://erlerobotics.gitb...s/exercises_pointers.html
code:
1 2 3 4 5 6 7 8 9 10 int n; cout<<"Enter number of values:"; cin>>n; cout<<"Enter values in array:\n"; int arr[n]; for(i=0;i<n;i++) { cin>>arr[i]; }
En vallen dit soort dingen vaker te verwachten bij meerdere commando's of is deze VLA (variabele lengte array) een uitzondering ?
[ Voor 6% gewijzigd door farlane op 25-01-2019 22:14 ]
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.
Wat C++ zelf betreft zijn er een aantal "versies": 98, 03, 11, 14 en 17. Over het algemeen doen de grote compilerbouwers allemaal wel hun best om zoveel mogelijk van de recentste standaard te implementeren, en zelfs al gedeeltes van de draft van de aankomende standaard (C++20).
VLA's staan echter in geen van die standaarden, zoals farlane ook zegt. Typisch gebruik je in deze situatie gewoon een std::vector<int>
[ Voor 6% gewijzigd door .oisyn op 25-01-2019 23:11 ]
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.
oeps.oisyn schreef op vrijdag 25 januari 2019 @ 23:10:
Die Visual Studio versies die je noemt hebben niets met de C++ standaard te maken, het zijn gewoon de interne versienummers van VS zelf.
de nummers lijken op elkaar, zelfde bereik ongeveer van 10 tot 15.
Ik heb het nog eens nagekeken maar ben ergens in een doolhof beland geloof ik.Wat C++ zelf betreft zijn er een aantal "versies": 98, 03, 11, 14 en 17. Over het algemeen doen de grote compilerbouwers allemaal wel hun best om zoveel mogelijk van de recentste standaard te implementeren, en zelfs al gedeeltes van de draft van de aankomende standaard (C++20).
Heb mijn msvc begin januari op de pc gezet, maar als ik cout << cplusplus; opvraag krijg ik 199711 hetgeen met C98 zou overeenkomen. Zag ook nog dingen over zwitchen tussen versies maar dat durf ik niet.
Ik laat het hier bij en wacht gewoon op de volgende error melding als iets niet compileert.
https://stackoverflow.com...-default-for-a-c-compiler
MSDN: MSVC now correctly reports __cplusplus | Visual C++ Team Blog
farlane schreef op vrijdag 25 januari 2019 @ 22:12:
VLA's zijn geen onderdeel van C++, maar wel C(99). Een van de aspecten van C die niet zijn overgenomen in de C++ standaard. Ze worden wel door de GCC (en misschien andere compilers) als extensie ondersteund in C++
De vector waarmee dit avontuur begonVLA's staan echter in geen van die standaarden, zoals farlane ook zegt. Typisch gebruik je in deze situatie gewoon een std::vector<int>
Heb mij iets verder verdiept in pointers zoals jij aanraadde, met iets van twee uur video's en een paar webs.
Dacht er inmiddels een redelijk begrip van te hebben totdat ik bij dynamisch geheugen aankwam. Ik bedoel niet dat ik helemaal niet weet waar hij het over heeft maar ik raak het pad kwijt door teveel variabelen. Zou eigenlijk alles op papier moeten zetten met adres en inhoud en pointer die wijst van de ene naar de andere. Nadeel is dan wel dat het uren gaat kosten. Soort van animatie zou nog beter zijn, met watch stappen en memory geeft ook niet direkt het hele plaatjes overzicht vind ik, hoewel ik me nog niet laat ontmoedigen. Hieronder staat de code en een link naar de video waar ik het over heb. De code heb ik zonder commentaar regels overgetypt vanuit de video.
Bedankt voor de antwoorden.
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
| // C++ video serie Hank Stalica // video 5 // https://www.youtube.com/watch?v=FpGgXO0a6T4&index=5&list=PLaatXkJEXKyK7-ng1Fo8qOBJ9iqFJFrV_ // TOETS -99 OM PROG TE STOPPEN #include <iostream> using namespace std; int *expand(int*, int, int&); void print(int*, int); int main(){ int *oldarr = 0; int length = 0; int input; do { cout << "Enter an integer : "; cin >> input; oldarr = expand(oldarr, input, length); print(oldarr, length); } while (input != -99); delete[] oldarr; oldarr = 0; cout << endl << endl; system("pause"); return 0;} int *expand(int* oldarr, int newvalue, int& length){ int *newarr = new int[length + 1]; for (int i = 0; i < length; i++) newarr[i] = oldarr[i]; newarr[length] = newvalue; delete[] oldarr; length++; return newarr;} void print(int* arr, int length){ for (int i = 0; i < length; i++) cout << arr[i] << " "; cout << endl; } |
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.
Bedankt Farlane, goeie tip.
Ik volg die hoofdstukjes, ben nu bij Hfdst 3. Program structure 3.1 Statements and flow control.
Pointers is een klein stukje verderop, zie index.
Deze serie bekijk ik ook ... https://www.tutorialspoint.com/cplusplus/cpp_pointers.htm .. hoewel oppervlakkiger, maar soms kom je dan iets tegen wat bij de eerste niet werd vermeld.
Ps/
deze vid is nog iets pittiger als de vorige, meer voor gevorderden en goeie recente kwaliteit video.
en wrs hebben de gevorderden deze zelf al ontdekt.
YouTube: What Are Pointers? (C++)
heb het nog niet nagespeeld maar zag wel handige dingen zoals slepen van watch naar memory.
[ Voor 24% gewijzigd door kitao op 26-01-2019 18:18 . Reden: Ps ]
Op minuut 10:52 kwam ik deze voor mij onbekende notatie tegen :
cout << (int) pointer;
Dit bleek na wat proberen hetzelfde te zijn als cout << pointer; met als enige verschil dat de eerste de waarde in dec geeft en de ander in hex.
Of heeft dit nog andere gevolgen ?
Volgende wat ik me afvroeg is hoe dan het opgeslagen adres in de pointer als oct uit te printen.
Zoeken op cout << (int) pointer gaf nog niet veel resultaat.
Zoeken op cout << oct << pointer gaf o.a. het resultaat dat onderin de code te vinden is (cplusplus reference).
Bij uitvoering van het programma zie ik bij regel 11 echter geen oct getal maar een hex getal verschijnen, vandaar de "????".
Ik veronderstel dat via een omweg het opgeslagen adres in de pointer wel als oct geprint kan worden, door deze bijvoorbeeld op te slaan in een niet-pointer variabele.
Maar vraag me af waarom het niet gewoon direkt kan en 'aparte trucjes' zoals (int)pointer moeten worden toegepast om een dec-getal te krijgen terwijl er zover ik weet geen 'trucje' voor oct is ?
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
| /*Pointers video javidx9 ---- minuut 10:51 https://www.youtube.com/watch?v=iChalAKXffs&t=2s */ #include <iostream> using namespace std; int main() { int SomeArray[10]; int *pointer10 = &SomeArray[10]; cout << "(int)pointer10 = " << (int)pointer10 << endl; cout << "pointer10 = " << pointer10 << endl; cout << "oct << pointer10 = " << oct << pointer10 << " (??????) " << endl << endl << endl; cout << "The difference between (int)pointer10 - pointer10" ; cout << " geeft een error bij compilen" << endl << endl; cout << "The difference between pointer10 - pointer10 = " ; cout << pointer10 - pointer10 << endl << endl; cout << "The difference between (int)pointer10 - (int)pointer10 = "; cout << (int)pointer10 - (int)pointer10 << endl; cout << endl << endl; cout << "Verschil met cout << oct volgens http://www.cplusplus.com/reference/ios/oct/ " << endl << endl; /* http://www.cplusplus.com/reference/ios/oct/ */ int n = 30; cout << "int n = 30" << endl; cout << "dec n geeft : " << dec << n << '\n'; cout << "hex n geeft : " << hex << n << '\n'; cout << "oct n geeft : " << oct << n << '\n'; cout << endl << endl; system("pause"); return 0;} |

Dat heet een cast. Je verandert het type van pointer (int *) naar int. Pointers worden normaliter geformat als hex als je ze uitprint, integers worden geformat als decimaal. Gevolg van de cast is dus dat de pointer een integer wordt, gevolg daarvan is weer de andere formatting.kitao schreef op zondag 27 januari 2019 @ 12:23:
Bovenstaande video inmiddels aan het na-apen.
Op minuut 10:52 kwam ik deze voor mij onbekende notatie tegen :
cout << (int) pointer;
Dit bleek na wat proberen hetzelfde te zijn als cout << pointer; met als enige verschil dat de eerste de waarde in dec geeft en de ander in hex.
Of heeft dit nog andere gevolgen ?
[ Voor 9% gewijzigd door .oisyn op 27-01-2019 14:42 ]
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.
Ik ben het met je eens dat het voor de semantiek beter is om het juiste type (typedef) te gebruiken, maar heeft een int per definitie niet woordbreedte van de architectuur? Al krijg je dan mogelijk negatieve getallen als je het als decimaal afdrukt..oisyn schreef op zondag 27 januari 2019 @ 14:41:
Een ander euvel is dat een pointer mogelijk niet in een int past (typisch in 64 bits applicaties). Een intptr_t is een integer type die gegarandeerd groot genoeg is voor een pointer.
Is een uintptr_t dan niet "beter"?
If money talks then I'm a mime
If time is money then I'm out of time
Op 64 bits Linux en Windows is een int nog steeds 32 bits.
[ Voor 41% gewijzigd door .oisyn op 27-01-2019 16:23 ]
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.
Ik kwam het tegen ja, ca. kwartier later noemde hij dat. Bij gewoon kijken viel het me niet op, pas met nabouwen (dus met video snelheid op 0.75, telkens pauzeren, terugspoelen etc.) hoorde ik dat de (int) een cast is. Later eens kijken of ik met dat trefwoord meer kan vinden.Radiant schreef op zondag 27 januari 2019 @ 14:03:
Dat heet een cast.
Je verandert het type van pointer (int *) naar int. Pointers worden normaliter geformat als hex als je ze uitprint, integers worden geformat als decimaal. Gevolg van de cast is dus dat de pointer een integer wordt, gevolg daarvan is weer de andere formatting.
Nog een handig iets gezien, shift+alt+pijltjestoetsen kun je kolommen in een code blok selecteren.
Vanaf ca. minuut 18 kon ik het niet zo best meer volgen, dat werd echt na-apen. Objects en subobjects en unique-pointers en smart-pointers allemaal nog niet gehad.
Zal die gelijk met cast nog eens opzoeken dan, tnx..oisyn schreef op zondag 27 januari 2019 @ 14:41:
Een ander euvel is dat een pointer mogelijk niet in een int past (typisch in 64 bits applicaties). Een intptr_t is een integer type die gegarandeerd groot genoeg is voor een pointer.
Als je moeite hebt met gewone pointers, dan wacht je best even met smartpointers. Die vereisen immers kennis van copy vs move en ownership van objecten en dat is op dit moment nog wat te ver gegrepen denk ik.kitao schreef op maandag 28 januari 2019 @ 01:55:
Vanaf ca. minuut 18 kon ik het niet zo best meer volgen, dat werd echt na-apen. Objects en subobjects en unique-pointers en smart-pointers allemaal nog niet gehad.
Wat wij doen in de opleiding is eenmaal ze wat met pointers vertrouwd worden om ze enkele datastructuren te laten maken. Meestal is dit een (enkelvoudige of dubbele) gelinkte lijst met een constructor/destructor, voegtoe en verwijder functie. Als je begint met pointers is het wel een tijdje spartelen en vloeken, maar eenmaal het je lukt om in elkaar te steken, heb je wel een goede brok inzicht in pointers en new/delete enzo. Je vind er ook veel over op het internet: maak wel de code echt zelf, het spartelen is hetgeen wat je het meest inzicht gaat geven. Later als je meer van C++ kent, kan je dan de pointers omzetten naar smartpointers ofzo.
Ja bedankt voor het advies, ik noemde het zelf al een video voor gevorderden hoewel dat in het begin vd video er niet op lijkt.MartenBE schreef op maandag 28 januari 2019 @ 18:40:
Als je moeite hebt met gewone pointers, dan wacht je best even met smartpointers. Die vereisen immers kennis van copy vs move en ownership van objecten en dat is op dit moment nog wat te ver gegrepen denk ik.
Wat wij doen in de opleiding is eenmaal ze wat met pointers vertrouwd worden om ze enkele datastructuren te laten maken. Meestal is dit een (enkelvoudige of dubbele) gelinkte lijst met een constructor/destructor, voegtoe en verwijder functie. Als je begint met pointers is het wel een tijdje spartelen en vloeken, maar eenmaal het je lukt om in elkaar te steken, heb je wel een goede brok inzicht in pointers en new/delete enzo. Je vind er ook veel over op het internet: maak wel de code echt zelf, het spartelen is hetgeen wat je het meest inzicht gaat geven. Later als je meer van C++ kent, kan je dan de pointers omzetten naar smartpointers ofzo.
Ben uren bezig geweest met de IDE, kom niet aan programmeren toe zo. Invoegen van header file.
Links e.d. in de codes.
Stap 1. Het maken van een c++ .asm project in visial studio 2017.
01 - Open empty project
02 - Geef het een naam , bijv. Test Header File en klik op ok.
03 - Klik op Project in toolbar (tussen view en debug) en klik Add new item.
04 - Klik op C++ File en geef het een naam , bijv main.cpp en klik op add.
-------- Tot dus ver is alles zoals normaal bij opstarten C++
Voor Masm assembly moet er echter een .asm folder bijgemaakt worden.
05 - Klik op Project in toolbar (tussen view en debug) en klik Add new item.
06 - Klik op C++ File maar geef het nu een naam met .asm aan het eind, bijv asm.asm en klik op add.
07 - In Solution Eplorer rechtsklik op Test Header File
08 - Klik op Build Dependencies - klik op Build Customizations
09 - Vink masm(.targets ....) en klik OK
10 - Op de Toolbar onder Tools en Test, verander x86 naar x64 in het veldje. Ik weet echter niet zeker of dat voldoende is. Heb enige tijd geleden daarin gerommeld en weet niet of dat nu automatisch standaard is geworden. Als het niet voldoende is klik in datzelfde veldje en kies Config. Manager. Bij mij staan die zo :

Alles zou nu moeten werken.
Zet een programmaatje in main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| //; Video 9 - Passing Integers to and from C++ and Assembly // vanaf ca. minuut 09:00 //; https://www.youtube.com/watch?v=0tpOEdxtRkA #include <iostream> #include <conio.h> using namespace std; extern "C" short PassingParameters(short a, short b, short c, short d); int main() { cout << "The function returned : " << PassingParameters(2, 4, 6, 8) << endl; _getch(); return 0; } |
Zet een programmaatje in asm.asm
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
| ; Vid 9 - Passing Integers to and from C++ and Assembly ; https://www.youtube.com/watch?v=0tpOEdxtRkA ; visual studio gebruikt fast call compiling convention ; To return an int use an appriote size of RAX comment /* ; ********************************************************* ; size QWORD DWORD WORD BYTE ; 1st RCX ECX CX CL ; 2nd RDX EDX DX DL ; 3rd R8 R8D R8W R8B ; 4th R9 R9D R9W R9B ; >4 Stack! Stack! Stack! Stack! */ ; ****************************************************************** .data .code PassingParameters proc mov ax, cx add ax, dx add ax, r8w add ax, r9w ret PassingParameters endp end |
11 - klik op run , er moet dan 20 in de window verschijnen.
Althans, dat was voorheen zo. ???????????????????????
Heb een andere video na zitten bouwen, no. 13 (typisch)
YouTube: x64 Assembly and C++ Tutorial 13: Programming a Useful Algorithm Par...
De video duurt 10 minuten maar heeft me uren gekost want er zat ineens een header file bij.
Uieindelijk na veel knopjes drukken en vergelijken met oudere, zonder header.h, wel werkende versies toch aan de praat gekregen. Maar nu zijn ineens ook voor nieuwe masm/c++ -projecten bovenstaande stappen niet meer genoeg want er komt een build error :
Error LNK2019 unresolved external symbol PassingParameters referenced in function main
Error LNK1120 1 unresolved externals Test Header File 1
Er moet nu ineens als extra bij :
12 - Rechtsklik op asm.asm in Sol.Expl. en klik op properties.
13 - Er verschijnt een pop-up, klik op Item Type en klik op Mic.Mac.Assembler en klik op ok.

(klik voor groter)
Nu gaat het wel goed en zal een window met 20 verschijnen.
Stap 2. Het maken van een header in een c++ .asm project in visial studio 2017.
Keer terug naar Stap 1. Begin met een nieuw project.
Doorloop 1 t/m 13, ga verder met 14.
14 - Klik op Project in toolbar (tussen view en debug) en klik Add new item.
15 - Klik op Header File (h) en geef het een naam , bijv ZeroArray.h en klik op add.
17 - klik op Save All in Toolbar.
18 - Plak de codes hieronder erin op de juiste plekken en klik op run, er verschijnen nu 2048 getallen, waarvan de helft 0.
Met een paar lege lijntjes ertussen ... zoals ik mij nu voel.
code voor respectievelijk main.cpp , asm.asm en ZerroArray.h
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
| #include <iostream> // For cout #include <conio.h> // For _getch() #include <stdlib.h> // For rand() #include "ZeroArray.h" // Header for our procedure using namespace std; // extern "C" void ZeroArray(void* arr, int countInBytes); int main() { int count = 1024; char *arr = new char[count]; // Init the array to contain random numbers // so its easy to tell that the procedure has worked for (int i = 0; i < count; i++) arr[i] = (char)rand(); // Print out the initial values for (int j = 0; j < count; j++) cout << (int)arr[j] << " "; // Call the procedure ZeroArray(arr, count * sizeof(char)); // Print out the values again to make sure the're all 0 cout << "\n\n\n\n\n\n\n\n"; for (int j = 0; j < count; j++) cout << (int)arr[j] << " "; _getch(); //Prevent window close delete[] arr; // Free the memory return 0; } |
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
| .code ; void ZeroArray(void* RCX, int EDX) ; Sets all bytes from *RCX to *RCX + EDX to 0 ZeroArray proc cmp edx, 0 ; Check for 0 or less jle Finished cmp edx, 1 ; Check for 1 je SetFinalByte mov ax, 0 ; Set AX to 00 mov r8d, edx ; Save the original count to r8d shr edx, 1 ; Halve the count because we use AX, not AL MainLoop: mov word ptr [rcx], ax ; Set two bytes to 0 add rcx, 2 ; Move RCX to the next two bytes dec edx ; Decrement counter jnz MainLoop ; Jump if more to set and r8d, 1 ; Check for even number jz Finished ; If there was, no byte was skipped SetFinalByte: mov byte ptr [rcx], 0 Finished: ret ZeroArray endp end |
1
2
3
4
5
6
7
8
9
| #ifndef ZEROARRAY_H #define ZEROARRAY_H // Set countInBytes to 0 starting from &arr and // moving to &arr + countInBytes extern "C" void ZeroArray(void* arr, int countInBytes); #endif |
Hopleijk kan de geïnteresseerde hier nog wijs uit (mits ik alsnog geen fouten bij het kopieeren heb gemaakt naar deze post. Maar dat was dus allemaal nodig om c++ gecombineerd met masm en een header file in actie te kunnen krijgen. Echt gebruiksvriendelijk kan ik het niet noemen, tenzij iemand mij mss kan wijzen op welke overbodige stappen ik evt. gemaakt heb ? En is het zo dat (bepaalde, niet alle) settings wijzigingen voor het ene project meteen erin gebakken blijven staan voor de volgende ? Want de mic.mac.assembler hoefde ik voorheen niet te selecteren en in het x84, x64 config manager veldje stond volgens mij eerst ook ARM maar heb die daarna nooit meer terug gezien.
Nog iets, heb inmiddels ook een asm. text highlighter programma erin staan, dat heet AsmDude.
YouTube: How to get Assembly Syntax Highlighting in Visual Studios
Is wel een verbetering maar soms ook wel hinderlijk als ieder woord oplicht.
[ Voor 1% gewijzigd door kitao op 30-01-2019 15:42 . Reden: Afbeelding naar thumbnail omgezet. ]
http://www.cplusplus.com/doc/tutorial/functions/
Vind het lastig te begrijpen wat er gebeurt en heb hier iets meer duidelijkheid gekregen :
https://beginnersbook.com/2017/08/cpp-recursion/
Ik heb de code uit cplusplus intact gelaten maar er enkele cout regels bijgezet om het beter in beeld te krijgen.
Overig commentaar staat in de 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
| // factorial calculator #include <iostream> using namespace std; long x = 6; // zet deze gelijk aan 'number' in main op regel 38. long factorial(long a) { if (a > 1) { cout << "a = " << a << endl; cout << "a - 1 = " << a - 1 << endl; x = x * (a - 1); // oftewel, number = number * (number -1) cout << "x = x * (a-1) = " << x << endl << endl; return (a * factorial(a - 1)); cout << " jump uit return 1 " << endl; // Deze wordt niet uitgeprint !!! } else { // zet op de regel hieronder een breakpoint cout << endl << endl << "a in Else = " << a << endl << endl; return 1; // Return 1 verspringt naar de accolade op regel 34 // Daarna wordt er (number-1) aantal keren versprongen tussen // de return op regel 16 en de accolade op regel 34. // Vragen : // 1. Hoe weet hij hoeveel keer hij moet verspringen ????? // 2. Waar kan ik een cout regel zetten om het aantal 'jumps' te tellen ???? // 3. En waar worden de tussenresultaten van 6x5, 6x5x4 ... etc. opgeslagen ??? } } int main() { long number = 6; // zet deze gelijk aan 'x' op regel 5. cout << "De faculteit van " << number << " = " << factorial(number); cout << endl << endl; system("pause"); return 0; } |
// Return 1 verspringt naar de accolade op regel 34
// Daarna wordt er (number-1) aantal keren versprongen tussen
// de return op regel 16 en de accolade op regel 34.
// Vragen :
// 1. Hoe weet hij hoeveel keer hij moet verspringen ?????
// 2. Waar kan ik een cout regel zetten om het aantal 'jumps' te tellen ????
// 3. En waar worden de tussenresultaten van 6x5, 6x5x4 ... etc. opgeslagen ???
Heb de cout op regel 17 geprobeerd op enkele plekken neer te zetten zodat die wel uitgeprint gaat worden en dus als tellertje kan gaan dienen van het aantal jumps zodra return 1 is gepasseerd. Maar dat is me nog niet gelukt.
Hoe kan ik wel het aantal jumps weergeven nadat return 1 is gepasseerd ?
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 suggestieJMaster 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).
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 ]
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.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.
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 ]
[ 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.
nee, nog niet naar gekeken, goeie tip..oisyn schreef op donderdag 31 januari 2019 @ 09:11:
Hou je de call stack window wel in de gaten?
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.
Heb inmiddels de call-stacks erbij gezet en dat hielp goed, tnx..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.
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.
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

Geraadpleegde video
YouTube: Illustrated Assembly Language Recursion
[ Voor 1% gewijzigd door kitao op 31-01-2019 21:30 . Reden: typo ]
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.
[ 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.
Nogmaals bedankt.oisyn schreef op vrijdag 15 februari 2019 @ 16:05:
Ik heb de masm posts even verplaatst naar een apart topic: [MASM] Beginnersvraag(en)
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.
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 ]
Ok, bedanktMijzelf 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.
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 ]
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.
ik geloof dat ik enigzins begrijp wat je bedoelt..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.
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/
Een functiepointer is de essentie van een (runtime variabele) callback dus het is (in tegenstelling tot assembly
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.
Bedankt voor de waarschuwing om dit niet zomaar over te slaan.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) wat mij betreft een must have skill om er mee om te kunnen gaan.
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 ]
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.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/
Stel je heb de volgende code:
1
2
| char const * a = "hello, world!"; char * b = (char *) a; |
[ Voor 3% gewijzigd door ThomasG op 18-02-2019 10:45 ]
Welke compiler heeft daar opties voor, dan?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)
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.
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..oisyn schreef op maandag 18 februari 2019 @ 11:27:
[...]
Welke compiler heeft daar opties voor, dan?
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 onderaanIs 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.
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)
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; } |
[ 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.
Tnx .oisyn, jouw puntje 1 maakt al veel meer duidelijk over mijn vraag 2..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.
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.
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.
Kan je het plaatje zien ?.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?
Anders zet ik hem hier
En ja sorry, je hebt gelijk, moet nog thuis worden in de terminologie, het is de editor.

- 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.

.
&subtraction gepind = ....26D0
&subtraction cout = ....13DE
pointer *minus wijst naar ....13DE
.
[ Voor 23% gewijzigd door kitao op 18-02-2019 21:14 ]
[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.
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.
Dat was mij vaag ook al opgevallen die offset, ik neem aan dat je dit bedoelt :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.
- plaatje 1 : &subtraction gepind = 010526D0
- plaatje 1 : &subtraction cout ... = 010513DE
na verversing ..
- plaatje 2 : &subtraction gepind = 00A426D0
- plaatje 2 : &subtraction cout ... = 00A413DE
Het klopt inderdaad dat in 'run mode' , en trouwens ook in 'debug mode', sowieso de uitkomst hetzelfde blijft, namelijk 20 - 14 = 6..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
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\ ]
Base address randomizationfarlane 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.
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.

Origineel :
https://www.tutorialspoin.../cpp_copy_constructor.htm
Zelfde maar dan gecomprimeerd en voorzien van blok nummers in de comments
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 ]
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.
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.
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.
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.
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.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
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.
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.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.
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.
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.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.
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.
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)[]
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.
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 meeThomasG 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)
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)



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 ]
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.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 ....
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.
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.
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 :
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 :

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 ?
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'.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.
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 :

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.
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.
Bedankt voor de toelichting farlane,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.
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.

[ Voor 26% gewijzigd door kitao op 05-03-2019 15:10 ]
Ja nogmaals bedankt, ben inmiddels halverwege hfdst 3.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.
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'
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 ]
Die bende die je post kan met een beetje formatting heel wat leesbaarder worden:
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.
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.
Het gaat vooral om de indenting en wat witregels hier en daar, daar gaat code=c++ je niet bij helpenkitao 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.
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.