Hier haal ik gcc 4.7.1 ( http://www.equation.com/servlet/equation.cmd?fa=fortran )quote:Op zondag 12 augustus 2012 14:42 schreef thenxero het volgende:
[..]
Dat is misschien het beste, misschien heb ik dat in de toekomst ook nog voor andere dingen nodig. Hoe installeer die nieuwe gcc?
Bedankt. Heb dit nu gedaan. Volgens mij werkt hij goed (heb het getest op mijn eigen oude bestanden), alleen als ik de class/header van GS42 wil gebruiken dan krijg ik:quote:Op zondag 12 augustus 2012 15:39 schreef ari_zahav het volgende:
[..]
Hier haal ik gcc 4.7.1 ( http://www.equation.com/servlet/equation.cmd?fa=fortran )
En dan in Code::Blocks:
Settings -> Compiler and debugger settings
Ik copy dan meestal de oude gcc
En dan in "Toolchain executables" gooi ik de nieuwe compiler install dir erin
En vergeet niet om de nieuwe compiler profile de default te maken.
Gefixt, het werkt nuquote:Op zondag 12 augustus 2012 16:23 schreef ari_zahav het volgende:
Geen idee wat dat zou kunnen zijn. Ik zou de error even googlen als ik jou was
Moest gewoon nog een path aanpassen naar de goede compilerquote:
Je kan het ook niet zo vergelijken, want er zit ook nog allerlei code van mezelf omheen om die dingen in te lezen. Kan best zijn dat het daar vandaan komt.quote:Op zondag 12 augustus 2012 17:04 schreef t4rt4rus het volgende:
Met GMP duurt het 0.003s om op te lossen.
Ik snap de vraag niet eens want ze zeggen niet hoe je de elementen moet permuterenquote:Op zondag 12 augustus 2012 18:06 schreef t4rt4rus het volgende:
Nu opdracht 24 doen zonder programmeren, moet lukken.
edit:
het werkt niet echt...
a b c d e f g h i j
10! mogelijkheden om dit te sorteren
Als plek 1 vast staat zijn er nog 9! mogelijkheden om te sorteren, etc.
De miljoenste permutatie is dan
k * 3628800 + l * 362880 + m * 40320 + n * 5040 + o * 720 + p * 120 + q * 24 + r * 6 + s * 2 + t * 1
waarin k het k'ste element is uit de gesorteerde set van getallen 10 getallen;
waarin l het l'ste element is uit de gesorteerde set van de overgebleven 9 getallen;
etc.
Of heb ik dit fout?
Staat er toch gewoon?quote:Op zondag 12 augustus 2012 18:57 schreef thenxero het volgende:
[..]
Ik snap de vraag niet eens want ze zeggen niet hoe je de elementen moet permuteren
quote:If all of the permutations are listed numerically or alphabetically, we call it lexicographic order.
What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?
Na wat gegoogle begrijp ik dat je ze moet sorteren op grootte, maar dat haal ik niet echt uit de vraagquote:
Het staat er gewoon...quote:Op zondag 12 augustus 2012 19:03 schreef thenxero het volgende:
[..]
Na wat gegoogle begrijp ik dat je ze moet sorteren op grootte, maar dat haal ik niet echt uit de vraag
edit:quote:If all of the permutations are listed numerically or alphabetically, we call it lexicographic order.
quote:The lexicographic permutations of 0, 1 and 2 are:
012 021 102 120 201 210
Ja, list numerically lees ik gewoon als numerieke waarden in een lijst zetten. Maar dat kan ook aan mij liggen.quote:Op zondag 12 augustus 2012 19:33 schreef t4rt4rus het volgende:
[..]
Het staat er gewoon...
[..]
edit:
En zelf nog een voorbeeld
[..]
quote:Op zondag 12 augustus 2012 18:06 schreef t4rt4rus het volgende:
Nu opdracht 24 doen zonder programmeren, moet lukken.
edit:
het werkt niet echt...
a b c d e f g h i j
10! mogelijkheden om dit te sorteren
Als plek 1 vast staat zijn er nog 9! mogelijkheden om te sorteren, etc.
De miljoenste permutatie is dan
k * 10! + l * 9! + m * 8! + n * 7! + o * 6! + p * 5! + q * 4! + r * 3! + s * 2! + t * 1!
waarin k het k'ste element is uit de gesorteerde set van getallen 10 getallen;
waarin l het l'ste element is uit de gesorteerde set van de overgebleven 9 getallen;
etc.
Of heb ik dit fout?
Nee list numerically is numeriek sorteren dus op grootte.quote:Op zondag 12 augustus 2012 19:43 schreef thenxero het volgende:
[..]
Ja, list numerically lees ik gewoon als numerieke waarden in een lijst zetten. Maar dat kan ook aan mij liggen.
Je kan wel eens gelijk hebben jaquote:
Volgens mij klopt dat wel
Je idee klopt wel maar volgens mij moet je met 9! beginnen... dus k * 9! + ... etc
1 | 1M = k*9! + l*8! + m*7! + n*6! + o*5! + p*4! + q*3! + r*2! + s*1! |
1 | 1M = 2*9! + 6*8! + 6*7! + 2*6! + 5*5! + 1*4! + 2*3! + 2*2! + 0*1! |
1 | 999999 = k*9! + l*8! + m*7! + n*6! + o*5! + p*4! + q*3! + r*2! + s*1! |
Ik zag het ja. Omdat je niet het aantal permutaties telt, maar het aantal keer dat je de originele permutatie gepermuteerd hebt. Samen met mijn vorige opmerking kom je goed uit.quote:Op zondag 12 augustus 2012 20:49 schreef t4rt4rus het volgende:
wacht eens even,
0 is de eerste permutatie...
Dus we moeten dit oplossen:
[ code verwijderd ]
En dan kom je wel op de goede uit.
We tellen wel het aantal permutatiesquote:Op zondag 12 augustus 2012 20:54 schreef thenxero het volgende:
[..]
Ik zag het ja. Omdat je niet het aantal permutaties telt, maar het aantal keer dat je de originele permutatie gepermuteerd hebt. Samen met mijn vorige opmerking kom je goed uit.
Ha, dank je. Natuurlijk was het ook niet overdreven moeilijk om verbeteringen aan te brengen.quote:Op zondag 12 augustus 2012 15:31 schreef t4rt4rus het volgende:
w00t OP is al een stuk beter, goed gedaan GS42!
Ik kijk later zelf wel even wat we kunnen toevoegen.
Daar kan je best gelijk in hebben. Ik moest kiezen tussen snelle in- en output of snel rekenen. Hier heb ik dus voor gekozen.quote:Op zondag 12 augustus 2012 17:01 schreef thenxero het volgende:
PE 13 eindelijk opgelost. Vreemd genoeg duurde het 1sec om één Unlimited Int te lezen en te printen, dus ik had niet veel vertrouwen in de snelheid. Maar die 50 getallen bij elkaar optellen ging ook in ongeveer 1 sec, dus dat viel wel mee
Ik heb ook geen schijn van kans tegen GMP.quote:Op zondag 12 augustus 2012 17:04 schreef t4rt4rus het volgende:
Met GMP duurt het 0.003s om op te lossen.
Als je dat in C++ wilt doen, gaat dat trouwens heel mooi met std::next_permuation. Die produceert permutaties in oplopende volgorde. Opgave 24 kan je zo in 3 (korte) regels code doen.quote:Op zondag 12 augustus 2012 19:03 schreef thenxero het volgende:
Na wat gegoogle begrijp ik dat je ze moet sorteren op grootte, maar dat haal ik niet echt uit de vraag
Blij dat het nu goed werkt. Dit is precies het soort doel dat ik voor ogen had: grote getallen en gebruiksgemak waar geen extreme snelheid nodig is. Dank je wel voor het testen.quote:Op zondag 12 augustus 2012 21:23 schreef thenxero het volgende:
Precies. Heb nu ook met de class van GS42 opgave 20 opgelost. In 0.2 seconde dus ik vind die klasse erg goed werken.
Ja, erg bedankt voor deze gebruiksvriendelijke classquote:Op zondag 12 augustus 2012 23:40 schreef GS42 het volgende:
Blij dat het nu goed werkt. Dit is precies het soort doel dat ik voor ogen had: grote getallen en gebruiksgemak waar geen extreme snelheid nodig is. Dank je wel voor het testen.
SPOILEROm spoilers te kunnen lezen moet je zijn ingelogd. Je moet je daarvoor eerst gratis Registreren. Ook kun je spoilers niet lezen als je een ban hebt.
1 | Unlimited::Int k("10000000"); |
Ik krijg vreemd genoeg geen compiler waarschuwing. Als naïeve newb dacht ik dat je bij Unlimited::int een ongelimiteerde integer kon initialiseren. Bedankt!quote:Op maandag 13 augustus 2012 00:45 schreef GS42 het volgende:
Hierboven staat zowel de oorzaak als de oplossing.C++ kan niet zulke grote getallen verwerken (vandaar de problemen om met grote getallen te rekenen) en daarom moeten zulke getallen in string-vorm aangeleverd worden.
[ code verwijderd ]
Initialiseert k vanuit een string.
Trouwens: je zou ook een compiler-waarschuwing moeten krijgen als je jouw code probeert te compileren. Iets als "integer constant too large for its type" ofzo. Een compiler-waarschuwing is vrijwel altijd een waarschuwing dat er iets niet helemaal klopt in de code en moet dus weggewerkt worden.
Morgen Vandaag ben ik hopelijk ook zo ver.quote:Op maandag 13 augustus 2012 02:44 schreef kutkloon7 het volgende:
tvp voor ProjectEuler. Ik heb de eerste 26 al/opschepmodus
Gebruik `-Wall -Wextra'.quote:Op maandag 13 augustus 2012 01:27 schreef thenxero het volgende:
[..]
Ik krijg vreemd genoeg geen compiler waarschuwing. Als naïeve newb dacht ik dat je bij Unlimited::int een ongelimiteerde integer kon initialiseren. Bedankt!
Opzich geen rare gedachte.quote:Op maandag 13 augustus 2012 01:27 schreef thenxero het volgende:
Als naïeve newb dacht ik dat je bij Unlimited::int een ongelimiteerde integer kon initialiseren. Bedankt!
Ik heb het trouwens opgelost door het te initialiseren als een klein getal, en dan met een loop steeds keer 10 doen totdat je genoeg nullen hebt. Dat werkt wel gewoon.quote:Op maandag 13 augustus 2012 12:20 schreef GS42 het volgende:
[..]
Opzich geen rare gedachte.Goede tip, ik zal het wel ergens in de documentatie opnemen.
Ook een prima oplossing natuurlijk. Iets als Int x(10); x.pow(999); geeft je ook het juiste getal.quote:Op maandag 13 augustus 2012 13:19 schreef thenxero het volgende:
Ik heb het trouwens opgelost door het te initialiseren als een klein getal, en dan met een loop steeds keer 10 doen totdat je genoeg nullen hebt. Dat werkt wel gewoon.
Goed idee, ik zie dat je dat inmiddels al gedaan hebtquote:Op maandag 13 augustus 2012 03:00 schreef thenxero het volgende:
[..]
Morgen Vandaag ben ik hopelijk ook zo ver.
Misschien moeten we maar een apart PE draadje maken(?)
1 2 3 4 5 6 7 | int a,b,c; a=1; b=2; c=b; b=a; a=c; |
Die truc die jij postte of die const?quote:Op donderdag 16 augustus 2012 21:43 schreef thabit het volgende:
Dit soort truuks lijken me niet hetgene om wakker van te liggen overigens. Vaak zitten ze al in std geoptimaliseerd, en anders wordt je code er alleen maar onleesbaarder van.
Ik doelde op de truc die ik zelf postte; const is wel goed om aan te leren.quote:Op donderdag 16 augustus 2012 22:09 schreef thenxero het volgende:
[..]
Die truc die jij postte of die const?
Nog een andere vraag trouwens: hoe kan je het beste goede random getallen produceren in C++? De snelheid van de methode is ook erg belangrijk. Met srand en rand krijg ik getallen die niet zo random lijken.
/dev/random ...quote:Op donderdag 16 augustus 2012 22:09 schreef thenxero het volgende:
[..]
Die truc die jij postte of die const?
Nog een andere vraag trouwens: hoe kan je het beste goede random getallen produceren in C++? De snelheid van de methode is ook erg belangrijk. Met srand en rand krijg ik getallen die niet zo random lijken.
xchg rax, rbxquote:Op donderdag 16 augustus 2012 20:54 schreef thenxero het volgende:
Is er een handige manier om twee waardes om te wisselen in C++ zonder dat je een derde variable aanmaakt? Bijvoorbeeld: Stel dat a=1, en b=2. Dan wil ik dat a=2 en b=1. Nu zou ik dat doen met zoiets als:
[ code verwijderd ]
Maar dan heb je dus extra geheugen nodig voor die c, en ik vroeg me dus af of dat ook beter kan.
Is niet altijd random in de zin dat het standaard statistische tests doorstaat, en wat erger is (vanuit wetenschappelijk oogpunt) is dat de gegenereerde nummers niet reproduceerbaar zijn (ook al haalt hij op gegeven moment wel een statistische test, het heeft geen betekenis).quote:
xchg is typisch langzamer dan gewone moves/stores. Het is schijnbaar handig om semaforen te implementeren (geen ervaring mee), maar anders spaart het wederom 1 register uit in ruil voor meer cycles voor de swap; i.e. geheugen vs snelheid, de aloude tradeoff.quote:Op vrijdag 17 augustus 2012 00:46 schreef t4rt4rus het volgende:
[..]
/dev/random is random nummer generator in linux.
xchg rax, rdx is swappen tussen rax en rbx.
Ik heb er even mee zitten kloten, maar het is toch wel een heel gedoe om dit in C++ voor elkaar te krijgen. Toen zag ik opeens dat er prima random integer generators op internet zijn. Ik genereer daar in een mum van tijd 100,000 random ints. Die plak ik in een textbestandje en lees ik dan in C++ in een array. So far so good, maar als ik bij element 20,096 van mijn array kom, dan loopt mijn programma vast.quote:Op donderdag 16 augustus 2012 22:19 schreef thabit het volgende:
[..]
Goed random getallen produceren, dat is een vakgebied op zich. Ik zou vooral googlen naar wat mensen ermee gedaan hebben.
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 | void ReadInts(int randint[]) { char *inname = "random2.txt"; //contains random numbers 0 - 9999 ifstream infile(inname); if (!infile) { cout << "There was a problem opening file " << inname << " for reading." << endl; } else cout << "Opened " << inname << " for reading." << endl; int k=0; randint[30000]; string value; int result; while ( infile.good() ) { getline ( infile, value, ',' ); result=0; stringstream convert(value); if ( !(convert >> result) ) { result = 0; } randint[k]=result; cout << "k = " << k << " en random number = " << result << endl; ++k; } } |
Misschien een beetje laat, maar over het algemeen is rand() een prima bron voor random getallen en alleen in geval van beveiliging kan ik me voorstellen dat je een betere random number generator wilt gebruiken.quote:Nog een andere vraag trouwens: hoe kan je het beste goede random getallen produceren in C++? De snelheid van de methode is ook erg belangrijk. Met srand en rand krijg ik getallen die niet zo random lijken.
Meneer zit op Windows...quote:Op zondag 19 augustus 2012 12:14 schreef trancethrust het volgende:
GSL is doorgaans wat makkelijker in gebruik.
Ik heb het nodig voor statistische technieken in de wiskunde, waarbij ik heel snel achter elkaar random numbers wil genereren die niet van elkaar afhankelijk zijn. Dat lukte me niet met srand met de tijd als seed als ik het heel snel achter elkaar deed. Ik zag iedere keer ongeveer hetzelfde patroon erin zitten. Op google vond ik ook dat je voor serieuze taken beter iets anders gebruikt.quote:Op zondag 19 augustus 2012 15:04 schreef GS42 het volgende:
[..]
Misschien een beetje laat, maar over het algemeen is rand() een prima bron voor random getallen en alleen in geval van beveiliging kan ik me voorstellen dat je een betere random number generator wilt gebruiken.
Waarom heb je het idee dat de de getallen "niet zo random lijken"? En waarvoor wil je het gebruiken?
Dan wordt het ook moeilijker dan noodzakelijk.quote:
Dat komt omdat (zelfs al gebruikt je installatie een betere RNG dan de twee die ik hierboven als voorbeeld aanhaalde), doordat rand() doorgaans een linear congruential RNG (LC-RNG) is. Als ik een gok doe dan ben je bezig met monte-carlo methoden, en voor zulke punt-gebaseerde methodes kun je bewijzen dat voor elke LC-RNG altijd een dimensie d is waarvoor de gegenereerde punten rond vlakken in die d-dimensionale ruimte clusteren.quote:Op maandag 20 augustus 2012 11:56 schreef thenxero het volgende:
[..]
Ik heb het nodig voor statistische technieken in de wiskunde, waarbij ik heel snel achter elkaar random numbers wil genereren die niet van elkaar afhankelijk zijn.
...
Je gebruikt srand() toch wel maar 1 keer he? Als je rand() gebruikt in je programma, roep je maar 1 enkele keer srand() aan, als eerste statement in je main(); op een andere plek of vaker is fout.quote:Op maandag 20 augustus 2012 11:56 schreef thenxero het volgende:
[..]
Ik heb het nodig voor statistische technieken in de wiskunde, waarbij ik heel snel achter elkaar random numbers wil genereren die niet van elkaar afhankelijk zijn. Dat lukte me niet met srand met de tijd als seed als ik het heel snel achter elkaar deed. Ik zag iedere keer ongeveer hetzelfde patroon erin zitten. Op google vond ik ook dat je voor serieuze taken beter iets anders gebruikt.
ik zou sowieso zo vaak mogelijk de std functies gebruiken ipv. zelf maken of uit externe libs halenquote:Op maandag 20 augustus 2012 12:59 schreef GS42 het volgende:
[..]
Je gebruikt srand() toch wel maar 1 keer he? Als je rand() gebruikt in je programma, roep je maar 1 enkele keer srand() aan, als eerste statement in je main(); op een andere plek of vaker is fout.
Verder klopt het dat je voor serieuze taken beter een aparte library kan gebruiken, maar dan moet je wel erg serieus zijn.Ik heb bijvoorbeeld voor mijn bachelorscriptie - een implementatie van een monte-carlo (= statistische classificatie) zoekalgoritme - gewoon de rand() gebruikt zonder problemen.
1 2 3 4 5 6 7 8 9 | 2 2 3 3 4 2 2 5 5 6 2 3 7 7 8 2 2 2 9 3 3 10 2 5 |
Waarom geen vector gebruiken?quote:Op zondag 26 augustus 2012 11:33 schreef thenxero het volgende:
Ik heb een txt-bestandje gemaakt waarbij getallen links staan en rechts hun priemfactoren, gescheiden door witte ruimte. Het ziet er dus uit als volgt:
[ code verwijderd ]
etcetera.
Nu wil ik dit bestandje lezen en in een array zetten. Maar omdat iedere regel een andere lengte kan hebben, weet ik niet hoe ik dat moet doen. Iemand een idee?
Gaat het om het inlezen of om het opslaan? De oplossing voor het tweede is al gegeven door thabit: gewoon een vector gebruiken in plaats van een array. Het inlezen zou ik als volgt doen:quote:Op zondag 26 augustus 2012 11:33 schreef thenxero het volgende:
Ik heb een txt-bestandje gemaakt waarbij getallen links staan en rechts hun priemfactoren, gescheiden door witte ruimte. Het ziet er dus uit als volgt:
[ code verwijderd ]
etcetera.
Nu wil ik dit bestandje lezen en in een array zetten. Maar omdat iedere regel een andere lengte kan hebben, weet ik niet hoe ik dat moet doen. Iemand een idee?
Ik zou std::getline gebruiken en niet std::basic_istream::getline.quote:Op zondag 26 augustus 2012 12:06 schreef GS42 het volgende:
[..]
Gaat het om het inlezen of om het opslaan? De oplossing voor het tweede is al gegeven door thabit: gewoon een vector gebruiken in plaats van een array. Het inlezen zou ik als volgt doen:
Het bestand per regel inlezen met getline (díe getline, er is ook een andere). Per regel stop je dan de string die je hebt gelezen in een std::istringstream. Uit de stringstream kan je daarna getallen halen met operator>>.
Dan zijn we het eens: jouw getline is dezelfde als de mijne.quote:Op zondag 26 augustus 2012 13:03 schreef t4rt4rus het volgende:
[..]
Ik zou std::getline gebruiken en niet std::basic_istream::getline.
http://en.cppreference.com/w/cpp/string/basic_string/getline
Als ik op die link van je klik kom ik toch ergens anders uit.quote:Op zondag 26 augustus 2012 13:06 schreef GS42 het volgende:
[..]
Dan zijn we het eens: jouw getline is dezelfde als de mijne.
quote:Op zondag 26 augustus 2012 13:20 schreef thenxero het volgende:
De reden dat ik het met een array wilde doen is omdat ik dezelfde 'layout' wil als in dat textbestand: een 2-dimensionaal ding. Met vector heb je altijd 1 dimensie voor zover ik weet.
1 | std::vector< std::vector<unsigned> > |
Jahoor, vrijwel alles kan in een vector. Uit mijn hoofd is alleen een (non-throwing) copy constructor vereist.quote:Op zondag 26 augustus 2012 13:32 schreef thenxero het volgende:
Oh okay, vector in vector kan ik wel proberen (wist niet dat dat kon).
Het probleem wat ik nog heb is dat je met getline een string krijgt die de hele regel bevat. Ik weet wel dat ik met string_naam[x] toegang krijg tot element x, maar hoe scheidt ik het best alle integers?
Had je problemen met de istringstream methode? Volgens mij vraag je namelijk naar bovenstaande, maar misschien was ik onduidelijk of snap ik je vraag niet.quote:Op zondag 26 augustus 2012 12:06 schreef GS42 het volgende:
[..]
Het bestand per regel inlezen met getline (díe getline, er is ook een andere). Per regel stop je dan de string die je hebt gelezen in een std::istringstream. Uit de stringstream kan je daarna getallen halen met operator>>.
Ja klopt, ik weet niet hoe dat werkt. Een korte voorbeeldcode zou wel fijn zijn.quote:Op zondag 26 augustus 2012 13:40 schreef GS42 het volgende:
[..]
Had je problemen met de istringstream methode? Volgens mij vraag je namelijk naar bovenstaande, maar misschien was ik onduidelijk of snap ik je vraag niet.
Nou, okay dan.quote:Op zondag 26 augustus 2012 13:46 schreef thenxero het volgende:
[..]
Ja klopt, ik weet niet hoe dat werkt. Een korte voorbeeldcode zou wel fijn zijn.
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 | #include <iostream> #include <string> // for std::string, std::getline #include <fstream> // for std::ifstream #include <sstream> // for std::istringstream int main() { // open file std::ifstream file("input.txt"); // read file per line std::string line; while (std::getline(file, line)) { // now [line] contains a line from input.txt // create istringstream filled with [line] std::istringstream iss(line); // extract all numbers from [iss] unsigned temp; while (iss >> temp) std::cout << temp << ' '; std::cout << '\n'; } } |
In de OP (hebben jullie 'em al wat uitgebreid?) staat onder andere een link naar de C++ Annotations. Volgens mij is deze pagina wel nuttig. Het is geen simpele pagina, maar dan heb je wel gelijk het volledige overzicht.quote:Op zondag 26 augustus 2012 14:07 schreef thenxero het volgende:
Bedankt! Weet je misschien een site waar dit allemaal helder uitgelegd wordt? Er zijn zoveel dingen... istream ifstream ofstream ostream getline cin cout << >> stringstream dat ik de bomen door het bos niet meer zie.
'unsigned' is hetzelfde als 'unsigned int'quote:En wat betekent 'unsigned temp' precies? Ik weet wel dat je unsigned kan gebruiken in combinatie met int, bijvoorbeeld 'unsigned int'. Maar wat als er geen type na unsigned komt?
1 | std::ostream& operator<<(std::ostream&, const C&); |
Wat ziet er verschrikkelijk uit?quote:Op zondag 26 augustus 2012 14:22 schreef thenxero het volgende:
Het ziet er verschrikkelijk uit, maar dat zal ik maar eens gaan doorlezen dan.
Die pagina met alle streams en zo. Ik vind het in het algemeen leuk om C++ te leren, maar daar zie ik tegenop. Noodzakelijk kwaad.quote:
Het is toch overzichtelijk?quote:Op zondag 26 augustus 2012 14:46 schreef thenxero het volgende:
[..]
Die pagina met alle streams en zo. Ik vind het in het algemeen leuk om C++ te leren, maar daar zie ik tegenop. Noodzakelijk kwaad.
Ja, het is ook waar ik naar op zoek was. To the point en overzichtelijk. En er zijn ook plaatjesquote:Op zondag 26 augustus 2012 14:47 schreef t4rt4rus het volgende:
[..]
Het is toch overzichtelijk?
Wil je alles in kleurtjes en plaatjes ofzo...?
Ik vind het een vreselijke pagina. Het staat vol met grijze informatie, tekst en voorbeeldcode staat door elkaar en het document is gigantisch. Daarnaast worden hoofd- en bijzaken niet goed gescheiden waardoor je snel in de details van error- of formatting flags zit te kijken terwijl dit niet erg belangrijk is om te kunnen werken met streams.quote:Op zondag 26 augustus 2012 14:47 schreef t4rt4rus het volgende:
[..]
Het is toch overzichtelijk?
Wil je alles in kleurtjes en plaatjes ofzo...?
Gelukkig ligt het niet aan mijquote:Op zondag 26 augustus 2012 14:57 schreef GS42 het volgende:
[..]
Ik vind het een vreselijke pagina. Het staat vol met grijze informatie, tekst en voorbeeldcode staat door elkaar en het document is gigantisch. Daarnaast worden hoofd- en bijzaken niet goed gescheiden waardoor je snel in de details van error- of formatting flags zit te kijken terwijl dit niet erg belangrijk is om te kunnen werken met streams.
Maar de informatie op zich is goed en de moeite waard om er doorheen te bijten. Ik kan me alleen prima voorstellen dat 9 op de 10 mensen er niet aan beginnen. Het is een gedetailleerd overzicht, geen tutorial.
Het is inderdaad meer een documentatie.quote:Op zondag 26 augustus 2012 14:57 schreef GS42 het volgende:
[..]
Maar de informatie op zich is goed en de moeite waard om er doorheen te bijten. Ik kan me alleen prima voorstellen dat 9 op de 10 mensen er niet aan beginnen. Het is een gedetailleerd overzicht, geen tutorial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include<stdio.h> #include <conio.h> int main(void) { float getal, som=0, gemiddelde; int teller=0; printf("Voer 10 getallen in (sluit af met een negatief getal) -> "); scanf("%f",&getal); while(getal > 0) { som+=getal; scanf("%f",&getal); teller++; } gemiddelde = som / teller; printf("Het gemiddelde van de %d getallen is = %.2f",teller,gemiddelde); getchar(); getchar(); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 | #include<stdio.h> #include <conio.h> int main(void) { float getallen; printf("voer getallen in"); scanf("%d", getallen); getchar(); getchar(); return 0; } |
Dit moet je eerst naar een float (of double) casten, anders voert-ie een integer deling uit en dat is gewoon afgerond naar beneden.quote:Op zaterdag 8 september 2012 15:41 schreef dfdsdfds het volgende:
gemiddelde = (1 + 9 + 8 + 5 + 1 + 1 +1 + 1)/(1+1+1+1) = Ik kom er niet uit. Iemand die me kan helpen?
Een float is 1 enkel getal, en geen reeks getallen. Je moet de getallen in een array (of beter: een vector) van floats stoppen.quote:Op zaterdag 8 september 2012 15:41 schreef dfdsdfds het volgende:
De float bestaat uit een reeks getallen, bv: 6 7 8 1. Ik kan hem getal voor getal in laten lezen, maar ik moet ieder getal een benaming geven voor deze opdracht. Kan iemand me verder helpen?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include<stdio.h> #include <conio.h> int main(void) { int r = 0; int a = 0; char v_naam[25]; printf("Voer uw voornaam in -> "); scanf("%s", &v_naam); for (a=1; a<21; a++) { printf("%s\t", v_naam); if (a % 5 == 0) { printf("\n"); } } getchar(); getchar(); return 0; } |
1 | if (a % 5 == 0) |
1 | if (5 % 5 == 0) |
Waarom staat er dan maar een keer %f als ik 5 6 4 3 invoer? Dan wordt er toch 5 6 4 3 in de float gestopt en word de float getal voor getal verwerkt?quote:Op zaterdag 8 september 2012 15:55 schreef thabit het volgende:
[..]
Een float is 1 enkel getal, en geen reeks getallen. Je moet de getallen in een array (of beter: een vector) van floats stoppen.
1 2 3 4 5 6 7 8 9 | printf("Voer 10 getallen in (sluit af met een negatief getal) -> "); scanf("%f",&getal); while(getal > 0) { som+=getal; scanf("%f",&getal); teller++; } gemiddelde = som / teller; |
Ik weet niet precies hoe scanf werkt, je kan beter de functionaliteit uit iostream gebruiken.quote:Op zaterdag 8 september 2012 16:03 schreef dfdsdfds het volgende:
[..]
Waarom staat er dan maar een keer %f als ik 5 6 4 3 invoer? Dan wordt er toch 5 6 4 3 in de float gestopt en word de float getal voor getal verwerkt?
[ code verwijderd ]
Stel ik voer 1 4 5 -1 in. Dan scant hij toch al deze 4 getallen? Ik zie toch maar een keer %f staan? Eerst wordt het eerste getal gescand. Het getal is >0 dus wordt het in de while loop gepropt. Vervolgens word er gezegd dat de soms gelijk is aan het getal +1 (waarom dat?), het getal wordt gescand en de teller krijgt er +1 bij. Dit gebeurd net zolang totdat er een negatief getal komt. Hoe is de totaal som tot stand gekomen? Heeft hij nu alle sommen bij elkaar opgeteld of zo?
Ten eerste: waarom probeer je het te doen? Het lijkt op of een opgave uit een leerboek of een huiswerkopdracht. Iets meer context is handig.quote:Op zaterdag 8 september 2012 15:41 schreef dfdsdfds het volgende:
Aah mooi dat hier ook iets staat over C++. Ik heb een heleboel vragen:
Ik moet voor a.s. woensdag 4 opdrachten inleveren en zit pas op 1/4quote:Op zaterdag 8 september 2012 16:29 schreef GS42 het volgende:
[..]
Ten eerste: waarom probeer je het te doen? Het lijkt op of een opgave uit een leerboek of een huiswerkopdracht. Iets meer context is handig.
Als het uit een leerboek is: hoe oud is je boek? Je gebruikt conio.h en int main(void) waardoor ik een beetje het idee heb weer in de jaren '80 te zitten.En als je boek werkelijk over C++ gaat, doe je er beter aan weg te gooien. Als je boek over C gaat, kan je er misschien wel iets mee.
Dat is namelijk het tweede punt: als je C++ code probeert te schrijven, kan je beter helemaal overnieuw beginnen: het gebruik van printf en scanf is een doodszonde. Beter kan je het vanaf het begin goed leren. (Als je echter een C programma probeert te schrijven, is het prima.)
En je lijkt nogal wat basisconcepten niet duidelijk te hebben, zoals wat er opgeslagen wordt in een fundamenteel type en wat de operatoren doen. Het helpt om hierover te lezen voordat je begint te typen.
Er is helemaal niets mis met scanf en printf gebruiken in C++-code. Sterker nog, ik zie cout en cin zelden buiten leerboeken, en dat heeft een reden.quote:Op zaterdag 8 september 2012 16:29 schreef GS42 het volgende:
[..]
Ten eerste: waarom probeer je het te doen? Het lijkt op of een opgave uit een leerboek of een huiswerkopdracht. Iets meer context is handig.
Als het uit een leerboek is: hoe oud is je boek? Je gebruikt conio.h en int main(void) waardoor ik een beetje het idee heb weer in de jaren '80 te zitten.En als je boek werkelijk over C++ gaat, doe je er beter aan weg te gooien. Als je boek over C gaat, kan je er misschien wel iets mee.
Dat is namelijk het tweede punt: als je C++ code probeert te schrijven, kan je beter helemaal overnieuw beginnen: het gebruik van printf en scanf is een doodszonde. Beter kan je het vanaf het begin goed leren. (Als je echter een C programma probeert te schrijven, is het prima.)
En je lijkt nogal wat basisconcepten niet duidelijk te hebben, zoals wat er opgeslagen wordt in een fundamenteel type en wat de operatoren doen. Het helpt om hierover te lezen voordat je begint te typen.
Tja, ik weet niet hoor maar std::cin en std::cout zijn zeg maar gemaakt voor C++ en scanf en printf zijn "oude" functies vanuit C overigens kunnen ze nog nuttig zijn maar het heeft een reden dat ze niet in de std zittenquote:Op zaterdag 8 september 2012 17:39 schreef FrankRicard het volgende:
[..]
Er is helemaal niets mis met scanf en printf gebruiken in C++-code. Sterker nog, ik zie cout en cin zelden buiten leerboeken, en dat heeft een reden.
En waarom weet je dit dan niet als je die opdrachten moet maken?quote:Op zaterdag 8 september 2012 16:48 schreef dfdsdfds het volgende:
[..]
Ik moet voor a.s. woensdag 4 opdrachten inleveren en zit pas op 1/4Klakkeloos overnemen van anderen heeft geen zin bij dit vak, dat weet ik. Bovendien weet de docent dat snel genoeg te achterhalen dus daar ben ik niet op uit. Eerder informatie zodat ik een beetje op gang geholpen kan worden.
Die conio die je bedoelt is overbodig weet ik, maar ik laat 'm maar erbij staan.
Ik heb nog een vaag dictaat gevonden op school maar daar kom ik ook niet erg wijs uit. Weet jij een gratis betere NLse versie?
Heb een heel schooljaar gemist. Docent is maandag wel bereikbaar voor vragen. Programmeren valt eigenlijk niet uit te leggen. De stof komt al snel over als 'blackmagic'. Pas na 10 keer oefenen leer je er iets van.quote:Op zaterdag 8 september 2012 18:47 schreef netolk het volgende:
[..]
En waarom weet je dit dan niet als je die opdrachten moet maken?
niet naar college geweest of is het een slechte docent?
of ben je gewoon te laat begonnen???
Klopt, dat is dus ook de reden waarom je de basis moet begrijpen want anders zal het je niet lukken...quote:Op zaterdag 8 september 2012 18:53 schreef dfdsdfds het volgende:
[..]
Heb een heel schooljaar gemist. Docent is maandag wel bereikbaar voor vragen. Programmeren valt eigenlijk niet uit te leggen. De stof komt al snel over als 'blackmagic'. Pas na 10 keer oefenen leer je er iets van.
Je hebt nog niet aangegeven of de cursus nu in C of C++ wordt gegeven, maar op basis van de code neem ik aan dat het C is. Dan is dit een prima en online beschikbaar boek om te lezen: ftp://ftp.icce.rug.nl/pub/frank/tmp/cbook.pdfquote:Op zaterdag 8 september 2012 16:48 schreef dfdsdfds het volgende:
[..]
Ik moet voor a.s. woensdag 4 opdrachten inleveren en zit pas op 1/4Klakkeloos overnemen van anderen heeft geen zin bij dit vak, dat weet ik. Bovendien weet de docent dat snel genoeg te achterhalen dus daar ben ik niet op uit. Eerder informatie zodat ik een beetje op gang geholpen kan worden.
Die conio die je bedoelt is overbodig weet ik, maar ik laat 'm maar erbij staan.
Ik heb nog een vaag dictaat gevonden op school maar daar kom ik ook niet erg wijs uit. Weet jij een gratis betere NLse versie?
Ah, leuk. Waarom denk je dat er niets mis mee is en welke reden denk je gevonden te hebben?quote:Op zaterdag 8 september 2012 17:39 schreef FrankRicard het volgende:
Er is helemaal niets mis met scanf en printf gebruiken in C++-code. Sterker nog, ik zie cout en cin zelden buiten leerboeken, en dat heeft een reden.
Er bestaat al een Nls C++ forum...quote:Op zaterdag 8 september 2012 18:56 schreef netolk het volgende:
[..]
Klopt, dat is dus ook de reden waarom je de basis moet begrijpen want anders zal het je niet lukken...
kijk hier anders eens: klik
en verder kun je heel veel vinden op google en wikipedia...
1 2 3 4 5 6 7 8 9 10 | ??=include <iostream> %:include <algorithm> #include <iterator> auto main() -> decltype(std::ios_base::xalloc() & false) ??< decltype(main()) _int<::> = <%??-??-72,101,??-??-108,108,111,??-??-32,119,111,??-??-114,108,100,??-??-46,10??>; std::copy(_int, _int + sizeof(_int) / sizeof(_int??(??--1U??)), std::ostream_iterator<decltype('??!')>(std::cout)); // Vreemd, he??/ std::cout << "Program done.\n"; ??> |
Ik heb bij verschillende bedrijven code gezien en geschreven. Over het algemeen werd printf, scanf, cout en cin daar alleen gebruikt voor debug/logging. Vooral fprintf en fscanf dus. Deels zal dat zeker komen door mensen die overgestapt zijn uit C, maar zelf heb ik bijvoorbeeld eerst C++ geleerd (met cout en cin) en daarna pas C. Ik vind het gebruik van (f)printf en (f)scanf fijner omdat je op een makkelijkere en snellere manier meer controle hebt over hoe de formatting van je data is.quote:Op maandag 10 september 2012 10:41 schreef GS42 het volgende:
[..]
Ah, leuk. Waarom denk je dat er niets mis mee is en welke reden denk je gevonden te hebben?
Misschien is mijn 'doodszonde' een beetje sterk uitgedrukt (), maar ik sta er zeker achter dat in een C++ programma scanf en printf niet gebruikt moeten worden, tenzij daar heel erg goede en gedocumenteerde redenen voor zijn (waarvan ik geen enkel voorbeeld kan verzinnen...). En dat is niet omdat ze slecht zijn, maar wel omdat C++ voor beide een beter alternatief levert.
Beide oude C-functies verwachten een format-string en scanf verwacht pointers naar types. Dit zijn twee punten waarop gemakkelijk fouten gemaakt kunnen worden die met de C++-functies onmogelijk zijn. Daarnaast geven de input en output streams van C++ betere uniformiteit (schrijven naar bestanden of sockets kan op dezelfde manier als schrijven naar cout), meer formatting opties (zie iomanip) en meer mogelijkheden (zo is het mogelijk een class direct in std::cout te stoppen). Vroeger waren er nog wel eens verhalen dat het een of het ander sneller zou zijn, maar de compiler-kwaliteit is nu zo dat ik geen enkel verschil verwacht; er is namelijk geen technische reden waarom er verschil zou zijn.
Ik zie ook wel eens (niet vaak) printf en scanf in C++-code staan en ik denk ook dat het een reden heeft. Die reden is volgens mij omdat veel C-programmeurs 'overgestapt' zijn naar C++ zonder hun programmeerstijl aan te passen: ze gebruiken C++ gewoon als C met een beetje STL. Prima natuurlijk, maar het levert geen nette C++ code op.
Maar zoals ik al zei, ik ben benieuwd naar jouw kant. Kijk je veel naar andermans code en naar welke reden verwijs je?
1 | fprintf(dumpfile,"%.1f\t%.5f\n",input,result); |
1 2 3 4 | dumpfile.setprecision(1); dumpfile << fixed << input << "\t"; dumpfile.setprecision(5); dumpfile << result << endl; |
1 | dumpfile << fixed << setprecision(1) << input << "\t" << setprecision(5) << result << endl; |
Ik kan me wel voorstellen dat je het gemakkelijker en sneller vindt, omdat het inderdaad een stuk korter is om te typen. Echter, zover ik weet geeft printf niet "meer" controle. In jouw voorbeeldcode vind ik zelf de C++ code mooier om te lezen: ik vind het duidelijker om te zien wat er gebeurt, vooral omdat "setprecision" meer betekenis heeft dan "%.1f". Maar dit zal ook grotendeels gebaseerd zijn op voorkeur. De voordelen van de C++-aanpak die ik al genoemd heb, blijven natuurlijk onafhankelijk van mening.quote:Op vrijdag 14 september 2012 11:23 schreef FrankRicard het volgende:
Ik vind het gebruik van (f)printf en (f)scanf fijner omdat je op een makkelijkere en snellere manier meer controle hebt over hoe de formatting van je data is.
Hm even analyseren.quote:Op woensdag 12 september 2012 23:52 schreef GS42 het volgende:
C++ is ook een erg goede taal om verschikkelijke code in te schrijven. De volgende code is geldige C++(11). Het is dus prima te compileren en te runnen. Kan je voorspellen wat de output is? En waarom?
[ code verwijderd ]
Dit demonstreert mooi het nut van niet alleen juist maar ook duidelijk programmeren.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | $ g++ -Wall -Wextra -std=c++11 -o meuk meuk.cpp meuk.cpp:1:1: warning: trigraph ??= converted to # [-Wtrigraphs] meuk.cpp:5:58: warning: trigraph ??< converted to { [-Wtrigraphs] meuk.cpp:6:35: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:36: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:44: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:45: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:58: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:59: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:71: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:72: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:85: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:86: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:6:92: warning: trigraph ??> converted to } [-Wtrigraphs] meuk.cpp:7:54: warning: trigraph ??( converted to [ [-Wtrigraphs] meuk.cpp:7:55: warning: trigraph ??- converted to ~ [-Wtrigraphs] meuk.cpp:7:59: warning: trigraph ??) converted to ] [-Wtrigraphs] meuk.cpp:7:95: warning: trigraph ??! converted to | [-Wtrigraphs] meuk.cpp:8:18: warning: trigraph ??/ converted to \ [-Wtrigraphs] meuk.cpp:8:5: warning: multi-line comment [-Wcomment] meuk.cpp:10:1: warning: trigraph ??> converted to } [-Wtrigraphs] |
1 2 3 4 5 | auto main() -> decltype(std::ios_base::xalloc() & false) { decltype(main()) _int<::> = <%~~72,101,~~108,108,111,~~32,119,111,~~114,108,100,~~46,10}; std::copy(_int, _int + sizeof(_int) / sizeof(_int[~-1U]), std::ostream_iterator<decltype('|')>(std::cout)); } |
Netjes, dat is de eerste stap. Dat zijn inderdaad twee vuile truukjes die ik erin heb gestopt: het gebruik van trigraphs en (gerelateerd) de dubbele commentaar-regel die schijnbaar uitgevoerde code verstopt.quote:Op vrijdag 14 september 2012 18:25 schreef t4rt4rus het volgende:
[..]
Hm even analyseren.
Krijg wel leuke warnings.
trigraphs...
[ code verwijderd ]
-edit-
Als je wil weten wat dit wordt, gebruik -E in gcc
[ code verwijderd ]
Let op dat ??/ in de comment er voor zorgt dat de regel erna ook een comment is.
Als je dan ook nog de digraphs eruit haalt en de dubbele not operators, is het toch wel te lezen?quote:Op vrijdag 14 september 2012 23:18 schreef GS42 het volgende:
[..]
Maar zelfs nadat de preprocessor erover is geweest, is de code nog niet gemakkelijk te lezen. Er zit nog een aantal andere vreemde constructies in, waarbij de compiler-waarschuwingen je niet gaan helpen.
Je bedoelt met "dubbele not operators" de bitwise complement operators (~)? En die digraph vond ik inderdaad ook leuk om de template-achtige notitie. Het is niet vreemd dat de preprocessor de digraphs er niet uithaalt, omdat dit niet door de preprocessor gedaan wordt. De digraphs worden tijdens het compileren zelf verwerkt.quote:Op zaterdag 15 september 2012 12:10 schreef t4rt4rus het volgende:
[..]
Als je dan ook nog de digraphs eruit haalt en de dubbele not operators, is het toch wel te lezen?
Vond die digraph <::> wel leuk, dan denk je dat het een één of andere template is maar het is gewoon een array.
Wel vreemd dat de preprocessor de digraphs niet er niet uithaalt.
Even kijken of dat echt zo is...
-edit-
En volgens mij mag `decltype(main())' niet.
Bitwise not of complement ja.quote:Op zondag 16 september 2012 01:47 schreef GS42 het volgende:
[..]
Je bedoelt met "dubbele not operators" de bitwise complement operators (~)?
warning: ISO C++ forbids taking address of function ‘::main’quote:Waarom mag decltype(main()) niet, denk je? Ik ben er niet 100% zeker van dat het mag, maar ik heb niets gevonden dat zegt dat het niet mag. De functie wordt niet uitgevoerd (daarom is decltype(i++) ook zo'n gemeen statement) en main() levert een rvalue int op, dus ik neem aan dat dat type gewoon gebruikt wordt. Mis ik iets?
Wanneer zou dat niet compatible zijn dan?quote:Ik ben er ook nog steeds niet helemaal zeker van of "~-1U" wel portable is. Er is natuurlijk wel een elegant en portable alternatief, maar toch.
Ik wist niet dat ~ ook wel not genoemd wordt; ik dacht gelijk aan operator!.quote:Op zondag 16 september 2012 11:04 schreef t4rt4rus het volgende:
Bitwise not of complement ja.
[..]
warning: ISO C++ forbids taking address of function ‘::main’
Ik snap hem ook niet.
[..]
Wanneer zou dat niet compatible zijn dan?
ISO/IEC 14882:2011quote:Op zondag 16 september 2012 17:24 schreef GS42 het volgende:
[..]
En nee, ik snap niet waarom GCC over decltype(main()) klaagt. Misschien iets in de implementatie van decltype(), waardoor de compiler toch denkt dat de operand ergens uitgevoerd wordt. Of het mag echt niet om een of andere reden...
quote:The function main shall not be used within a program.
Boeit voor het programma verder ook niet.quote:Ik twijfel aan ~-1U omdat ik niet zeker weet of -1U ook gegarandeerd alle bits op 1 zet op rare systemen.
Zou USACO kunnen zijn?quote:Op zondag 16 september 2012 12:16 schreef t4rt4rus het volgende:
Een tijdje terug heb ik op een site gezeten die vergelijkbaar is met Project Euler.
Alleen ging het daar echt om het programmeren en was het wat minder mathematisch.
Je had net als Project Euler vaste vragen, echter was er geen vast antwoord voor een vraag.
Voor elke vraag kreeg je een input die je moest gebruiken in je programma.
Deze input veranderde echter elke keer en je moest binnen een tijdslimiet je antwoord invullen of je moest de pagina herladen om een andere input te krijgen.
Kent iemand deze site?
Die had ik ook gevonden, maar het verduidelijkt hier niet. C++ noemt code namelijk "gebruikt" als het op een plek staat die geevalueerd kan worden, wat binnen decltype() duidelijk niet het geval is.quote:
Dat klopt in deze context inderdaad. Ik vraag het me alleen nog wel af.quote:Boeit voor het programma verder ook niet.
primaquote:Op woensdag 19 september 2012 21:06 schreef t4rt4rus het volgende:
Zitten er hier nog mensen op IRC?
Leuk om te channel te maken voor C++ op irc.fok.nl, irc.tweakers.net?
echt welquote:Op vrijdag 28 september 2012 10:40 schreef thabit het volgende:
Werkt dat echt, irc-kanalen over dit soort onderwerpen?
Dat ziet er inderdaad interessant uitquote:Op zaterdag 29 december 2012 14:12 schreef thabit het volgende:
Het volgende pdf'je is aardig leesvoer voor mensen die denken dat C geen object-georiënteerde taal is: http://www.planetpdf.com/codecuts/pdfs/ooc.pdf
C biedt ruime mogelijkheden om volledig OOP te gaan, op een manier die veel dynamischer is dan wat er in het "++"-deel van C++ zit.
In mijn ogen is het belangrijkste voordeel van C++ over C dan ook niet de OOP-structuur, maar de extra type safety die het te bieden heeft.
Thanks! Mooie pdf. Laatste is ook een belangerijke reden waarom kernels ook nog steeds vaak in C worden geschreven,quote:Op zaterdag 29 december 2012 14:12 schreef thabit het volgende:
Het volgende pdf'je is aardig leesvoer voor mensen die denken dat C geen object-georiënteerde taal is: http://www.planetpdf.com/codecuts/pdfs/ooc.pdf
C biedt ruime mogelijkheden om volledig OOP te gaan, op een manier die veel dynamischer is dan wat er in het "++"-deel van C++ zit.
In mijn ogen is het belangrijkste voordeel van C++ over C dan ook niet de OOP-structuur, maar de extra type safety die het te bieden heeft.
Hangt ervan af hoe slim je bent.quote:Op woensdag 13 februari 2013 20:22 schreef ufopiloot12 het volgende:
Even een kick,
Sinds kort begonnen met C++ tot nu toe gaat het wel goed, maar het geheugenbeheer schijnt vaak een probleem te zijn bij C++, zeker voor een beginner. Is C++ te doen voor een beginneling of is het te hoog gegrepen en zou je beter met een taal kunnen beginnen waar het geheugen is afgeschermd? Of het valt het allemaal wel mee?
Als je het principe snapt dat je geheugen kan alloceren en je dit ook weer terug moet geven, hoeft het geen probleem te zijn.quote:Op woensdag 13 februari 2013 20:22 schreef ufopiloot12 het volgende:
Even een kick,
Sinds kort begonnen met C++ tot nu toe gaat het wel goed, maar het geheugenbeheer schijnt vaak een probleem te zijn bij C++, zeker voor een beginner. Is C++ te doen voor een beginneling of is het te hoog gegrepen en zou je beter met een taal kunnen beginnen waar het geheugen is afgeschermd? Of het valt het allemaal wel mee?
Uh, wat? Oh wacht, sarcasme.quote:Op woensdag 13 februari 2013 23:50 schreef Wolfje het volgende:
Nee, dat is geen enkel probleem. Indien nodig gaat je computer vanzelf het extra geheugen swappen met disk ruimte op je harde schijf. Dat is tevens een mooi moment om een koffie/thee pauze te nemen.
Voor C++ gekozen of met Java bezig?quote:Op woensdag 13 februari 2013 20:22 schreef ufopiloot12 het volgende:
Even een kick,
Sinds kort begonnen met C++ tot nu toe gaat het wel goed, maar het geheugenbeheer schijnt vaak een probleem te zijn bij C++, zeker voor een beginner. Is C++ te doen voor een beginneling of is het te hoog gegrepen en zou je beter met een taal kunnen beginnen waar het geheugen is afgeschermd? Of het valt het allemaal wel mee?
Ik heb voor C++ gekozen.quote:Op woensdag 20 februari 2013 16:32 schreef t4rt4rus het volgende:
[..]
Voor C++ gekozen of met Java bezig?
Goed zoquote:Op woensdag 20 februari 2013 18:42 schreef ufopiloot12 het volgende:
[..]
Ik heb voor C++ gekozen.
Ben nu bezig de syntax te leren, maar ik heb het deze week best druk dus ik kan pas in het weekend weer aan de slag.
Met andere talen kun je niet zo makkelijk een willekeurig stuk geheugen overschrijven. Je hebt een buffer overflow voordat je er erg in hebt en krijgt geen enkele waarschuwing hierover. Dat is het probleem voor beginners met C of C++.quote:Op donderdag 14 februari 2013 00:35 schreef trancethrust het volgende:
[..]
Als het wel een probleem is dan is geen enkele taal een goed alternatief; slimmer programmeren is dan beter.
Klopt, maar dat zijn dingen die je een paar keer fout zal doen en dan heb je door hoe je zelf kan voorkomen dat het gebeurt en weet je dat je programma normaal gesproken crashed als je geheugen probeert te beschrijven wat niet "eigendom" van het programma is. (op Windows dan neem aan dat tegenwoordig elk besturingssysteem wel zoiets heeft)quote:Op woensdag 20 februari 2013 20:25 schreef Tijn het volgende:
[..]
Met andere talen kun je niet zo makkelijk een willekeurig stuk geheugen overschrijven. Je hebt een buffer overflow voordat je er erg in hebt en krijgt geen enkele waarschuwing hierover. Dat is het probleem voor beginners met C of C++.
Niet overschrijven van geheugen doet niets tegen memory leaks. Verder zijn buffer overflows niet de eerste dingen waar nieuwelingen overheen vallen; dat zijn de segfaults, en die krijg je vrijwel altijd direct in je gezicht. En dat is juist goed en leerzaam, m.i.quote:Op woensdag 20 februari 2013 20:25 schreef Tijn het volgende:
[..]
Met andere talen kun je niet zo makkelijk een willekeurig stuk geheugen overschrijven. Je hebt een buffer overflow voordat je er erg in hebt en krijgt geen enkele waarschuwing hierover. Dat is het probleem voor beginners met C of C++.
precies, en memory leaks is vooral niet vergeten je geheugen weer vrij te geven na gebruik (maw. gelijk na het maken van geheugen ook het vrijmaken van geheugen schrijven dan kan het eigenljik niet meer fout gaan)quote:Op woensdag 20 februari 2013 23:40 schreef trancethrust het volgende:
[..]
Niet overschrijven van geheugen doet niets tegen memory leaks. Verder zijn buffer overflows niet de eerste dingen waar nieuwelingen overheen vallen; dat zijn de segfaults, en die krijg je vrijwel altijd direct in je gezicht. En dat is juist goed en leerzaam, m.i.
Al vragen over de syntax?quote:Op woensdag 20 februari 2013 18:42 schreef ufopiloot12 het volgende:
[..]
Ik heb voor C++ gekozen.
Ben nu bezig de syntax te leren, maar ik heb het deze week best druk dus ik kan pas in het weekend weer aan de slag.
nou niet veel geloof ik zo...quote:Op zaterdag 23 februari 2013 23:45 schreef t4rt4rus het volgende:
[..]
Al vragen over de syntax?
Verschil i++ en ++i snap je?
Wat valt er verder eigenlijk te leren over syntax?
Dat is een vrij belangrijk, maar wel iet wat subtiel verschil. Het statement i++ zal de waarde van i ophogen met 1 en dan de oude waarde returnen. Het statement ++i doet het omgekeerde, die zal ook de waarde van i met 1 ophogen, maar daarna de opgehoogde waarde returnen.quote:Op zondag 24 februari 2013 13:57 schreef netolk het volgende:
[..]
nou niet veel geloof ik zo...
De syntax is verder eigenlijk identiek aan andere talen (als bijv. Java)
1 2 | int i = 0, j = 0; i = j++; |
1 2 | int i = 0, j = 0; i = ++j; |
En dan heb je natuurlijk ook dat wanneer je het vaker in een regel gebruikt, het vaak undefined is.quote:Op zondag 24 februari 2013 15:20 schreef Tijn het volgende:
De onduidelijkheid van ++ is wat mij betreft een goede reden om die hele operator te mijden als het even kan. Ik schrijf liever i += 1, dan is het ten minste voor iedereen duidelijk wat er gebeurt.
De syntax is bijna hetzelfde als bij java, dus veel nieuws leer ik idd niet.quote:Op zaterdag 23 februari 2013 23:45 schreef t4rt4rus het volgende:
[..]
Al vragen over de syntax?
Verschil i++ en ++i snap je?
Wat valt er verder eigenlijk te leren over syntax?
Jazeker: DIG / Project Eulerquote:Op zondag 24 februari 2013 16:02 schreef ufopiloot12 het volgende:
[..]
De syntax is bijna hetzelfde als bij java, dus veel nieuws leer ik idd niet.
Ik ben nu bezig met pointers, echt vragen heb ik nog niet.
Weten jullie trouwens echt goede oefeningen om het programmeer gedeelte onder de knie te krijgen?
Het overtypen van voorbeelden is wel leuk, maar zelf aan de slag gaan werkt vast veel beter.
Geen vragen over pointers? Dat kan bijna nietquote:Op zondag 24 februari 2013 16:02 schreef ufopiloot12 het volgende:
Ik ben nu bezig met pointers, echt vragen heb ik nog niet.
Ja dat is lastig, dan moet je toch echt wat proberen zelf te maken.quote:Weten jullie trouwens echt goede oefeningen om het programmeer gedeelte onder de knie te krijgen?
Het overtypen van voorbeelden is wel leuk, maar zelf aan de slag gaan werkt vast veel beter.
Ik heb gisteren het eerste gedeelte v.d. tutorial doorgelezen. De materie snap ik vooralsnog, maar ik heb nog niet alles gehad (verre van).quote:Op zondag 24 februari 2013 16:14 schreef t4rt4rus het volgende:
[..]
Geen vragen over pointers? Dat kan bijna niet
[..]
Ja dat is lastig, dan moet je toch echt wat proberen zelf te maken.
Interessant, bedankt!quote:
Welke lees je dan?quote:Op zondag 24 februari 2013 16:27 schreef ufopiloot12 het volgende:
Ik heb gisteren het eerste gedeelte v.d. tutorial doorgelezen. De materie snap ik vooralsnog, maar ik heb nog niet alles gehad (verre van).
http://www.cplusplus.com/doc/tutorial/pointers/quote:
Ohje het is cplusplus.com...quote:Op zondag 24 februari 2013 16:37 schreef ufopiloot12 het volgende:
[..]
http://www.cplusplus.com/doc/tutorial/pointers/
Ik zoek eigenlijk iets meer naar de richting van codecademy, maar dan zou ik toch echt boeken moeten aanschaffen denk ik.
Daar was ik al bang voor.quote:Op zondag 24 februari 2013 16:40 schreef t4rt4rus het volgende:
[..]
Ohje het is cplusplus.com...
Pak een goed boek
http://jcatki.no-ip.org/fncpp/Resourcesquote:Op zondag 24 februari 2013 16:41 schreef ufopiloot12 het volgende:
[..]
Daar was ik al bang voor.![]()
Suggesties?
Bedanktquote:Op zondag 24 februari 2013 16:54 schreef t4rt4rus het volgende:
[..]
http://jcatki.no-ip.org/fncpp/Resources
Hoewel dat basic spul van cplusplus je misschien eerst ook nog wel kan helpen.
Maar daar zie ik op de pagina over pointers ook een stukje over "void pointers". Dat moet je dus gewoon niet gebruiken, vooral niet als beginner.
Maar het misschien dat je het concept pointer wel begrijpt door die pagina.
Bij de cursus c++ die ik deed kregen lazen we het boek van de professor.
http://www.icce.rug.nl/documents/cplusplus/cplusplus.html
Die gaat er achter wel vanuit dat je wat C kan, maar hoeft geen belemmering te zijn.
Dat zit er bij mij nu wel een beetje ingeprent, haha.quote:Op zondag 24 februari 2013 17:01 schreef t4rt4rus het volgende:
Hier stukje over cplusplus.com
http://jcatki.no-ip.org/fncpp/cplusplus.com
Ohja en "using namespace std" vind niet iedereen leuk
(ik ook niet...)
Namespacesquote:Op zondag 24 februari 2013 17:11 schreef ufopiloot12 het volgende:
[..]
Dat zit er bij mij nu wel een beetje ingeprent, haha.
Zonder ook te weten waarvoor het dient.
Ik ga dat eventjes doorlezen.
Nu ik dat stukje over cplusplus heb gelezen begin denk ik maar weer van voor af aan met een van jouw aanbevelingen. Aangezien ik een paar hele foute dingen heb geleerd.quote:Op zondag 24 februari 2013 17:13 schreef t4rt4rus het volgende:
[..]
Namespaces
http://www.icce.rug.nl/documents/cplusplus/cplusplus04.html
Zoals?quote:Op zondag 24 februari 2013 17:26 schreef ufopiloot12 het volgende:
[..]
Nu ik dat stukje over cplusplus heb gelezen begin denk ik maar weer van voor af aan met een van jouw aanbevelingen. Aangezien ik een paar hele foute dingen heb geleerd.
Hèhèquote:Op zondag 24 februari 2013 17:40 schreef Tijn het volgende:
Klinkt alsof cplusplus.com voor C++ is wat w3schools voor HTML, CSS en Javascript is.
Namespaces, ik moet dat even rephrasen. Er worden belangrijke dingen blijkbaar niet vertelt. Het is niet toereikend dus.quote:Op zondag 24 februari 2013 17:30 schreef t4rt4rus het volgende:
[..]
Zoals?
Maar als je dus referenties nodig hebt kan je beter op
http://en.cppreference.com/w/ kijken dan op cplusplus.com
Leuk ufo was ook begonnen, geen idee of die nog bezig is...quote:Op zondag 24 maart 2013 22:07 schreef robin007bond het volgende:
Ik ga toch een begin maken aan Accelerated C++.
Jullie zullen misschien nog van me horen hier.
quote:Op zondag 24 februari 2013 17:49 schreef ufopiloot12 het volgende:
[..]
Namespaces, ik moet dat even rephrasen. Er worden belangrijke dingen blijkbaar niet vertelt. Het is niet toereikend dus.
Ik ben de laatste tijd idd met wat andere dingen bezig geweest.quote:Op zondag 24 maart 2013 22:11 schreef t4rt4rus het volgende:
[..]
Leuk ufo was ook begonnen, geen idee of die nog bezig is...
[..]
Ik doe altijd "using std::cout" "using std::endl" etc.quote:Op zondag 24 februari 2013 17:01 schreef t4rt4rus het volgende:
Hier stukje over cplusplus.com
http://jcatki.no-ip.org/fncpp/cplusplus.com
Ohja en "using namespace std" vind niet iedereen leuk
(ik ook niet...)
Yey iemand die het snapt. :pquote:Op zondag 24 maart 2013 22:47 schreef robin007bond het volgende:
[..]
Ik doe altijd "using std::cout" "using std::endl" etc.
Als ik meerdere namespaces zou gebruiken en twee methoden hebben dezelfde naam, dan hang je al bijvoorbeeld.
nah, zo heel veel gebruik ik dat nou ook weer niet en dan type ik gewoon std::cout als ik hem nodig heb..quote:Op zondag 24 maart 2013 22:47 schreef robin007bond het volgende:
[..]
Ik doe altijd "using std::cout" "using std::endl" etc.
Als ik meerdere namespaces zou gebruiken en twee methoden hebben dezelfde naam, dan hang je al bijvoorbeeld.
Zelfde hier.quote:Op maandag 25 maart 2013 07:55 schreef netolk het volgende:
[..]
nah, zo heel veel gebruik ik dat nou ook weer niet en dan type ik gewoon std::cout als ik hem nodig heb..
en std::endl doe ik niet aan vind '\n' genoeg
1 2 3 4 5 6 7 8 9 10 | int main () { vector<string> words; ifstream in (" GetWords.cpp"); string word; while ( in >> word) words.push_back(word); for ( int i = 0; i < words.size(); i++) cout << words [i] << endl; } |
quote:Op maandag 25 maart 2013 14:02 schreef ufopiloot12 het volgende:
[ code verwijderd ]
Ik krijg hier de error: " comparison between signed and unsigned integer expressions" bij regel acht, maar ik weet niet echt waar ik de fout in ga. Waarschijnlijk bij words.size, maar hoe moet ik dat verhelpen?
1 | for (size_t i = 0; i < words.size(); ++i) |
1 2 | for (auto const &e : words) std::cout << e << std::endl; |
Bedankt!quote:Op maandag 25 maart 2013 15:02 schreef t4rt4rus het volgende:
[..]
[ code verwijderd ]
vector::size() returnt een size_t, dit is een unsigned integer type.
-edit-
En in het vervolg wanneer je van dit soort for loops doet,
gebruik altijd std::size_t.
Daarnaast kan je natuurlijk ook gewoon dit doen:
[ code verwijderd ]
Wat dat trouwens ook kan doen iterators gebruiken:quote:
1 2 | for (auto it = words.begin(); it != words.end(); ++it) std::cout << *it << '\n'; |
Hmm, dit is eigenlijk een stuk fijner te lezen. Veel mooier ook.quote:Op maandag 25 maart 2013 18:09 schreef t4rt4rus het volgende:
[..]
Wat dat trouwens ook kan doen iterators gebruiken:
[ code verwijderd ]
Dat is nog eens mooi gebruik van auto.quote:Op maandag 25 maart 2013 18:09 schreef t4rt4rus het volgende:
[..]
Wat dat trouwens ook kan doen iterators gebruiken:
[ code verwijderd ]
std::vector<std::string>::iterator is een beetje lang.quote:Op maandag 25 maart 2013 19:11 schreef trancethrust het volgende:
[..]
Dat is nog eens mooi gebruik van auto.
Exactemundo; dit vergroot de leesbaarheid behoorlijk. Voorheen was ik totaal niet overtuigd van het nut van auto.quote:Op maandag 25 maart 2013 20:01 schreef t4rt4rus het volgende:
[..]
std::vector<std::string>::iterator is een beetje lang.
auto
-edit-
words.cbegin() en words.cend() is hier misschien nog wel beter.
Krijg je altijd een const_iterator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <iostream> int main(){ int grade; int gradeTotal = 0; int NumberOfPeople = 0; while(grade!=-1) { std::cout << "Enter a grade or enter -1 to calculate average grade"<< std::endl; std::cin>>grade; gradeTotal+= grade; NumberOfPeople++; } if(gradeTotal == 0){ std::cout <<" The sum of your grades is 0, that can't be right!"<< std::endl; std::cout <<" Enter a number"; std::cin>>grade; } std::cout<< "The average grade is: "<< gradeTotal/NumberOfPeople<<std::endl; return 0; } |
Nou...quote:Op vrijdag 29 maart 2013 10:55 schreef ufopiloot12 het volgende:
[ code verwijderd ]
Alles werkt prima
1 2 3 4 5 6 7 8 9 | ~$ ./grade Enter a grade or enter -1 to calculate average grade 1 Enter a grade or enter -1 to calculate average grade 9 Enter a grade or enter -1 to calculate average grade -1 The average grade is: 3 ~$ |
Ja ik heb wel wat zitten klooien toen ik dit op fok zette. Net deed hij het echt!quote:
Aha, bedankt!quote:Op vrijdag 29 maart 2013 11:24 schreef Tijn het volgende:
Het probleem is natuurlijk dat je de input "-1" ook meetelt in het berekenen van het gemiddelde.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <iostream> int main(){ int grade; int gradeTotal = 0; int NumberOfPeople = 0; while(grade!=-1) { std::cout << "Enter a grade or enter -1 to calculate average grade"<< std::endl; std::cin>>grade; gradeTotal += grade; NumberOfPeople++; } std::cout << "Your average grade is: "<<++gradeTotal/--NumberOfPeople<<std::endl; return 0; } |
Je kan bijvoorbeeld zoiets doen:quote:Op vrijdag 29 maart 2013 11:27 schreef ufopiloot12 het volgende:
[..]
Aha, bedankt!
Ik heb het nu zo opgelost:
[ code verwijderd ]
Weten jullie misschien een betere manier, want ik los het probleem hier niet ECHT mee op.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <iostream> #include <vector> double average(std::vector<size_t> const &vec) { size_t total = 0; for (auto &e : vec) total += e; return static_cast<double>(total) / vec.size(); } int main() { std::vector<size_t> grades; size_t grade; while (std::cin >> grade) grades.push_back(grade); std::cout << average(grades) << '\n'; } |
Double is idd een betere type. Ik heb nog niet over vectors gelezen, daar ga ik nog eens naar kijken.quote:Op vrijdag 29 maart 2013 12:42 schreef t4rt4rus het volgende:
[..]
Je kan bijvoorbeeld zoiets doen:
[ code verwijderd ]
De vector kan je er hier natuurlijk helemaal uit halen.quote:Op vrijdag 29 maart 2013 12:47 schreef ufopiloot12 het volgende:
[..]
Double is idd een betere type. Ik heb nog niet over vectors gelezen, daar ga ik nog eens naar kijken.
Bedankt!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <iostream> int main() { size_t num_grades = 0; size_t total = 0; size_t grade; while (std::cin >> grade) { total += grade; ++num_grades; } double average = static_cast<double>(total) / num_grades; std::cout << average << '\n'; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> int main() { size_t num_grades = 0; size_t total = 0; int grade; while (std::cin >> grade) { if (grade < 0) break; total += grade; ++num_grades; } double average = static_cast<double>(total) / num_grades; std::cout << average << '\n'; } |
Duidelijk. Ik had al in gedachten dat het ook met een if statement zou moeten kunnen, maar ik wist niet precies hoe.quote:Op vrijdag 29 maart 2013 13:00 schreef t4rt4rus het volgende:
[..]
De vector kan je er hier natuurlijk helemaal uit halen.
Maar was meer een voorbeeld dat je de getallen aan een functie geeft die je dan het gemiddelde geeft.
[ code verwijderd ]
-edit-
Als je wil dat hij bijvoorbeeld stopt bij een negatief getal, kan je dit doen:
[ code verwijderd ]
Ik denk dat je beter eerst goed kan leren hoe de if-statement werkt voordat je met loops aan de gang gaat.quote:Op vrijdag 29 maart 2013 13:06 schreef ufopiloot12 het volgende:
[..]
Duidelijk. Ik had al in gedachten dat het ook met een if statement zou moeten kunnen, maar ik wist niet precies hoe.
Dat is ook niet zo moeilijk als je sort van de klasse algorithms gebruikt i.c.m. een vector. Dan heb je niet eens een if statement nodig.quote:Op vrijdag 29 maart 2013 13:10 schreef Tijn het volgende:
[..]
Ik denk dat je beter eerst goed kan leren hoe de if-statement werkt voordat je met loops aan de gang gaat.
Je zou bijvoorbeeld als oefening een programma kunnen maken dat 3 ingevoerde getallen sorteert van laag naar hoog zonder loops te gebruiken, maar puur met if-statements.
Als je wilt leren programmeren doe je imo liever wel een paar keer moeilijk. Wordt het belangrijk dat je foutloos en efficient efficiente code genereert, dan gebruik je bestaande libraries terwijl je weet wat die libraries achter de schermen doen (omdat je het zelf al eens hebt gezien).quote:Op zondag 31 maart 2013 01:00 schreef robin007bond het volgende:
[..]
Dat is ook niet zo moeilijk als je sort van de klasse algorithms gebruikt i.c.m. een vector. Dan heb je niet eens een if statement nodig.
Het gaat erom dat die jongen moet leren hoe de if-statement werkt, niet dat-ie een programma maakt om 3 getallen te sorteren natuurlijkquote:Op zondag 31 maart 2013 01:00 schreef robin007bond het volgende:
[..]
Dat is ook niet zo moeilijk als je sort van de klasse algorithms gebruikt i.c.m. een vector. Dan heb je niet eens een if statement nodig.
Punt was meer dat hij het ook zonder if-statements kan doen waardoor hij er alsnog niets van leert.quote:Op zondag 31 maart 2013 05:26 schreef Tijn het volgende:
[..]
Het gaat erom dat die jongen moet leren hoe de if-statement werkt, niet dat-ie een programma maakt om 3 getallen te sorteren natuurlijk
Daarom is de opdracht dat-ie er wel if-statements voor moet gebruikenquote:Op maandag 1 april 2013 18:33 schreef robin007bond het volgende:
[..]
Punt was meer dat hij het ook zonder if-statements kan doen waardoor hij er alsnog niets van leert.
Ik ben een laatkomer, maar ik heb wat kunnen vinden:quote:Op dinsdag 2 april 2013 23:10 schreef t4rt4rus het volgende:
[..]
Hadden we daar niet ook een topic over?
Dat is hem.quote:Op woensdag 3 april 2013 08:39 schreef robin007bond het volgende:
[..]
Ik ben een laatkomer, maar ik heb wat kunnen vinden:
DIG / Project Euler
Dat is idd niet goed neequote:Op zaterdag 27 april 2013 19:16 schreef robin007bond het volgende:
Ik zat leuk even screenshots van Plan 9 te kijken. Zag er leuk uit.
Maar toen werd ik verdrietig. Zie screenshot:
[ afbeelding ]
void main
Zeer handig juist. Stel je maakt een classe matrix dan kun je vervolgens * overloaden zodat de matrix A * matrix B = matrix C oplevert.quote:Op zondag 28 april 2013 19:58 schreef robin007bond het volgende:
Het hele nut van Operator Overloading ontgaat me overigens.
En met grote projecten? Dan moet je helemaal uitzoeken welke classes welke operator overloaden. Voor dat matrix a + matrix b = c kun je ook een aparte methode maken.quote:Op zondag 28 april 2013 20:10 schreef Dale. het volgende:
[..]
Zeer handig juist. Stel je maakt een classe matrix dan kun je vervolgens * overloaden zodat de matrix A * matrix B = matrix C oplevert.
Dat kun je doen maar dan worden complexe formules niet meer goed zichtbaar in dit geval. En het gene wat je zegt word idd vaak als een van de nadelen genoemd van operater overloading. Goede documentatie kan echter een verschil makenquote:Op zondag 28 april 2013 20:13 schreef robin007bond het volgende:
[..]
En met grote projecten? Dan moet je helemaal uitzoeken welke classes welke operator overloaden. Voor dat matrix a + matrix b = c kun je ook een aparte methode maken.
Ik denk dat het voor de formules niet veel uitmaakt. Als je de functies/methoden een goede naam geeft is het duidelijk wat de formules doen.quote:Op zondag 28 april 2013 20:16 schreef Dale. het volgende:
[..]
Dat kun je doen maar dan worden complexe formules niet meer goed zichtbaar in dit geval. En het gene wat je zegt word idd vaak als een van de nadelen genoemd van operater overloading. Goede documentatie kan echter een verschil maken
Die bottom lines hebben toch een heel groot duh-gehalte, maar het ergste is een van zijn eerste assumpties. Als x een std::vector is van lengte n, dan wijst &(x[0]) zeker wel naar een contiguous blok geheugen van n elementen. Zou hij de initialisatie van de vector buiten de loop halen (d.w.z., een propere buffer aanleggen), dan was er niets aan de hand; C++ en C zijn verschillende talen en daar moet je ook naar programmeren.quote:Op zondag 28 april 2013 19:16 schreef robin007bond het volgende:
Interessant stukje over de performance-verschillen tussen normale C-arrays en vectors:
http://assoc.tumblr.com/p(...)or-vs-plain-c-arrays
nja, toch is het wel handig als je gewoon A*B=C kan doen en a*B=c of 6*A=B (waar de hoofdletters voor matrices staan en de kleine letters voor vectoren)quote:Op zondag 28 april 2013 20:18 schreef robin007bond het volgende:
[..]
Ik denk dat het voor de formules niet veel uitmaakt. Als je de functies/methoden een goede naam geeft is het duidelijk wat de formules doen.
Die extra documentatie vind ik verspilde uren. Het lijkt zo net eigen werkverschaffing
Klopt niks van. Hij zegt dat vector niet continous is, dat is het wel.quote:Op zondag 28 april 2013 19:16 schreef robin007bond het volgende:
Interessant stukje over de performance-verschillen tussen normale C-arrays en vectors:
http://assoc.tumblr.com/p(...)or-vs-plain-c-arrays
Andere member functies moet je ook opzoeken...quote:Op zondag 28 april 2013 20:13 schreef robin007bond het volgende:
[..]
En met grote projecten? Dan moet je helemaal uitzoeken welke classes welke operator overloaden. Voor dat matrix a + matrix b = c kun je ook een aparte methode maken.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // The IP header struct IPHeader { char h_len:4; // Length of the header in dwords char version:4; // Version of IP char tos; // Type of service unsigned short total_len; // Length of the packet in dwords unsigned short ident; // unique identifier unsigned short flags; // Flags char ttl; // Time to live char proto; // Protocol number (TCP, UDP etc) unsigned short checksum; // IP checksum unsigned long source_ip; unsigned long dest_ip; }; SOCKET hSocket = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | std::cout << "Receiving... "; recv_buff = new IPHeader + 1024; char buff[1024+sizeof(IPHeader)]; int i = recv(hSocket,buff,1024+sizeof(IPHeader),0); if(i == 0) std::cout << "Connection closed\n"; else if(i == SOCKET_ERROR){ std::cout << "Failed!\n"; if(WSAGetLastError() == WSAEMSGSIZE) std::cout << "Buffer is too small!\n"; throw Error(); } else{ std::cout << "Done.\n"; std::cout << '\n'; for(int j = 0; j < i; j++){ //std::cout << tempbuff[j]; } |
1 | recv_buff = new IPHeader + 1024; |
haha, ja dat is het ookquote:Op dinsdag 18 juni 2013 20:17 schreef thabit het volgende:
[ code verwijderd ]
Lijkt me nogal een vreemd stukje code. Wat wil je hier precies mee doen?
En ook een memory leak, want je delete the IPHeader niet.quote:Op dinsdag 18 juni 2013 23:03 schreef netolk het volgende:
[..]
haha, ja dat is het ook
maar dat is zodat de buffer groot genoeg is omdat de ping request toevallig 1024 byte is (dat kan idd veel netter)
bedankt maar dat word ergens aan het einde van het programma gedaanquote:
En wat doet je code dan precies? Deadlock?quote:Op dinsdag 18 juni 2013 19:22 schreef netolk het volgende:
hey, ik zit met een probleempje
Ik ben bezig om data via icmp te versturen (zoals ping ect.)
nu is het zo dat ik via het programmaatje dat ik gemaakt heb wel data kan versturen alleen niet kan ontvangen (wireshark ziet wel een ping reply terug komen).
nu is dit mijn ontvang code:
[ code verwijderd ]
[ code verwijderd ]
Ik weet dat het dus aan dit stukje code moet liggen aangezien wireshark wel een ping reply vind op een request dat ik gemaakt heb
Weet iemand waarom het programmaatje dat pakketje niet onderschept?
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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | // include ook de lib (D:\IDE\MinGW\lib\libws2_32.a) #include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #include <string> /* ICMP codes */ #define ICMP_ECHO_REPLY 0 #define ICMP_DEST_UNREACH 3 #define ICMP_TTL_EXPIRE 11 #define ICMP_ECHO_REQUEST 8 class Error{ }; struct icmp{ unsigned char _TYPE; unsigned char _CODE; unsigned short _CHECKSUM; }; // The IP header struct IPHeader { char h_len:4; // Length of the header in dwords char version:4; // Version of IP char tos; // Type of service unsigned short total_len; // Length of the packet in dwords unsigned short ident; // unique identifier unsigned short flags; // Flags char ttl; // Time to live char proto; // Protocol number (TCP, UDP etc) unsigned short checksum; // IP checksum unsigned long source_ip; unsigned long dest_ip; }; // ICMP header struct ICMPHeader { char type; // ICMP packet type char code; // Type sub code unsigned short checksum; unsigned short id; unsigned short seq; unsigned long timestamp; // not part of ICMP, but we need it }; unsigned short ip_checksum(unsigned short* buffer, int size){ unsigned long cksum = 0; // Sum all the words together, adding the final byte if size is odd while (size > 1) { cksum += *buffer++; size -= sizeof(unsigned short); } if (size) { cksum += *(unsigned char*)buffer; } // Do a little shuffling cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); // Return the bitwise complement of the resulting mishmash return (unsigned short)(~cksum); } unsigned long FindHostIP(const char *pServerName){ std::cout << "Looking up host... "; HOSTENT *pHostent; // Get hostent structure for hostname: if(!(pHostent = gethostbyname(pServerName))){ std::cout << "Failed!\n"; throw Error(); } // Extract primary IP address from hostent structure: if(pHostent->h_addr_list && pHostent->h_addr_list[0]){ std::cout << "Done.\n"; return *reinterpret_cast<unsigned long*>(pHostent->h_addr_list[0]); } return 0; } int main(int argc, char* argv[]){ WSADATA wsaData; unsigned long IP = 0; ICMPHeader *send_buff = 0; IPHeader *recv_buff = 0; if(argc == 1){ std::cout << argv[0] << " [IP adres]\n"; return 0; } std::cout << "inizializing... "; if(WSAStartup(MAKEWORD(2,0),&wsaData)==0){ if(LOBYTE(wsaData.wVersion) >= 2){ std::cout << "Done.\n"; /* hier moet de ICMP verbinding gemaakt worden */ SOCKET hSocket = INVALID_SOCKET; try{ std::cout << "Creating socket... "; if((hSocket = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) == INVALID_SOCKET){ std::cout << "Failed!\n"; throw Error(); } std::cout << "Done.\n"; sockaddr_in sockAddr; sockAddr.sin_family = AF_INET; sockAddr.sin_addr.S_un.S_addr = FindHostIP(argv[1]); std::cout << "Connecting... "; if(connect(hSocket,reinterpret_cast<sockaddr*>(&sockAddr),sizeof(sockAddr))!= 0){ std::cout << "Failed!\n"; throw Error(); } std::cout << "Done.\n"; send_buff = new ICMPHeader; send_buff->type = ICMP_ECHO_REQUEST; send_buff->code = 0; send_buff->checksum = 0; // als 0 dan genereerd zelf send_buff->id = (unsigned short)GetCurrentProcessId(); send_buff->seq = 1; // thread nr??? send_buff->timestamp = GetTickCount(); send_buff->checksum = ip_checksum((unsigned short*)send_buff,1024+sizeof(ICMPHeader)); std::cout << "Sending... "; if(send(hSocket,(char*)send_buff,1024+sizeof(ICMPHeader),0) == SOCKET_ERROR){ std::cout << "Failed!\n"; throw Error(); } std::cout << "Done.\n"; std::cout << "Receiving... "; recv_buff = new IPHeader + 1024; char buff[1024+sizeof(IPHeader)]; int i = recv(hSocket,buff,1024+sizeof(IPHeader),0); if(i == 0) std::cout << "Connection closed\n"; else if(i == SOCKET_ERROR){ std::cout << "Failed!\n"; if(WSAGetLastError() == WSAEMSGSIZE) std::cout << "Buffer is too small!\n"; throw Error(); } else{ std::cout << "Done.\n"; std::cout << '\n'; for(int j = 0; j < i; j++){ //std::cout << tempbuff[j]; } std::cout << "\n-------------\n"; } } catch(Error){ } delete send_buff; delete recv_buff; } else std::cout << "Failed!\n"; std::cout << "Cleaning up winsock... "; if(WSACleanup()!=0) std::cout << "Failed!\n"; else std::cout << "Done.\n"; } else std::cout << "Failed!\n"; return 0; } |
De buffer die gereserveerd wordt is gewoon sizeof(IPHeader) bytes in dat stukje code. Het enige wat + 1024 doet, is 1024*sizeof(IPHeader) (en niet 1024) bytes bij de pointer optellen optellen. Lijkt me dus iets wat in alle opzichten fout is.quote:Op dinsdag 18 juni 2013 23:03 schreef netolk het volgende:
[..]
haha, ja dat is het ook
maar dat is zodat de buffer groot genoeg is omdat de ping request toevallig 1024 byte is (dat kan idd veel netter)
hij komt bij het block recv aan alleen vervolgens blijft hij daar "wachten" en doet dan dus niks meerquote:Op woensdag 19 juni 2013 01:43 schreef trancethrust het volgende:
Het probleem is meer dat we geen glazen bol hebben. Een recv blockt totdat hij wat ontvangt. Als je programma niet vastloopt, heeft hij dus wel wat ontvangen; de vraag is dan wat. Als het programma wel vastloopt dan komt het bericht nooit bij de recv aan en is er compleet wat anders aan de hand.
ow, dat is idd niet de bedoeling (normaal doe ik het wel eens met een char maar gezien dat die 1 byte is klopt dat sowieso... hoe kan ik hem dan de grote van 1024 bytes + de sizeof(IPHeader) geven? is new char + (1024+sizeof(IPHeader)) daar de enige optie voor? Vind ik er namelijk niet netjes uitzienquote:Op woensdag 19 juni 2013 08:54 schreef thabit het volgende:
[..]
De buffer die gereserveerd wordt is gewoon sizeof(IPHeader) bytes in dat stukje code. Het enige wat + 1024 doet, is 1024*sizeof(IPHeader) (en niet 1024) bytes bij de pointer optellen optellen. Lijkt me dus iets wat in alle opzichten fout is.
Dat is een deadlock. Die message komt dus nooit aan bij de recv. Ervanuitgaande dat er geen bug zit in die code, moet je echt in de hoek zoeken van een firewall die ICMP/jouw applicatie blokkeert, of het luisteren op de verkeerde poort. Controleren of de socket open is alvorens de recv aan te roepen is ook handig.quote:Op woensdag 19 juni 2013 10:27 schreef netolk het volgende:
[..]
hij komt bij het block recv aan alleen vervolgens blijft hij daar "wachten" en doet dan dus niks meer
Precies.quote:[..]
ow, dat is idd niet de bedoeling (normaal doe ik het wel eens met een char maar gezien dat die 1 byte is klopt dat sowieso... hoe kan ik hem dan de grote van 1024 bytes + de sizeof(IPHeader) geven? is new char + (1024+sizeof(IPHeader)) daar de enige optie voor? Vind ik er namelijk niet netjes uitzien
EDIT: zie net dat die recv_buff toch niet gebruikt word.
zucht haat aan code die ik niet zelf geschreven heb
hmm, ICMP heeft geen poort maar dat terzijde.quote:Op woensdag 19 juni 2013 10:32 schreef trancethrust het volgende:
[..]
Dat is een deadlock. Die message komt dus nooit aan bij de recv. Ervanuitgaande dat er geen bug zit in die code, moet je echt in de hoek zoeken van een firewall die ICMP/jouw applicatie blokkeert, of het luisteren op de verkeerde poort. Controleren of de socket open is alvorens de recv aan te roepen is ook handig.
[..]
Precies.
Bovendien maak je hier een denkfout; als iets van de grootte 1024+sizeof(IPHeader) is, dan is het geen IPHeader meer. Je `new char' notatie maakt bovendien precies dezelfde fout; hij alloceert 4 bytes en sprint dan 1024+x bytes ernaast.quote:Op woensdag 19 juni 2013 10:27 schreef netolk het volgende:
[..]
ow, dat is idd niet de bedoeling (normaal doe ik het wel eens met een char maar gezien dat die 1 byte is klopt dat sowieso... hoe kan ik hem dan de grote van 1024 bytes + de sizeof(IPHeader) geven? is new char + (1024+sizeof(IPHeader)) daar de enige optie voor? Vind ik er namelijk niet netjes uitzien
..
OKquote:Op woensdag 19 juni 2013 10:34 schreef netolk het volgende:
[..]
hmm, ICMP heeft geen poort maar dat terzijde.
Volgens mij het gedrag van recv ongedefineerd wanneer het een ongeldige socket wordt gevoerd.quote:Zal idd even een check er voor gooien die checkt of de socket nog wel open is (maar zou recv niet gewoon 0 moeten returnen als de socket niet meer open is?)
[..]
goed punt.quote:Op woensdag 19 juni 2013 10:37 schreef trancethrust het volgende:
[..]
Bovendien maak je hier een denkfout; als iets van de grootte 1024+sizeof(IPHeader) is, dan is het geen IPHeader meer. Je `new char' notatie maakt bovendien precies dezelfde fout; hij alloceert 4 bytes en sprint dan 1024+x bytes ernaast.
Wat je wilt is new char[ 1024+sizeof(IPHeader) ] maar dit is totaal geen C++ meer. Beter maak je een klasse gebaseerd op IPHeader die als eerste veld iets van 1024 heeft, en alloceer je dat gevaarte. Let wel dat het me nog steeds compleet onduidelijk is wat de bedoeling is van die 1024 bytes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | std::cout << "Receiving... "; int result = 0; fd_set socks; struct timeval t; /* Set socket listening descriptors */ FD_ZERO(&socks); FD_SET(hSocket, &socks); if((result = select(hSocket + 1, &socks, 0, 0, &t)) < 0){ std::cout << "Failed!.\nCould not select socket.\n"; throw Error(); } else if(result > 0){ char recv_buff[4048]; sockaddr_in dst; int dst_addr_len = sizeof(dst); //int Received_bytes = recv(hSocket, (char*)recv_buff,sizeof(recv_buff),0); int Received_bytes = recv(hSocket, recv_buff, sizeof(recv_buff), 0); std::cout << "\nReceived bytes: " << Received_bytes << ".\n";// temp } else std::cout << "Failed!\nPacket not received.\n"; |
die timeout is op 5 sec gezet dat klopt want daarna stopt het programma.quote:Op woensdag 19 juni 2013 12:14 schreef trancethrust het volgende:
Moet je je timeout niet zetten? Stel dat de compiler t initialiseert als 0, dan wordt select een poll ipv een wait-to-get-ready.
Wat gebeurt overigens eerst? Een program exit of het binnenkomen van die reply?
Dus je socket is na 5 seconden nog steeds niet klaar voor ontvangst zoals gedetecteerd door gebruik van select, metgevolg dat je dat detectiemechanisme eruit haalt? Is het niet logischer te onderzoeken waarom je socket nooit klaar is om uitgelezen te worden?quote:Op woensdag 19 juni 2013 13:24 schreef netolk het volgende:
[..]
die timeout is op 5 sec gezet dat klopt want daarna stopt het programma.
Ondertussen die select er weer uitgesloopt aangezien het niet werkte en volgens mij overbodig is.
overigens ping ik naar de router en heb ik bijna meteen (lees 1ms) een ping reply terug alleen onderschept mijn programma dat niet
Het programma blijft namelijk tot in den treuren wachten op een pakketje
Dat is dus het punt ik kan niks raars vinden waardoor het niet zou moeten werken. Had ooit een http request programma gemaakt en daar werkte de boel wel gewoon (zonder select)quote:Op woensdag 19 juni 2013 13:58 schreef trancethrust het volgende:
[..]
Dus je socket is na 5 seconden nog steeds niet klaar voor ontvangst zoals gedetecteerd door gebruik van select, metgevolg dat je dat detectiemechanisme eruit haalt? Is het niet logischer te onderzoeken waarom je socket nooit klaar is om uitgelezen te worden?
Tijdens debuggen moet je de fout proberen te isoleren; select helpt door te detecteren dat het probleem bij de socket zit. Ik zou daaruit verder gaan met isoleren; ligt het aan een firewall / heeft je programma wel rechten om een socket te openen? Is je socket-initialisatie code wel OK?quote:Op woensdag 19 juni 2013 14:08 schreef netolk het volgende:
[..]
Dat is dus het punt ik kan niks raars vinden waardoor het niet zou moeten werken. Had ooit een http request programma gemaakt en daar werkte de boel wel gewoon (zonder select)
Ja, ik ken het principe wel.quote:Op woensdag 19 juni 2013 14:13 schreef trancethrust het volgende:
[..]
Tijdens debuggen moet je de fout proberen te isoleren; select helpt door te detecteren dat het probleem bij de socket zit. Ik zou daaruit verder gaan met isoleren; ligt het aan een firewall / heeft je programma wel rechten om een socket te openen? Is je socket-initialisatie code wel OK?
Bedenk oorzaken en vind methodes om te controleren of je hypothese klopt of niet. Zo ja, zoek verder in die richting, zo nee, vind een nieuwe hypothese. Dat is zo'n beetje de debug-cyclus en ja, dat kan vervelend zijn.
Is ICMP synchroon? Ik denk dan meer aan TCP ofzo. Misschien is select helemaal niet van toepassing?quote:The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O.
Ligt de sleutel dan in het gebruiken van recvfrom ipv recv?quote:Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using sendto and recvfrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer using send and can be received only from this peer using recv.
Ja, zat ook al te denken dat het recvfrom moet zijn dat is nu ook wat ik gebruik maar tot nu toe nog steeds het zelfde probleemquote:Op woensdag 19 juni 2013 15:46 schreef trancethrust het volgende:
M.i. moet het iets basaals zijn als functies als select en recv misgaan.
[..]
Is ICMP synchroon? Ik denk dan meer aan TCP ofzo. Misschien is select helemaal niet van toepassing?
[..]
Ligt de sleutel dan in het gebruiken van recvfrom ipv recv?
SPOILEROm spoilers te kunnen lezen moet je zijn ingelogd. Je moet je daarvoor eerst gratis Registreren. Ook kun je spoilers niet lezen als je een ban hebt.Ik vraag me nu alleen af of ik bij de recvfrom functie de buffer grote niet via een sizeof() kan doen ipv. de 1500 die er nu staat (want ja dat ga je natuurlijk geheid vergeten als je de buffer grote aanpast)Beware of the Raping Zebra's
1 2 3 | struct receive_buffer { char buffer[ 1500 ]; }; |
Nee, klopt had ik idd al bedacht was meer dat ik niet zo bekent ben met memcpy en memset dus in dat opzicht had ik dat gekopieerd van iemand anders zijn code (snap wel wat het doet) Had idd ook gewoon de & en * kunnen gebruiken.quote:Op donderdag 20 juni 2013 00:54 schreef trancethrust het volgende:
Je kan er een struct van maken als in
[ code verwijderd ]
Een sizeof(receive_buffer) is dan 1500*sizeof(char).
(Overigens is dynamisch alloceren van de receive-buffer via new niet nodig)
1 | char RecvBuff[1500]; |
1 | recvfrom(Sock,RecvBuff,sizeof(RecvBuff),0,0,0); |
Die struct stond er voor een redenquote:Op donderdag 20 juni 2013 09:40 schreef netolk het volgende:
[..]
Nee, klopt had ik idd al bedacht was meer dat ik niet zo bekent ben met memcpy en memset dus in dat opzicht had ik dat gekopieerd van iemand anders zijn code (snap wel wat het doet) Had idd ook gewoon de & en * kunnen gebruiken.
maar stel dat ik de buffer statisch alloceer als
[ code verwijderd ]
Dan zou je zeggen dat dit ook zou moeten werken
[ code verwijderd ]
Maar dat werkt dus niet en faalt de recvfrom functie
1 | T x[ n ] |
klinkt logisch iddquote:Op donderdag 20 juni 2013 09:51 schreef trancethrust het volgende:
[..]
Die struct stond er voor een reden
Een
[ code verwijderd ]
alloceert een statische array van type T en grootte n. De type van x is dan dus een array van T, ofwel een pointer naar T, en de size daarvan is sizeof( void* ).
Als je de boel in een struct gooit, dan neemt de struct de grootte van alle velden, dus de grootte van de totale char array.
Een *recvbuffer is een pointer, dus wederom 4 of 8 bytes. sizeof(recvbuffer) is wat je wilt (als recvbuffer een struct is dat de char-array bevat, zoals hierboven).quote:Op donderdag 20 juni 2013 09:58 schreef netolk het volgende:
[..]
klinkt logisch idd
maar dan zou sizeof(*recvBuff) ook moeten werken maar bij de dynamische allocatie kreeg ik daar ook een error van recvfrom
k, dus sizeof neemt alleen de grote van het object wat je er instopt en niet waar het naar verwijst ongeacht het gebruikt van * ?quote:Op donderdag 20 juni 2013 10:04 schreef trancethrust het volgende:
[..]
Een *recvbuffer is een pointer, dus wederom 4 of 8 bytes. sizeof(recvbuffer) is wat je wilt (als recvbuffer een struct is dat de char-array bevat, zoals hierboven).
http://en.cppreference.com/w/cpp/language/sizeofquote:Op donderdag 20 juni 2013 10:08 schreef netolk het volgende:
[..]
k, dus sizeof neemt alleen de grote van het object wat je er instopt en niet waar het naar verwijst ongeacht het gebruikt van * ?
Grootte van het type van het object dat je erin stopt, inderdaad, of de grootte van het type dat je meegeeft (sizeof werkt op zowel objecten/instances als datatypes). Dit is ook precies wat je wilt.quote:Op donderdag 20 juni 2013 10:08 schreef netolk het volgende:
[..]
k, dus sizeof neemt alleen de grote van het object wat je er instopt en niet waar het naar verwijst ongeacht het gebruikt van * ?
Uhm, nee?quote:Op donderdag 20 juni 2013 09:51 schreef trancethrust het volgende:
[..]
Die struct stond er voor een reden
Een
[ code verwijderd ]
alloceert een statische array van type T en grootte n. De type van x is dan dus een array van T, ofwel een pointer naar T, en de size daarvan is sizeof( void* ).
Als je de boel in een struct gooit, dan neemt de struct de grootte van alle velden, dus de grootte van de totale char array.
1 2 3 4 5 6 | long buffer[256]; int True = (sizeof(buffer) == 1024); for(int i=0; i<sizeof(buffer)/sizeof(*buffer); i++) printf("%d\n", buffer[i]); |
Oh. Redelijk stonedquote:
SPOILEROm spoilers te kunnen lezen moet je zijn ingelogd. Je moet je daarvoor eerst gratis Registreren. Ook kun je spoilers niet lezen als je een ban hebt.More oneness, less categories
Open hearts, no strategies
Decisions based upon faith and not fear
People who live right now and right here
quote:Op vrijdag 21 juni 2013 16:32 schreef trancethrust het volgende:
[..]
Oh. Redelijk stonedBlijkbaar wordt een (niet-dynamische array) als een soort struct gezien; nooit geweten!
sizeof geeft size van een object, een C array is ook gewoon een object.SPOILEROm spoilers te kunnen lezen moet je zijn ingelogd. Je moet je daarvoor eerst gratis Registreren. Ook kun je spoilers niet lezen als je een ban hebt.
Alleen zijn C arrays best wel klote want je kan niet pass by value doen, alleen maar by reference.
En als je dus in een function sizeof doet van je parameter "array" krijg je size van je reference ipv array.
http://ideone.com/jcU5D8
ahh, vandaarquote:Op vrijdag 21 juni 2013 19:10 schreef t4rt4rus het volgende:
[..]
sizeof geeft size van een object, een C array is ook gewoon een object.
Alleen zijn C arrays best wel klote want je kan niet pass by value doen, alleen maar by reference.
En als je dus in een function sizeof doet van je parameter "array" krijg je size van je reference ipv array.
http://ideone.com/jcU5D8
Ah ik snap de tegenstelling nu. Mijn eerste reactie was `dit is nog lelijker dan een struct'`, maar de grap is natuurlijk dat als een C array geen aparte datatype was, dat een struct zoals hier ook nooit zou kunnen werken; de struct zou anders precies de grootte zijn van een array pointer.quote:Op vrijdag 21 juni 2013 19:10 schreef t4rt4rus het volgende:
[..]
sizeof geeft size van een object, een C array is ook gewoon een object.
Alleen zijn C arrays best wel klote want je kan niet pass by value doen, alleen maar by reference.
En als je dus in een function sizeof doet van je parameter "array" krijg je size van je reference ipv array.
http://ideone.com/jcU5D8
Je weet dat het zetten van struct voor de typename C is en niet nodig (deprecated?) in C++?quote:Op vrijdag 21 juni 2013 23:53 schreef trancethrust het volgende:
[..]
Ah ik snap de tegenstelling nu. Mijn eerste reactie was `dit is nog lelijker dan een struct'`, maar de grap is natuurlijk dat als een C array geen aparte datatype was, dat een struct zoals hier ook nooit zou kunnen werken; de struct zou anders precies de grootte zijn van een array pointer.
En een pass-by-value zou nooit letterlijk kunnen omdat de grootte van een argument nooit compile-time bepaald kon worden. Noodzakelijk kwaad. Cool, weer wat geleerd.
http://ideone.com/swuvZrquote:Op zaterdag 22 juni 2013 00:15 schreef t4rt4rus het volgende:
[..]
Je weet dat het zetten van struct voor de typename C is en niet nodig (deprecated?) in C++?
Het was meer een discussie over waarom een T foo[500] geen T*-type had, wat (mij) aanvankelijk veel natuurlijker leek. Persoonlijk als ik arrays doorgeef gebruik ik pointers/iterators, het andere komt me wat onnatuurlijk over.quote:Zie std::array als je een array als value will passen.
In C++14 komt er waarschijnlijk een dynamic array.
nee, ik heb een boek uit 2002 van hem (wel is waar vertaald naar NL in die tijd was ik nog niet zo'n voorstander van Engelse boeken)quote:Op zondag 23 juni 2013 01:07 schreef t4rt4rus het volgende:
Is er al iemand die Stroustrups nieuwe boek heeft?
En zijn er mensen die C++14 een beetje volgen?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | for (size_t y = 0; y < p_Par->Xtion.CanvasYRes; y = y++) { for (size_t x = 0; x < p_Par->Xtion.CanvasXRes; x = x++) { float py = OpenNiDataObj->OriginalYMatrix.at<float>(y,x); float px = OpenNiDataObj->OriginalXMatrix.at<float>(y,x); if ((abs(px-Par->obj.leftx)<10 || abs(px-Par->objrightx)<10) && py!=0) { OpenNiDataObj->OriginalYMatrix.at<float>(y,x)=-501; } } } |
Dit is een derde snellerquote:Op donderdag 5 december 2013 13:40 schreef Gehenna het volgende:
Je zou met een Lambda functie de 2 for loops kunnen vervangen.
Maar dat is waarschijnlijk minder leesbaard dan 2 for loops, om nog maar te zwijgen over de potentiële snelheidsverlies...
Of het sneller kan, zou je dat even in de OpenCV documentatie moeten halen (wellicht zijn er bepaalde iterators die je kunt gebruiken). maar zo bekend ben ik niet met OpenCV.
1 2 3 4 5 6 7 8 9 10 11 12 13 | for (size_t y = 0; y < p_Par->Xtion.CanvasYRes;y=y++) { float* My = (p_OpenNiDataObj->ZMatrix).ptr<float>(y); for (size_t x = 0; x < p_Par->Xtion.CanvasXRes; x = x++) { float& Myx = My[x]; } } [code] Maar waar ik eigenlijk naar op zoek was is iets als [code] matrixoperation(doeditendat); |
1 2 3 4 5 6 7 | for (size_t y = 0; y < p_Par->Xtion.CanvasYRes;y=y++) { float* My = (p_OpenNiDataObj->ZMatrix).ptr<float>(y); for (size_t x = 0; x < p_Par->Xtion.CanvasXRes; x = x++) { doeditendat } } |
1 2 3 | matrixoperation( (if(px)<40 || px>80){px=2}); of matrixoperation((if(px)<40 || px>80){sumx++},pointertosumx); |
Als ik het goed begrijp wil je dus graag een functie 'doeditendat' meegeven als argument van de functie 'matrixoperation'?quote:Op donderdag 5 december 2013 14:14 schreef Holy_Goat het volgende:
[..]
Dit is een derde sneller
[ code verwijderd ]
en de bijbehorende functie dan zoiets is als
[ code verwijderd ]
Doeditendat is altijd iets simpels. Soms trekt het lijntjes als x = iets, soms somt het alle waarden op, etc.
Denk het wel jaquote:Op donderdag 5 december 2013 14:53 schreef Gehenna het volgende:
[..]
Als ik het goed begrijp wil je dus graag een functie 'doeditendat' meegeven als argument van de functie 'matrixoperation'?
Dan is dit wellicht iets voor je: http://stackoverflow.com/(...)-as-a-parameter-in-c
Ja, hier staat namelijk een oneindige loop.quote:Op donderdag 5 december 2013 12:29 schreef Holy_Goat het volgende:
for (size_t y = 0; y < p_Par->Xtion.CanvasYRes; y = y++)
Dit moet toch sneller kunnen?
En in die oneindige loop nog een oneindige loopquote:Op donderdag 5 december 2013 19:59 schreef thabit het volgende:
[..]
Ja, hier staat namelijk een oneindige loop.
Ja verbaasde mij ook alquote:
Kom maar op met de vragenquote:Op vrijdag 6 december 2013 03:42 schreef netolk het volgende:
[..]
Ja verbaasde mij ook al
Normaal was ik de gene die het actief hield met vragen
Die for-loops van jou zijn niet zo groot.quote:Op donderdag 5 december 2013 15:06 schreef Holy_Goat het volgende:
[..]
Denk het wel ja
Vind het gewoon een beetje naar om o-ve-ral die dubbele forloop te hebben (ook al is het wel sneller)
Dus daar is op zich niets op tegen? Ik dacht dat als je dingen vaak gebruikte je moest bedenken of je niet iets anders compacters moest bedenkenquote:Op vrijdag 6 december 2013 11:54 schreef t4rt4rus het volgende:
[..]
Die for-loops van jou zijn niet zo groot.
Kan je makkelijk in meerdere functies stoppen.
Sorry, momenteel met m'n minor bezig en daar moeten we een game in javaquote:
eventueel als je vaak dezelfde loops gebruikt zou je ze nog in een andere methode kunnen zetten. Soms word je code daar leesbaarder van maar dat is het dan ookquote:Op vrijdag 6 december 2013 14:06 schreef Holy_Goat het volgende:
[..]
Dus daar is op zich niets op tegen? Ik dacht dat als je dingen vaak gebruikte je moest bedenken of je niet iets anders compacters moest bedenken
Een game in Java. Ik heb echt medelijden.quote:Op vrijdag 6 december 2013 19:19 schreef netolk het volgende:
[..]
Sorry, momenteel met m'n minor bezig en daar moeten we een game in java![]()
maken
[..]
eventueel als je vaak dezelfde loops gebruikt zou je ze nog in een andere methode kunnen zetten. Soms word je code daar leesbaarder van maar dat is het dan ook
Ja, weet ook niet waarom ze dat bedacht hebben....quote:Op vrijdag 6 december 2013 19:21 schreef robin007bond het volgende:
[..]
Een game in Java. Ik heb echt medelijden.
Een beetje off-topic, maar voor een schoolproject maak ik ook een game in XNA. Wat een ramp. C++ en SFML.
C# (c sharp) misschien?quote:Op vrijdag 6 december 2013 21:38 schreef robin007bond het volgende:
Op de een of andere manier gaat OOP mij moeilijker af in C++ dan in Java. De header-files vind ik zo'n zooitje.
Als ik een C+=2 zou maken zouden die header files er definitief uit mogen.
CSharp lukt me ook prima, maar er zijn dingen waarvoor je liever C++ gebruikt.quote:Op vrijdag 6 december 2013 22:24 schreef Gehenna het volgende:
[..]
C# (c sharp) misschien?
En anders Python proberen
Java is dan ook mijn favoriet, maar serieus, die header files zijn heus zo erg niet.quote:Op vrijdag 6 december 2013 21:38 schreef robin007bond het volgende:
Op de een of andere manier gaat OOP mij moeilijker af in C++ dan in Java. De header-files vind ik zo'n zooitje.
Als ik een C+=2 zou maken zouden die header files er definitief uit mogen.
Als ik eerlijk ben vind ik het echt een last.quote:Op vrijdag 6 december 2013 23:21 schreef Crutch het volgende:
[..]
Java is dan ook mijn favoriet, maar serieus, die header files zijn heus zo erg niet.
tja het is maar een regeltje per toegevoegde functie, is dat nu echt zo erg? (toegegeven het is niet ideaal vanaf de programmeurs kant gezien)quote:Op vrijdag 6 december 2013 23:48 schreef robin007bond het volgende:
[..]
Als ik eerlijk ben vind ik het echt een last.
En het verschil tussen een abstracte klasse in Java en een Virtual in C++ is me na wat ingelezen te hebben ook niet zo duidelijk.
Maar de headers, tsja. Elke keer als je iets toevoegt moet je ook gelijk de headers aanpassen. Het werkt echt contraproductief.
1 2 3 4 | int daysInstalled = util.getDaysInstalled(context); int random = new Random().nextInt(10); if (random == 0 & daysInstalled > 2) { |
Absoluut niet. Groot verschil is hierbij dat booleans in C gewoon een integraal datatype zijn en (in C++) automatisch gepromoveerd worden tot integers voor bitwise berekeningen, terwijl in Java er een aparte overload is voor bitwise & op boolean types. In C evalueert bitwise & altijd tot een integer type, terwijl in dit geval Java een Boolean type teruggeeft.quote:Op zaterdag 7 december 2013 11:45 schreef MichielPH het volgende:
volgens mij komen C en Java op dit basale niveau precies overeen
Ah, leuk om te weten!quote:Op zaterdag 7 december 2013 11:58 schreef GS42 het volgende:
[..]
Absoluut niet. Groot verschil is hierbij dat booleans in C gewoon een integraal datatype zijn en gepromoveerd worden tot integers voor bitwise berekeningen, terwijl in Java er een aparte overload is voor bitwise & op boolean types. In C evaluaeert bitwise & altijd tot een integraal type, terwijl in dit geval Java een Boolean type teruggeeft.
Ik had zelf ook verwacht dat het resultaat niet anders zou zijn. Toch komt daysInstalled met waarden van -1, 0, 1, 2 en groter voor in m'n logs, dus er gaat iets mis. Ik kan met 100% zekerheid zeggen dat dat gelogd wordt doordat die statement true is.quote:> Wat gaat er mis?
In jouw voorbeeld, grappig genoeg: niets. De code werkt precies hetzelfde met & of &&, met als enige uitzondering dat bij (A & B) altijd zowel A als B geevalueerd wordt, terwijl bij (A && B) de waarde van B alleen wordt geevalueerd als A true is. Dit gedrag van && heet "short circuiting". Aangezien jouw vergelijkingen geen bijwerkingen hebben, is het resultaat hetzelfde (maar iets minder efficient).
Zie http://docs.oracle.com/ja(...)-15.html#jls-15.22.2 voor details.
(Let op lezers: we hebben het nog steeds over Java.)quote:Op zaterdag 7 december 2013 12:13 schreef MichielPH het volgende:
Ik had zelf ook verwacht dat het resultaat niet anders zou zijn. Toch komt daysInstalled met waarden van -1, 0, 1, 2 en groter voor in m'n logs, dus er gaat iets mis. Ik kan met 100% zekerheid zeggen dat dat gelogd wordt doordat die statement true is.
1 2 3 4 5 6 7 8 | for (size_t y = 0; y < p_Par->Xtion.CanvasYRes;y=y++) { float* My = (p_OpenNiDataObj->ZMatrix).ptr<float>(y); for (size_t x = 0; x < p_Par->Xtion.CanvasXRes; x = x++) { float& Myx = My[x]; doe dingen met Myx } } |
1 2 3 4 5 6 7 8 9 10 | for (size_t y = 0; y < p_Par->Xtion.CanvasYRes;y=y++) { float* My = (p_OpenNiDataObj->ZMatrix).ptr<float>(y); for (size_t x = 0; x < p_Par->Xtion.CanvasXRes; x = x++) { Doe dingen met *My My++; //increment de pointer dus, ipv My[x] in een Myx reference zetten } } |
1 2 3 4 5 6 7 8 9 10 11 12 | if (waarde==0) { //doe niets, en de waarde 0 komt 90% van de tijd voor } else if ( waarde == 1 ) { //doe iets met betrekking op gevonden waarde 1, komt 5% van de tijd voor } else if ( waarde == 2) { //doe iets met betrekking op gevonden waarde 2, komt het minst voor } |
1 2 3 4 5 6 7 8 | if ( waarde == 1 ) { //doe iets met betrekking op gevonden waarde 1, komt 5% van de tijd voor } else if ( waarde == 2) { //doe iets met betrekking op gevonden waarde 2, komt het minst voor } |
Je zou zeggen van wel, en vroeger was dit ook vaak het geval. Maar tegenwoordig blijkt dat dit vooral aan de processor ligt waarmee je werkt. Ik zou zeggen probeer beide eens. Timer functie erom heen en kijk welke het snelst is (ik ben zelf ook wel benieuwd)quote:Op maandag 9 december 2013 09:56 schreef Holy_Goat het volgende:
Bonusvraag:
De Matrices waar ik mee werk zijn 320x240, en bevatten float data. Echter, de punten achter de komma zijn voor mij volkomen irrelevant.
Zou het programma met de vele loops die dus ook de vele float waarden aandoet er veel sneller van worden op het moment dat ik de matrices bij het verkrijgen al om zou zetten naar signed int zodat het complete programma met ints werkt?
Omdat er geen operatie bij if(waarde == 0) wordt gedaan, wordt deze if bij (verre weg de meeste) compilers weggegooid bij de optimalisatie. Dus er zal als het goed is geen verschil zijn in de performance tussen beide algoritmes.quote:Bonusvraag2: (triviaal?)
Ik weet dat de volgorde van if/else if statements de performance kan beinvloeden. De eerste statement voor wat je verwacht dat het vaakst gaat voorkomen, de tweede wat je iets minder vaak verwacht, etc.
Maar het gebeurt ook wel dat je waarden tegenkomt (vaak!) waar je niets mee doen wilt.
Is bovenste code dan beter dan de onderste?
[ code verwijderd ]
[ code verwijderd ]
Dan maak je er ints van, ook al maakt het niets uit qua snelheid.quote:Op maandag 9 december 2013 09:56 schreef Holy_Goat het volgende:
Bonusvraag:
De Matrices waar ik mee werk zijn 320x240, en bevatten float data. Echter, de punten achter de komma zijn voor mij volkomen irrelevant.
switch/case. Of je gaat richting ijle matrices voor de minder-voorkomende waarden?quote:...
Bonusvraag2: (triviaal?)
Ik weet dat de volgorde van if/else if statements de performance kan beinvloeden. De eerste statement voor wat je verwacht dat het vaakst gaat voorkomen, de tweede wat je iets minder vaak verwacht, etc.
Maar het gebeurt ook wel dat je waarden tegenkomt (vaak!) waar je niets mee doen wilt.
Is bovenste code dan beter dan de onderste?
[ code verwijderd ]
[ code verwijderd ]
Hoe kun je dan het beste er voor zorgen dat het proces zo min mogelijk tijd kwijt is bij tegenkomen van een 0? Anders gaat ie voor elke 0 toch allebei de ifs checkenquote:Op maandag 9 december 2013 10:42 schreef Gehenna het volgende:
[..]
Je zou zeggen van wel, en vroeger was dit ook vaak het geval. Maar tegenwoordig blijkt dat dit vooral aan de processor ligt waarmee je werkt. Ik zou zeggen probeer beide eens. Timer functie erom heen en kijk welke het snelst is (ik ben zelf ook wel benieuwd)
[..]
Omdat er geen operatie bij if(waarde == 0) wordt gedaan, wordt deze if bij (verre weg de meeste) compilers weggegooid bij de optimalisatie. Dus er zal als het goed is geen verschil zijn in de performance tussen beide algoritmes.
Verder is de volgorde van de if statements idd wel iets wat je in je achterhoofd wil houden, je moet zorgen dat wat het vaakst voorkomt ook als eerste wordt geëvalueerd.
Dat geld ook voor 'nested conditions' zoals:
if ( (A && B) || (C && D) )
waarbij geld:
1. if A is false, goto 3.
2. if B is true, return true.
3. if C is false, return false.
4. if D is false, return false
1 2 3 4 5 6 7 8 9 10 11 12 | #define RED(x) ((x)&0xff) #define GREEN(x) (((x)&0xff)<<8) #define BLUE(x) (((x)&0xff)<<16) static const unsigned c_width = 320; static const unsigned c_height = 240; unsigend long canvas[c_width * c_height] = {0}; unsigned long *pix = canvas; for(int y=0; y<c_height; y++) for(int x=0; x<c_width; x++) *pix++ = RED(x / 2) | GREEN(y/2); |
oh wacht daar heb je gelijk in idd (Ik ben net wakkerquote:Op maandag 9 december 2013 10:54 schreef Holy_Goat het volgende:
[..]
Hoe kun je dan het beste er voor zorgen dat het proces zo min mogelijk tijd kwijt is bij tegenkomen van een 0? Anders gaat ie voor elke 0 toch allebei de ifs checken
Forum Opties | |
---|---|
Forumhop: | |
Hop naar: |