t4rt4rus | zondag 12 augustus 2012 @ 15:28 |

Het topic over de programmeertalen C en C++. Als je vragen over C of C++ hebt, zit je hier goed. Natuurlijk kan je ook gewoon mee kletsen.
Let er bij het stellen van een vraag op dat je zo veel mogelijk revelante informatie geeft, zoals: - wat je probeert te doen; - welk besturingsysteem je hebt; - welke compiler en versie je gebruikt; - de eventuele foutmelding die je ziet; - een minimaal codevoorbeeld dat je fout veroorzaakt.
FAQ
Wat is het verschil tussen C en C++?
De programmeertalen C en C++ hebben veel overeenkomsten. C++ is begonnen als een uitbreiding op C en ondersteunt bijna de volledige C-taal. Dit betekent dat een computerprogramma geschreven in C meestal ook een geldig C++-programma is.
C++ heeft onderdelen aan de C-taal toegevoegd en ondersteunt verschillende programmeerstijlen beter. C++ heeft onder andere sterkere typechecking, betere manieren om data te encapsuleren en eenvoudigere structuren om algemene code te schrijven. C is echter nog steeds beter ondersteund op 'afwijkende' platformen en wordt mede daarom nog veel gebruikt.
Zie Stroustrups FAQ voor meer informatie.
Ik wil beginnen met C of C++; welke moet ik kiezen?
Dat hangt van jou af: er is geen direct 'betere' keuze. Je hoeft zeker geen C te leren voordat je aan C++ begint: het is waarschijnlijk zelfs beter van niet. Zorg in de eerste plaats voor een goed leerboek, de online informatie en 'cursussen' laat vaak te wensen over voor de beginneling.
Wat is een goed boek voor C of C++
Zie wederom Stroustrups FAQ.
Links
Naslagwerken
C/C++ Reference The C Library Reference Guide C++ Documentation C++ Annotations
Achtergrond The Association of C and C++ Users Stroustrup's homepage
Deze OP vind je hier. |
t4rt4rus | zondag 12 augustus 2012 @ 15:31 |
w00t OP is al een stuk beter, goed gedaan GS42!
Ik kijk later zelf wel even wat we kunnen toevoegen. |
ari_zahav | zondag 12 augustus 2012 @ 15:39 |
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? 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. |
thenxero | zondag 12 augustus 2012 @ 16:06 |
quote: 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:
"It seems like this project has not been built yet. Do you want to build it now?" Vervolgens druk je op "Ja" en dan krijg ik weer hetzelfde bericht. Ik heb net een minuut lang enter ingedrukt maar het bericht blijft maar terugkomen  |
ari_zahav | zondag 12 augustus 2012 @ 16:23 |
Geen idee wat dat zou kunnen zijn. Ik zou de error even googlen als ik jou was  |
thenxero | zondag 12 augustus 2012 @ 16:46 |
quote: Gefixt, het werkt nu  |
t4rt4rus | zondag 12 augustus 2012 @ 16:58 |
quote: En hoe? |
thenxero | zondag 12 augustus 2012 @ 17:01 |
quote: Moest gewoon nog een path aanpassen naar de goede compiler 
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  |
t4rt4rus | zondag 12 augustus 2012 @ 17:04 |
Met GMP duurt het 0.003s om op te lossen. |
thenxero | zondag 12 augustus 2012 @ 17:17 |
quote: 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.
100! berekent ie ook binnen 50ms op mijn langzame netbookje
[ Bericht 5% gewijzigd door thenxero op 12-08-2012 17:28:28 ] |
t4rt4rus | zondag 12 augustus 2012 @ 17:44 |
Opdracht 25 is ook leuk  1000 digits  |
t4rt4rus | zondag 12 augustus 2012 @ 18:06 |
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?
[ Bericht 39% gewijzigd door t4rt4rus op 12-08-2012 19:02:23 ] |
thenxero | zondag 12 augustus 2012 @ 18:57 |
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 * 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? Ik snap de vraag niet eens want ze zeggen niet hoe je de elementen moet permuteren |
t4rt4rus | zondag 12 augustus 2012 @ 18:59 |
quote: Staat er toch gewoon?
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?
|
thenxero | zondag 12 augustus 2012 @ 19:03 |
quote: Na wat gegoogle begrijp ik dat je ze moet sorteren op grootte, maar dat haal ik niet echt uit de vraag |
t4rt4rus | zondag 12 augustus 2012 @ 19:33 |
quote: Het staat er gewoon...
quote: If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. edit: En zelf nog een voorbeeld
quote: The lexicographic permutations of 0, 1 and 2 are:
012 021 102 120 201 210
[ Bericht 13% gewijzigd door t4rt4rus op 12-08-2012 19:39:07 ] |
thenxero | zondag 12 augustus 2012 @ 19:43 |
quote: 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 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?
Volgens mij klopt dat wel
Je idee klopt wel maar volgens mij moet je met 9! beginnen... dus k * 9! + ... etc |
t4rt4rus | zondag 12 augustus 2012 @ 19:52 |
quote: Nee list numerically is numeriek sorteren dus op grootte. 
quote: Volgens mij klopt dat wel
Je idee klopt wel maar volgens mij moet je met 9! beginnen... dus k * 9! + ... etc
Je kan wel eens gelijk hebben ja 
Dan wordt het dus
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! |
Dus dan lukt het wel... Ok nu zeg ik verder niks meer. 
[ Bericht 5% gewijzigd door t4rt4rus op 12-08-2012 19:57:55 ] |
t4rt4rus | zondag 12 augustus 2012 @ 20:00 |
En dit klopt ook weer niet :S |
thenxero | zondag 12 augustus 2012 @ 20:02 |
quote: Hmm, ik zal er even naar gaan kijken |
thenxero | zondag 12 augustus 2012 @ 20:25 |
Ik snap al waar het fout gaat. Er zijn meerdere manieren om je coëfficiënten te bepalen. Je moet dus nog controleren of je een coëfficiënt kan veranderen door de volgende coëfficiënten te vergroten. Als dat kan moet je het ook zo laten staan. |
t4rt4rus | zondag 12 augustus 2012 @ 20:49 |
wacht eens even, 0 is de eerste permutatie...
Dus we moeten dit oplossen:
1 | 999999 = k*9! + l*8! + m*7! + n*6! + o*5! + p*4! + q*3! + r*2! + s*1! |
En dan kom je wel op de goede uit.  |
thenxero | zondag 12 augustus 2012 @ 20:54 |
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.  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. |
t4rt4rus | zondag 12 augustus 2012 @ 20:57 |
quote: 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. We tellen wel het aantal permutaties  999 999 is de miljoenste permutatie van de set {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} |
thenxero | zondag 12 augustus 2012 @ 21:23 |
Precies. Heb nu ook met de class van GS42 opgave 20 opgelost. In 0.2 seconde dus ik vind die klasse erg goed werken. |
GS42 | zondag 12 augustus 2012 @ 23:40 |
quote: Ha, dank je. Natuurlijk was het ook niet overdreven moeilijk om verbeteringen aan te brengen. Leuk als jullie ook iets toevoegen, het is nog lang niet compleet.
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  Daar kan je best gelijk in hebben. Ik moest kiezen tussen snelle in- en output of snel rekenen. Hier heb ik dus voor gekozen. Compileren met -O2 of -O3 helpt wel flink.
quote: Ik heb ook geen schijn van kans tegen GMP. Op een korte benchmark die ik gedaan heb, was GMP zo 50 keer sneller op puur rekenwerk en ik ben bang dat dat oploopt naarmate de getallen groter worden. Op de in- en output wil ik niet eens weten hoe veel sneller ze zijn. Maar sneller zijn dan GMP was gelukkig ook niet mijn doel.
quote: 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: 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.  |
thenxero | maandag 13 augustus 2012 @ 00:32 |
quote: 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.  Ja, erg bedankt voor deze gebruiksvriendelijke class .
Ik vrees dat ik een bug heb gevonden. Ik probeer het eerste Fibonacci getal te vinden die uit minstens 1000 cijfers bestaat. Dat betekent dat het getal groter dan of gelijk aan 10^999 is. Dus ik ga getallen vergelijken met 10000.........000 (999 nullen). Ik krijg geen error maar ook geen output (alleen return 0).
SPOILER 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #include <iostream> #include <C:\\unlimited_int.h>
using namespace std;
int main() { Unlimited::Int fib1=1, fib2=1, fib3=2; Unlimited::Int k = 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000; while(fib1<k) { fib3=fib1+fib2; fib1=fib2; fib2=fib3; cout << fib1 << endl; } return 0; } |
|
thabit | maandag 13 augustus 2012 @ 00:42 |
C++ kan natuurlijk geen getallen zoals 100000000....0000 parsen. |
t4rt4rus | maandag 13 augustus 2012 @ 00:42 |
lol dat gaat ook niet werken xero  Misschien in een string zetten? |
GS42 | maandag 13 augustus 2012 @ 00:45 |
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.
1 | Unlimited::Int k("10000000"); |
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.
[ Bericht 14% gewijzigd door GS42 op 13-08-2012 00:51:07 ] |
thenxero | maandag 13 augustus 2012 @ 01:27 |
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. Ik krijg vreemd genoeg geen compiler waarschuwing. Als naïeve newb dacht ik dat je bij Unlimited::int een ongelimiteerde integer kon initialiseren. Bedankt! |
kutkloon7 | maandag 13 augustus 2012 @ 02:44 |
tvp voor ProjectEuler. Ik heb de eerste 26 al /opschepmodus |
thenxero | maandag 13 augustus 2012 @ 03:00 |
quote: Morgen Vandaag ben ik hopelijk ook zo ver.
Misschien moeten we maar een apart PE draadje maken(?) |
ari_zahav | maandag 13 augustus 2012 @ 11:23 |
Een goed idee. Ik ben ook begonnen met PE, maar dan met Python 3. |
t4rt4rus | maandag 13 augustus 2012 @ 11:40 |
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! Gebruik `-Wall -Wextra'. Ik compile het meeste met `-O3 -std=c++11 -Wall -Wextra'
[ Bericht 5% gewijzigd door t4rt4rus op 13-08-2012 11:48:31 ] |
thenxero | maandag 13 augustus 2012 @ 11:53 |
Al het gepraat over Project Euler kan nu hier, dan blijft het wel zo overzichtelijk en kunnen andere talen ook meedoen. |
GS42 | maandag 13 augustus 2012 @ 12:20 |
quote: Opzich geen rare gedachte. Goede tip, ik zal het wel ergens in de documentatie opnemen. |
thenxero | maandag 13 augustus 2012 @ 13:19 |
quote: 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. |
GS42 | maandag 13 augustus 2012 @ 13:25 |
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. Ook een prima oplossing natuurlijk. Iets als Int x(10); x.pow(999); geeft je ook het juiste getal. |
kutkloon7 | woensdag 15 augustus 2012 @ 18:22 |
quote: Goed idee, ik zie dat je dat inmiddels al gedaan hebt  |
thenxero | donderdag 16 augustus 2012 @ 20:54 |
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:
1 2 3 4 5 6 7 | int a,b,c; a=1; b=2;
c=b; b=a; a=c; |
Maar dan heb je dus extra geheugen nodig voor die c, en ik vroeg me dus af of dat ook beter kan. |
thabit | donderdag 16 augustus 2012 @ 20:58 |
|
thenxero | donderdag 16 augustus 2012 @ 21:08 |
Natuurlijk, ik zat eigenlijk te denken aan bepaalde libraries  |
trancethrust | donderdag 16 augustus 2012 @ 21:33 |
std::swap, maar soms heb je geen andere keus (maar dat regelt std::swap dus achter de schermen).
edit: voor primitive datatypes gaat dit niets uitmaken, het is vooral handig met types die ook pointers naar andere objecten bevatten. Een kleine optimisatie is je c in die code als const te declareren, dan houdt hij em zeker in CPU registers. Of de berekening met meer flops uitvoeren zoals thabit doet als je echt geen plek hebt. |
thabit | donderdag 16 augustus 2012 @ 21:43 |
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. |
trancethrust | donderdag 16 augustus 2012 @ 21:51 |
Mwah, dat van const is mijns inziens toch erg handig zoveel mogelijk goed te doen, in alle situaties. |
thenxero | donderdag 16 augustus 2012 @ 22:09 |
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. 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. |
thabit | donderdag 16 augustus 2012 @ 22:19 |
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. Ik doelde op de truc die ik zelf postte; const is wel goed om aan te leren.
Goed random getallen produceren, dat is een vakgebied op zich. Ik zou vooral googlen naar wat mensen ermee gedaan hebben. |
t4rt4rus | vrijdag 17 augustus 2012 @ 00:13 |
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 ... |
t4rt4rus | vrijdag 17 augustus 2012 @ 00:16 |
quote: 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. xchg rax, rbx  |
thenxero | vrijdag 17 augustus 2012 @ 00:17 |
quote:
quote: ? |
t4rt4rus | vrijdag 17 augustus 2012 @ 00:46 |
quote: /dev/random is random nummer generator in linux. xchg rax, rdx is swappen tussen rax en rbx. |
thenxero | vrijdag 17 augustus 2012 @ 00:55 |
oke |
trancethrust | vrijdag 17 augustus 2012 @ 09:55 |
quote: 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. Indien standaard C gebruikt wordt met correcte consts, dan gaat dit allemaal automatisch. Mocht xchg dus wel even snel zijn op je architectuur, of gebruikt jouw code echt al alle registers, dan kiest de compiler uit zichzelf xchg.
edit: const temporary in C, std::swap in C++; de standaard STD implementatie doet dit zelf al goed. |
thenxero | zondag 19 augustus 2012 @ 01:27 |
quote: 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.
Toen dacht ik misschien dat mijn array gewoon niet groter kon worden dan 20,096 integers. Dat ben ik gaan testen door array[i]=i te doen voor i=0 tot i=100,000. Maar dat gaf geen problemen, dus daar zou het niet aan mogen liggen.
Als return value krijg ik 0xC0000005. Heb je enig idee waar het aan kan liggen? Dit is de code die ik gebruik (en die dus goed werkt tot de gevreesde 20,096) (random2.txt is een CSV-bestand):
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; }
} |
|
thenxero | zondag 19 augustus 2012 @ 02:06 |
Problem solved, had randomint verkeerd geinitialiseerd in mijn main  |
thabit | zondag 19 augustus 2012 @ 09:00 |
Zijn er geen C(++)-voorbeelden/libraries die dat beter kunnen dan de standaardlibrary? Lijkt me toch wat makkelijker dan eerst een file moeten genereren. |
thenxero | zondag 19 augustus 2012 @ 10:40 |
Klopt. Boost is volgens mij zo'n library. Maar de vorige keer dat ik een niet-standaard library probeerde te gebruiken was dat een drama . |
trancethrust | zondag 19 augustus 2012 @ 12:14 |
GSL is doorgaans wat makkelijker in gebruik. |
GS42 | zondag 19 augustus 2012 @ 15:04 |
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. 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? |
trancethrust | zondag 19 augustus 2012 @ 16:23 |
Of rand() goed is hangt af van de compilercollectie. gsl_rng_rand heeft/had bijvoorbeeld een duidelijk probleem. IBM's randu-functie was schijnbaar ook niet zo'n succes. Met een beetje ongeluk kom je ze nog tegen in de praktijk. |
t4rt4rus | maandag 20 augustus 2012 @ 10:47 |
quote: Meneer zit op Windows...  |
thenxero | maandag 20 augustus 2012 @ 11:56 |
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? 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. |
trancethrust | maandag 20 augustus 2012 @ 12:07 |
quote: Dan wordt het ook moeilijker dan noodzakelijk.
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 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. De oplossing is inderdaad om een niet LC-RNG te gebruiken (je kan ook de code van de wiki-pagina over de Mersenne-twister testen), of je kiest simpelweg een LC-RNG die het wel goed doet voor jouw d.
Ten tweede, als je met `heel snel' richting high-performance computing wil gaan, raad ik je ten sterkste aan toch op linux verder te gaan. Je krijgt simpelweg betere performance (zeker wanneer je multithreaded gaat) en in de industrie zelf (incl. de academici overigens) is er nagenoeg niemand die serieus in Windows werkt. |
thenxero | maandag 20 augustus 2012 @ 12:42 |
Oke, ik zal later naar Linux gaan kijken. Voor nu is het al een hele stap vooruit in de performance van Matlab naar C++. Voor nu voldoet mijn gedownloadde txt bestand met random numbers, en het werkt al een stuk sneller dan gehoopt, maar het is inderdaad niet ideaal. |
GS42 | maandag 20 augustus 2012 @ 12:59 |
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. 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. |
netolk | dinsdag 21 augustus 2012 @ 19:08 |
quote: 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. ik zou sowieso zo vaak mogelijk de std functies gebruiken ipv. zelf maken of uit externe libs halen |
thenxero | zondag 26 augustus 2012 @ 11:33 |
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:
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 |
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? |
thabit | zondag 26 augustus 2012 @ 11:39 |
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? Waarom geen vector gebruiken? |
GS42 | zondag 26 augustus 2012 @ 12:06 |
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:
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>>. |
t4rt4rus | zondag 26 augustus 2012 @ 13:03 |
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>>. Ik zou std::getline gebruiken en niet std::basic_istream::getline. http://en.cppreference.com/w/cpp/string/basic_string/getline |
GS42 | zondag 26 augustus 2012 @ 13:06 |
quote: Dan zijn we het eens: jouw getline is dezelfde als de mijne.  |
t4rt4rus | zondag 26 augustus 2012 @ 13:16 |
quote: Als ik op die link van je klik kom ik toch ergens anders uit.
edit:
ohnee toch niet  |
thenxero | zondag 26 augustus 2012 @ 13:20 |
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. |
GS42 | zondag 26 augustus 2012 @ 13:22 |
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> > |
Als je wilt kan het ook in een array van unsigned-pointers, maar dan moet je dynamisch alloceren en ergens de lengte van elke array opslaan om deze te kunnen gebruiken.
Oh, eventueel zou je ook een array van vectoren kunnen gebruiken, als je weet hoeveel regels je bestand heeft en dit niet verandert. |
thenxero | zondag 26 augustus 2012 @ 13:32 |
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? |
GS42 | zondag 26 augustus 2012 @ 13:40 |
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? Jahoor, vrijwel alles kan in een vector. Uit mijn hoofd is alleen een (non-throwing) copy constructor vereist.
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>>. 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. |
thenxero | zondag 26 augustus 2012 @ 13:46 |
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. Ja klopt, ik weet niet hoe dat werkt. Een korte voorbeeldcode zou wel fijn zijn. |
GS42 | zondag 26 augustus 2012 @ 13:57 |
quote: Nou, okay dan. 
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'; } } |
Dit moet op jouw bestandsformaat werken. De truc zit in de istringstream: deze neemt een string en doet zich daarna voor als istream. Hierdoor kan je uit het object lezen alsof het een bestand is. De istringstream en ostringstream (doet het tegenovergestelde) zijn vrij nuttig en het is een goed idee je er eens in te verdiepen. |
thenxero | zondag 26 augustus 2012 @ 14:07 |
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.
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? |
GS42 | zondag 26 augustus 2012 @ 14:12 |
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. 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: 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?
'unsigned' is hetzelfde als 'unsigned int'  |
thenxero | zondag 26 augustus 2012 @ 14:22 |
Het ziet er verschrikkelijk uit, maar dat zal ik maar eens gaan doorlezen dan. |
thabit | zondag 26 augustus 2012 @ 14:26 |
Als ik een class C aanmaak, implementeer ik ook meteen een functie
1 | std::ostream& operator<<(std::ostream&, const C&); |
Handig voor testen en debuggen! Met std::cout kun je je object op het scherm zetten, en met stringstreams kun je je object in een string omzetten, mocht dat nodig zijn. |
t4rt4rus | zondag 26 augustus 2012 @ 14:39 |
quote: Wat ziet er verschrikkelijk uit? |
thenxero | zondag 26 augustus 2012 @ 14:46 |
quote: 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. |
t4rt4rus | zondag 26 augustus 2012 @ 14:47 |
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. Het is toch overzichtelijk? Wil je alles in kleurtjes en plaatjes ofzo...? |
thenxero | zondag 26 augustus 2012 @ 14:48 |
quote: Ja, het is ook waar ik naar op zoek was. To the point en overzichtelijk. En er zijn ook plaatjes . Maar leuk is anders... |
GS42 | zondag 26 augustus 2012 @ 14:57 |
quote: 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. |
thenxero | zondag 26 augustus 2012 @ 15:06 |
quote: 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. Gelukkig ligt het niet aan mij . |
t4rt4rus | zondag 26 augustus 2012 @ 16:19 |
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. Het is inderdaad meer een documentatie. Ik vind dat wel lekker lezen 
Maar misschien kan code wel in een box, is wat makkelijker lezen. Is dat in de gedrukte versie ook niet het geval? |
dfdsdfds | zaterdag 8 september 2012 @ 15:41 |
Aah mooi dat hier ook iets staat over C++. Ik heb een heleboel vragen:
Mijn vraag gaat hierover:
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; } |
Tussen elk getal zet je een spatie. De som is dus gelijk aan een getal + 1? Dus als je een 1 invoert wordt de som gelijk aan 2? De teller krijgt er steeds +1 bij zolang er getallen > 0 ingevoerd worden. Dat snap ik.
Stel ik voer 1 9 8 5 -4 in.
som = getal + 1 som = 1 + 1 teller = 1
gemiddelde = (1 + 9 + 8 + 5 + 1 + 1 +1 + 1)/(1+1+1+1) = Ik kom er niet uit. Iemand die me kan helpen?
Druk het laatste getal en het voorlaatste getal (in die volgorde) af van een rij
Hoe moet ik dit aanpakken? Ik heb nu dit programma:
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; } |
Voor woorden is dit een eitje: gwn char string[5], bij iemand die 'Joop" intikt kun je zo elke letter van het woord benoemen. Er wordt in ieder geval een '%f-file' van ieder getal gemaakt. Hoe kan ik deze getallen onderschijden? 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?
[ Bericht 22% gewijzigd door dfdsdfds op 08-09-2012 15:48:16 ] |
thabit | zaterdag 8 september 2012 @ 15:44 |
Kun je je code in [code]-tags zetten? Dat leest wat prettiger. |
thabit | zaterdag 8 september 2012 @ 15:51 |
quote: Dit moet je eerst naar een float (of double) casten, anders voert-ie een integer deling uit en dat is gewoon afgerond naar beneden. |
thabit | zaterdag 8 september 2012 @ 15:55 |
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? Een float is 1 enkel getal, en geen reeks getallen. Je moet de getallen in een array (of beter: een vector) van floats stoppen. |
dfdsdfds | zaterdag 8 september 2012 @ 15:56 |
Bij dit programma moet een naam 5 keer in 4 rijen afgedrukt worden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #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; } |
Wat betekent die in godsnaam Na 5 'a's' moet er een witregel geplaatst worden. Zonder deze regel werden er gwn 20 namen onder elkaar gezet. Het == teken betekent 'is gelijk aan'. Als ik voor a 5 invoer staat er dus . Wat betekent de % hier? |
dfdsdfds | zaterdag 8 september 2012 @ 16:03 |
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. 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?
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; |
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? |
thabit | zaterdag 8 september 2012 @ 16:15 |
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? Ik weet niet precies hoe scanf werkt, je kan beter de functionaliteit uit iostream gebruiken. |
thabit | zaterdag 8 september 2012 @ 16:16 |
quote: Rest bij deling. |
GS42 | zaterdag 8 september 2012 @ 16:29 |
quote: 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.  |
dfdsdfds | zaterdag 8 september 2012 @ 16:48 |
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.  Ik moet voor a.s. woensdag 4 opdrachten inleveren en zit pas op 1/4 Klakkeloos 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? |
FrankRicard | zaterdag 8 september 2012 @ 17:39 |
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.  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. |
netolk | zaterdag 8 september 2012 @ 18:46 |
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. 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 zitten |
netolk | zaterdag 8 september 2012 @ 18:47 |
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/4  Klakkeloos 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? 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??? |
dfdsdfds | zaterdag 8 september 2012 @ 18:53 |
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??? 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. |
netolk | zaterdag 8 september 2012 @ 18:56 |
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. 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... |
GS42 | maandag 10 september 2012 @ 10:13 |
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/4  Klakkeloos 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? 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.pdf
Als het toch C++ betreft, kan je hier kijken voor tips. Misschien zijn boeken op die lijst vertaald naar het Nederlands? |
GS42 | maandag 10 september 2012 @ 10:41 |
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. 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? |
dfdsdfds | maandag 10 september 2012 @ 12:18 |
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: kliken verder kun je heel veel vinden op google en wikipedia... Er bestaat al een Nls C++ forum... |
GS42 | woensdag 12 september 2012 @ 23:52 |
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?
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"; ??> |
Dit demonstreert mooi het nut van niet alleen juist maar ook duidelijk programmeren.  |
FrankRicard | vrijdag 14 september 2012 @ 11:23 |
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? 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. Bijvoorbeeld:
1 | fprintf(dumpfile,"%.1f\t%.5f\n",input,result); |
Of (en dit moest ik even opzoeken)
1 2 3 4 | dumpfile.setprecision(1); dumpfile << fixed << input << "\t"; dumpfile.setprecision(5); dumpfile << result << endl; |
EDIT: Ik zie nu dat dit ook kan, maar dan vind ik de fprintf nog steeds makkelijker.
1 | dumpfile << fixed << setprecision(1) << input << "\t" << setprecision(5) << result << endl; |
|
thabit | vrijdag 14 september 2012 @ 11:41 |
Het voordeel van printf is de formatting, en het voordeel van cin en cout is dat je er niet tot beperkt bent maar dezelfde code bijvoorbeeld ook kunt toepassen op stringstreams. Het heeft allebei voor- en nadelen, en je moet gewoon datgene gebruiken wat voor je specifieke doeleinden het beste is. |
GS42 | vrijdag 14 september 2012 @ 12:56 |
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. 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. 
Het enige objectieve voordeel van de printf-notatie is volgens mij dat printf tekst en variabelen mooi gescheiden houdt. Als je bijvoorbeeld een applicatie in meerdere talen wilt leveren, dan is iets als "Je leeftijd is %d jaar en %d dagen" mooi in een apart bestandje te zetten en kan je elke zin in een keer vertalen. Met std::cout gaat dit moeilijker, omdat je de zin in stukjes moet knippen.
Dit is natuurlijk niet de primaire functie van output-methoden en dus eigenlijk een toevallig effect van printf, maar wel een heel handige eigenschap. Boost heeft een library om dit effect ook in C++ te bereiken, met de voordelen van C++ (typesafe en eigen klassen gemakkelijk afdrukken) erbij.
Ik kan goed begrijpen dat je de printf-notatie gemakkelijker te typen vindt, maar ik denk dat de voordelen van de C++-alternatieven zwaarder wegen dan dat gemak. |
t4rt4rus | vrijdag 14 september 2012 @ 18:25 |
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.  Hm even analyseren. 
Krijg wel leuke warnings. trigraphs...
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] |
-edit- Als je wil weten wat dit wordt, gebruik -E in gcc 
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));
} |
Let op dat ??/ in de comment er voor zorgt dat de regel erna ook een comment is.
[ Bericht 30% gewijzigd door t4rt4rus op 14-09-2012 18:43:45 ] |
GS42 | vrijdag 14 september 2012 @ 23:18 |
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. 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.
Trigraphs zijn tekencombinaties die beginnen met ?? en bepaalde speciale tekens "#\^[]|{}~" kunnen vervangen (omdat die tekens vroeger niet op alle machines beschikbaar waren). Ook kan je ermee dus een commentaar-regel door laten lopen naar de volgende regel. De preprocessor vervangt deze trigraphs door het 'normale' teken en compileert daarna de code verder. Zoals je kunt zien leidt het gebruik van trigraphs tot onleesbare code en moet je ze dan ook nooit gebruiken, maar het is nuttig om te weten dat ze bestaan: ze kunnen rare problemen veroorzaken.
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.  |
t4rt4rus | zaterdag 15 september 2012 @ 12:10 |
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.  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. |
GS42 | zondag 16 september 2012 @ 01:47 |
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. 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.
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?
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. |
t4rt4rus | zondag 16 september 2012 @ 11:04 |
quote: Bitwise not of complement ja.
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?
warning: ISO C++ forbids taking address of function ‘::main’
Ik snap hem ook niet.
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.
Wanneer zou dat niet compatible zijn dan? |
t4rt4rus | zondag 16 september 2012 @ 12:16 |
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? |
GS42 | zondag 16 september 2012 @ 17:24 |
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? Ik wist niet dat ~ ook wel not genoemd wordt; ik dacht gelijk aan operator!. 
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...
Ik twijfel aan ~-1U omdat ik niet zeker weet of -1U ook gegarandeerd alle bits op 1 zet op rare systemen. |
t4rt4rus | zondag 16 september 2012 @ 19:42 |
quote: 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... ISO/IEC 14882:2011 3.6.1/3:
quote: The function main shall not be used within a program.
quote: Ik twijfel aan ~-1U omdat ik niet zeker weet of -1U ook gegarandeerd alle bits op 1 zet op rare systemen.
Boeit voor het programma verder ook niet.  http://ideone.com/txgjY
[ Bericht 1% gewijzigd door t4rt4rus op 16-09-2012 20:51:54 ] |
Ai_KaRaMBa | zondag 16 september 2012 @ 21:15 |
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? Zou USACO kunnen zijn? |
GS42 | zondag 16 september 2012 @ 22:35 |
quote: 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: Boeit voor het programma verder ook niet.  Dat klopt in deze context inderdaad. Ik vraag het me alleen nog wel af.  |
t4rt4rus | zondag 16 september 2012 @ 23:06 |
quote: Nee
Misschien zijn er ook wel zo veel van die sites... |
t4rt4rus | woensdag 19 september 2012 @ 21:06 |
Zitten er hier nog mensen op IRC? Leuk om te channel te maken voor C++ op irc.fok.nl, irc.tweakers.net? |
ouyevoli | donderdag 27 september 2012 @ 02:12 |
quote: prima #cplusplus
[ Bericht 48% gewijzigd door ouyevoli op 27-09-2012 06:13:33 ] |
t4rt4rus | vrijdag 28 september 2012 @ 10:19 |
quote: Je mag ook blijven zitten in #c of #c++  |
thabit | vrijdag 28 september 2012 @ 10:40 |
Werkt dat echt, irc-kanalen over dit soort onderwerpen? |
thenxero | vrijdag 28 september 2012 @ 10:57 |
Waarschijnlijk alleen als je afspreekt om tijdstip X. |
t4rt4rus | vrijdag 28 september 2012 @ 11:24 |
quote: echt wel  Is gezellig, lol. |
t4rt4rus | zondag 4 november 2012 @ 15:39 |
Zijn er nog mensen bezig met C++? Ik ben nu een beetje bezig om Autotools te gebruiken. Weet alleen niet echt waar te beginnen met het lezen van documentaties. Iemand een idee? |
thabit | zaterdag 29 december 2012 @ 14:12 |
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. |
t4rt4rus | zaterdag 29 december 2012 @ 14:13 |
Yey weer een post in C(++)  |
netolk | vrijdag 4 januari 2013 @ 01:52 |
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.pdfC 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. Dat ziet er inderdaad interessant uit
bedankt |
Dale. | vrijdag 4 januari 2013 @ 02:24 |
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.pdfC 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, |
ufopiloot12 | woensdag 13 februari 2013 @ 20:22 |
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? |
thabit | woensdag 13 februari 2013 @ 20:33 |
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? Hangt ervan af hoe slim je bent. |
t4rt4rus | woensdag 13 februari 2013 @ 21:07 |
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. Maar C++ heeft ook classes voor memory management  |
Wolfje | woensdag 13 februari 2013 @ 23:50 |
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 . |
trancethrust | donderdag 14 februari 2013 @ 00:35 |
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  . Uh, wat? Oh wacht, sarcasme.
Als het wel een probleem is dan is geen enkele taal een goed alternatief; slimmer programmeren is dan beter. |
t4rt4rus | woensdag 20 februari 2013 @ 16:32 |
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? Voor C++ gekozen of met Java bezig?  |
ufopiloot12 | woensdag 20 februari 2013 @ 18:42 |
quote: 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.  |
netolk | woensdag 20 februari 2013 @ 20:07 |
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.  Goed zo
Overigens is de syntax (vind ik) vrij logisch en duidelijk. Ook lijkt deze veel op bijvoorbeeld C en Java |
Tijn | woensdag 20 februari 2013 @ 20:25 |
quote: 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++. |
netolk | woensdag 20 februari 2013 @ 23:11 |
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++. 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) |
trancethrust | woensdag 20 februari 2013 @ 23:40 |
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. |
t4rt4rus | donderdag 21 februari 2013 @ 12:40 |
En verder moeten beginners de containers gebruiken, nog minder kans dat er iets fout kan gaan. |
netolk | vrijdag 22 februari 2013 @ 15:23 |
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. 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) |
t4rt4rus | vrijdag 22 februari 2013 @ 16:13 |
Maar daar hebben we deze hulp middelen dus voor: Containers http://en.cppreference.com/w/cpp/container
Dynamic memory management http://en.cppreference.com/w/cpp/memory |
t4rt4rus | zaterdag 23 februari 2013 @ 23:45 |
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.  Al vragen over de syntax?  Verschil i++ en ++i snap je?
Wat valt er verder eigenlijk te leren over syntax? |
netolk | zondag 24 februari 2013 @ 13:57 |
quote: nou niet veel geloof ik zo... De syntax is verder eigenlijk identiek aan andere talen (als bijv. Java) |
ouyevoli | zondag 24 februari 2013 @ 14:46 |
quote: 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.
Met andere woorden:
1 2 | int i = 0, j = 0; i = j++; |
De waarde van i is nog steeds 0, de waarde van j is 1.
1 2 | int i = 0, j = 0; i = ++j; |
De waarde van i en j is 1. |
thabit | zondag 24 februari 2013 @ 14:48 |
Wat dat betreft was het logischer geweest om de taal ++C te noemen in plaats van C++. |
t4rt4rus | zondag 24 februari 2013 @ 15:08 |
Operator precedence kan je misschien wel wat mee http://en.cppreference.com/w/cpp/language/operator_precedence |
Tijn | zondag 24 februari 2013 @ 15:20 |
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. |
t4rt4rus | zondag 24 februari 2013 @ 15:48 |
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. En dan heb je natuurlijk ook dat wanneer je het vaker in een regel gebruikt, het vaak undefined is. Maar in een for loop gebruik ik meestal wel gewoon ++i. |
ufopiloot12 | zondag 24 februari 2013 @ 16:02 |
quote: 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.
[ Bericht 10% gewijzigd door ufopiloot12 op 24-02-2013 16:08:05 ] |
thabit | zondag 24 februari 2013 @ 16:14 |
quote: 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. Jazeker: DIG / Project Euler |
t4rt4rus | zondag 24 februari 2013 @ 16:14 |
quote: Geen vragen over pointers? Dat kan bijna niet 
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.
Ja dat is lastig, dan moet je toch echt wat proberen zelf te maken. |
t4rt4rus | zondag 24 februari 2013 @ 16:14 |
quote: Ohja dat hebben we natuurlijk ook nog  |
ufopiloot12 | zondag 24 februari 2013 @ 16:27 |
quote: 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: Interessant, bedankt! |
t4rt4rus | zondag 24 februari 2013 @ 16:35 |
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). Welke lees je dan? |
ufopiloot12 | zondag 24 februari 2013 @ 16:37 |
quote: 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. |
t4rt4rus | zondag 24 februari 2013 @ 16:40 |
quote: Ohje het is cplusplus.com...
Pak een goed boek  |
ufopiloot12 | zondag 24 februari 2013 @ 16:41 |
quote: Daar was ik al bang voor. Suggesties? |
t4rt4rus | zondag 24 februari 2013 @ 16:54 |
quote: 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 echter wel vanuit dat je wat C kan, maar hoeft geen belemmering te zijn. |
ufopiloot12 | zondag 24 februari 2013 @ 16:57 |
quote: Bedankt  |
t4rt4rus | zondag 24 februari 2013 @ 17:01 |
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...) |
ufopiloot12 | zondag 24 februari 2013 @ 17:11 |
quote: Dat zit er bij mij nu wel een beetje ingeprent, haha. Zonder ook te weten waarvoor het dient. 
Ik ga dat eventjes doorlezen. |
t4rt4rus | zondag 24 februari 2013 @ 17:13 |
quote: Namespaces http://www.icce.rug.nl/documents/cplusplus/cplusplus04.html |
ufopiloot12 | zondag 24 februari 2013 @ 17:26 |
quote: 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.  |
t4rt4rus | zondag 24 februari 2013 @ 17:30 |
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.  Zoals? 
Maar als je dus referenties nodig hebt kan je beter op http://en.cppreference.com/w/ kijken dan op cplusplus.com |
Tijn | zondag 24 februari 2013 @ 17:40 |
Klinkt alsof cplusplus.com voor C++ is wat w3schools voor HTML, CSS en Javascript is. |
#ANONIEM | zondag 24 februari 2013 @ 17:41 |
quote: Hèhè |
ufopiloot12 | zondag 24 februari 2013 @ 17:49 |
quote: Namespaces, ik moet dat even rephrasen. Er worden belangrijke dingen blijkbaar niet vertelt. Het is niet toereikend dus.
[ Bericht 0% gewijzigd door ufopiloot12 op 24-02-2013 18:58:26 ] |
trancethrust | zondag 24 februari 2013 @ 19:42 |
Thinking in C++ is ook een erg mooie: http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html
Boek is gratis te krijgen in PDF; een van de html versies:
http://www.smart2help.com(...)-vol-one/Frames.html |
#ANONIEM | zondag 24 maart 2013 @ 22:07 |
Ik ga toch een begin maken aan Accelerated C++.
Jullie zullen misschien nog van me horen hier. |
t4rt4rus | zondag 24 maart 2013 @ 22:11 |
quote: Leuk ufo was ook begonnen, geen idee of die nog bezig is...
quote:
|
ufopiloot12 | zondag 24 maart 2013 @ 22:30 |
quote: Ik ben de laatste tijd idd met wat andere dingen bezig geweest. Ik ben gisteren eens wezen kijken naar boeken, die hier werden aangeraden en dit leek mij wel een redelijke. Ik heb hoofdstuk 1 maar overgeslagen en heb al vluchtig hoofdstuk 2 doorgekeken aangezien hier ook niet veel nieuws in kwam. http://www.smart2help.com(...)-vol-one/Frames.html |
#ANONIEM | zondag 24 maart 2013 @ 22:47 |
quote: 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. |
t4rt4rus | zondag 24 maart 2013 @ 23:45 |
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. Yey iemand die het snapt. :p |
netolk | maandag 25 maart 2013 @ 07:55 |
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. 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 |
t4rt4rus | maandag 25 maart 2013 @ 11:29 |
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 Zelfde hier. |
ufopiloot12 | maandag 25 maart 2013 @ 14:02 |
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; } |
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? |
t4rt4rus | maandag 25 maart 2013 @ 15:02 |
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) |

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:
1 2 | for (auto const &e : words) std::cout << e << std::endl; |
|
ufopiloot12 | maandag 25 maart 2013 @ 15:18 |
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 ] Bedankt! |
t4rt4rus | maandag 25 maart 2013 @ 18:09 |
quote: Wat dat trouwens ook kan doen iterators gebruiken:
1 2 | for (auto it = words.begin(); it != words.end(); ++it) std::cout << *it << '\n'; |
|
ufopiloot12 | maandag 25 maart 2013 @ 18:13 |
quote: Hmm, dit is eigenlijk een stuk fijner te lezen. Veel mooier ook. Hier ga ik morgen eens naar kijken.  |
trancethrust | maandag 25 maart 2013 @ 19:11 |
quote: Dat is nog eens mooi gebruik van auto. |
t4rt4rus | maandag 25 maart 2013 @ 20:01 |
quote: 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 |
trancethrust | maandag 25 maart 2013 @ 20:16 |
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 Exactemundo; dit vergroot de leesbaarheid behoorlijk. Voorheen was ik totaal niet overtuigd van het nut van auto. |
ufopiloot12 | vrijdag 29 maart 2013 @ 10:55 |
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;
} |
Ik heb een programma gemaakt die het gemiddelde van een som van een x aantal cijfers uitrekent. Alles werkt prima, geen errors, maar mijn if statement werkt niet. Wat doe ik fout? |
Tijn | vrijdag 29 maart 2013 @ 11:02 |
quote: Nou...
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 ~$ |
|
ufopiloot12 | vrijdag 29 maart 2013 @ 11:03 |
quote: Ja ik heb wel wat zitten klooien toen ik dit op fok zette. Net deed hij het echt!  edit: bij nader inzien klopt er geen kut van mijn code. 
[ Bericht 5% gewijzigd door ufopiloot12 op 29-03-2013 11:11:10 ] |
Tijn | vrijdag 29 maart 2013 @ 11:24 |
Het probleem is natuurlijk dat je de input "-1" ook meetelt in het berekenen van het gemiddelde. |
ufopiloot12 | vrijdag 29 maart 2013 @ 11:27 |
quote: Aha, bedankt!
Ik heb het nu zo opgelost:
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;
} |
Weten jullie misschien een betere manier, want ik los het probleem hier niet ECHT mee op.
[ Bericht 27% gewijzigd door ufopiloot12 op 29-03-2013 11:45:48 ] |
t4rt4rus | vrijdag 29 maart 2013 @ 12:42 |
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. Je kan bijvoorbeeld zoiets doen:
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'; } |
|
ufopiloot12 | vrijdag 29 maart 2013 @ 12:47 |
quote: Double is idd een betere type. Ik heb nog niet over vectors gelezen, daar ga ik nog eens naar kijken. Bedankt! |
t4rt4rus | vrijdag 29 maart 2013 @ 13:00 |
quote: 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.
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'; } |
-edit-
Als je wil dat hij bijvoorbeeld stopt bij een negatief getal, kan je dit doen:
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'; } |
|
ufopiloot12 | vrijdag 29 maart 2013 @ 13:06 |
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 ] Duidelijk. Ik had al in gedachten dat het ook met een if statement zou moeten kunnen, maar ik wist niet precies hoe.  |
Tijn | vrijdag 29 maart 2013 @ 13:10 |
quote: 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. |
#ANONIEM | zondag 31 maart 2013 @ 01:00 |
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. 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.
[ Bericht 0% gewijzigd door #ANONIEM op 31-03-2013 01:02:02 ] |
trancethrust | zondag 31 maart 2013 @ 01:32 |
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. 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). |
Tijn | zondag 31 maart 2013 @ 05:26 |
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 natuurlijk  |
#ANONIEM | maandag 1 april 2013 @ 18:33 |
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  Punt was meer dat hij het ook zonder if-statements kan doen waardoor hij er alsnog niets van leert.
[ Bericht 0% gewijzigd door #ANONIEM op 01-04-2013 18:35:43 ] |
Tijn | maandag 1 april 2013 @ 19:20 |
quote: Daarom is de opdracht dat-ie er wel if-statements voor moet gebruiken  |
#ANONIEM | dinsdag 2 april 2013 @ 15:50 |
Dat Project Euler is leuk! |
t4rt4rus | dinsdag 2 april 2013 @ 16:32 |
quote: Ohja dat deden we ook nog. 
Ik zit nu te kloten met AES... |
Tijn | dinsdag 2 april 2013 @ 16:46 |
quote: Ik heb er laatst weer een paar opgelost, ik zit nu bij opgave 46  |
t4rt4rus | dinsdag 2 april 2013 @ 23:10 |
quote: Hadden we daar niet ook een topic over? |
#ANONIEM | woensdag 3 april 2013 @ 08:39 |
quote: Ik ben een laatkomer, maar ik heb wat kunnen vinden:
DIG / Project Euler |
t4rt4rus | woensdag 3 april 2013 @ 14:28 |
quote: Dat is hem. |
#ANONIEM | zaterdag 27 april 2013 @ 19:16 |
Ik zat leuk even screenshots van Plan 9 te kijken. Zag er leuk uit.
Maar toen werd ik verdrietig. Zie screenshot:

void main  |
netolk | zondag 28 april 2013 @ 16:18 |
quote: Dat is idd niet goed nee word ik ook altijd verdrietig van |
t4rt4rus | zondag 28 april 2013 @ 19:13 |
void main'ers should die!
hoi  |
#ANONIEM | zondag 28 april 2013 @ 19:16 |
Interessant stukje over de performance-verschillen tussen normale C-arrays en vectors:
http://assoc.tumblr.com/p(...)or-vs-plain-c-arrays |
#ANONIEM | zondag 28 april 2013 @ 19:58 |
Het hele nut van Operator Overloading ontgaat me overigens. |
Dale. | zondag 28 april 2013 @ 20:10 |
quote: Zeer handig juist. Stel je maakt een classe matrix dan kun je vervolgens * overloaden zodat de matrix A * matrix B = matrix C oplevert. |
#ANONIEM | zondag 28 april 2013 @ 20:13 |
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. 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. |
Dale. | zondag 28 april 2013 @ 20:16 |
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. 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  |
#ANONIEM | zondag 28 april 2013 @ 20:18 |
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  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  |
trancethrust | zondag 28 april 2013 @ 22:07 |
quote: 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. |
netolk | zondag 28 april 2013 @ 22:47 |
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  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) |
t4rt4rus | maandag 29 april 2013 @ 00:23 |
quote: Klopt niks van. Hij zegt dat vector niet continous is, dat is het wel. En een c array is te vergelijken met een std::array niet vector.
Vector doet dynamic allocation, dat kan je met c arrays niet doen. |
t4rt4rus | maandag 29 april 2013 @ 00:32 |
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. Andere member functies moet je ook opzoeken...
Als je twee matrices wil optellen is het toch veel makkelijker om A += B; te doen ipv A.add(B); En A + B; moet dan worden Add(A, B);? En daar is het dan weer geen member functie...
Wees blij dat er operators zijn... Wil je alles met gewone functies doen? int *i; initialize(i, 0);
cout(dereference ); etc... Dat wordt leuk  |
netolk | dinsdag 18 juni 2013 @ 19:22 |
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:
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]; } |
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? |
thabit | dinsdag 18 juni 2013 @ 20:17 |
1 | recv_buff = new IPHeader + 1024; |
Lijkt me nogal een vreemd stukje code. Wat wil je hier precies mee doen? |
netolk | dinsdag 18 juni 2013 @ 23:03 |
quote: 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) |
t4rt4rus | dinsdag 18 juni 2013 @ 23:08 |
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) En ook een memory leak, want je delete the IPHeader niet. |
netolk | woensdag 19 juni 2013 @ 00:09 |
quote: bedankt maar dat word ergens aan het einde van het programma gedaan  heb nu alleen het ontvang stukje staan omdat daar het probleem in moet zitten maar als de hele code nodig is kan ik die ook best plaatsen hoor (hij is alleen niet zo heel netjes) |
trancethrust | woensdag 19 juni 2013 @ 00:15 |
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? En wat doet je code dan precies? Deadlock? |
netolk | woensdag 19 juni 2013 @ 00:57 |
Niet wat ik wil dat het doet iig
het verstuurd nu dus een ping request alleen hij ontvangt de reply niet (terwijl die wel naar mijn pc is verstuurd want via wireshark zie ik die wel gewoon) dus ergens in de recv code zit iets niet lekker lijkt mij maar ik kan het zo niet vinden Hoopte eigenlijk dat het heel obvious was en zo opgelost was maar blijkbaar zien jullie het ook niet zo 1,2,3
zal hier mijn hele code wel even droppen:
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; } |
|
trancethrust | woensdag 19 juni 2013 @ 01:43 |
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. |
thabit | woensdag 19 juni 2013 @ 08:54 |
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) 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. |
netolk | woensdag 19 juni 2013 @ 10:27 |
quote: 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. hij komt bij het block recv aan alleen vervolgens blijft hij daar "wachten" en doet dan dus niks meer
quote: 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. 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 |
trancethrust | woensdag 19 juni 2013 @ 10:32 |
quote: 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: [..]
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
Precies. |
netolk | woensdag 19 juni 2013 @ 10:34 |
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. hmm, ICMP heeft geen poort maar dat terzijde. 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?) en anders zal ik eens even kijken of hij het zonder firewall wel doet |
trancethrust | woensdag 19 juni 2013 @ 10:37 |
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 .. 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. |
trancethrust | woensdag 19 juni 2013 @ 10:39 |
quote: OK
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?) [..]
Volgens mij het gedrag van recv ongedefineerd wanneer het een ongeldige socket wordt gevoerd. |
netolk | woensdag 19 juni 2013 @ 10:56 |
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. goed punt. Die 1024 bytes is puur als pakket vergroting zodat er wat data verstuurd word. Maar zoals eerder was dat code dat sowieso verder niet gebruikt werd dus dat heb ik er maar gelijk uit gehaald
Net even zonder firewall geprobeerd maar hij blijft in die deathlock uitkomen |
netolk | woensdag 19 juni 2013 @ 11:51 |
Oke, ik heb er nu een select voor gezet, dit is nu de receive code:
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"; |
nu returned select 0, waardoor het als gefaald word beschouwt (maar wireshark zit nog steeds een reply binnen komen) |
trancethrust | woensdag 19 juni 2013 @ 12:14 |
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? |
netolk | woensdag 19 juni 2013 @ 13:24 |
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? 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 |
trancethrust | woensdag 19 juni 2013 @ 13:58 |
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 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? |
netolk | woensdag 19 juni 2013 @ 14:08 |
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? 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) |
trancethrust | woensdag 19 juni 2013 @ 14:13 |
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) 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. |
netolk | woensdag 19 juni 2013 @ 15:34 |
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. Ja, ik ken het principe wel. Heb al zonder firewall geprobeerd, hielp niet. Ook kan hij gewoon data verzenden dus neem aan dat de initialisatie code ok is want dan zou dat ook niet kunnen. Maar heb nu een code op internet gevonden van een ping en trace programma ik denk dat ik me daar eens in ga verdiepen om te kijken hoe het daar word aangepakt. (al is het in C denk dat ik er toch nog wel wat uit kan halen) in ieder geval bedankt voor de hulp |
trancethrust | woensdag 19 juni 2013 @ 15:46 |
M.i. moet het iets basaals zijn als functies als select en recv misgaan.
quote: The select function determines the status of one or more sockets, waiting if necessary, to perform synchronous I/O. Is ICMP synchroon? Ik denk dan meer aan TCP ofzo. Misschien is select helemaal niet van toepassing?
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. Ligt de sleutel dan in het gebruiken van recvfrom ipv recv? |
netolk | woensdag 19 juni 2013 @ 21:34 |
quote: 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? 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 probleem Zal het eens even opnieuw en wat netter gaan schrijven misschien dat het met behulp van een andere code die ik gevonden heb wil lukken |
netolk | donderdag 20 juni 2013 @ 00:01 |
Oke, ik heb het nu aan de praat gekregen.
dit is nu de uiteindelijke code:
SPOILER 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 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | // 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
struct Error{ std::string _ERROR; Error(std::string error):_ERROR(error){} }; // 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 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("Lookup Failed!"); } // 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; }
unsigned short CalcChecksum(char *pBuffer,int nLen){ //Checksum for ICMP is calculated in the same way as for //IP header
//This code was taken from: http://www.netfor2.com/ipsum.htm
unsigned short nWord; unsigned int nSum = 0; int i; //Make 16 bit words out of every two adjacent 8 bit words in the packet //and add them up for(i = 0; i < nLen; i = i + 2){ nWord =((pBuffer [i] << 8)& 0xFF00) + (pBuffer [i + 1] & 0xFF); nSum = nSum + (unsigned int)nWord; } //Take only 16 bits out of the 32 bit sum and add up the carries while (nSum >> 16){ nSum = (nSum & 0xFFFF) + (nSum >> 16); }
//One's complement the result nSum = ~nSum; return ((unsigned short) nSum); } bool ValidateChecksum(char *pBuffer,int nLen){ unsigned short nWord; unsigned int nSum = 0; int i; //Make 16 bit words out of every two adjacent 8 bit words in the packet //and add them up for(i = 0; i < nLen; i = i + 2) { nWord =((pBuffer [i] << 8)& 0xFF00) + (pBuffer [i + 1] & 0xFF); nSum = nSum + (unsigned int)nWord; } //Take only 16 bits out of the 32 bit sum and add up the carries while(nSum >> 16){ nSum = (nSum & 0xFFFF) + (nSum >> 16); }
//To validate the checksum on the received message we don't complement the sum //of one's complement //One's complement the result //nSum = ~nSum; //The sum of one's complement should be 0xFFFF return((unsigned short)nSum == 0xFFFF); } bool Initialize(){ //Initialize WinSock WSADATA wsaData;
if (WSAStartup (MAKEWORD (2, 2), &wsaData) == SOCKET_ERROR){ throw Error("An error occured in WSAStartup operation"); return false; }
return true; } bool UnInitialize(){ //Cleanup if(WSACleanup() == SOCKET_ERROR){ std::cerr << "\nAn error occured in WSACleanup operation\n"; return false; }
return true; }
int main (int argc, char* argv[]){ if(argc < 2 || argc > 2){ std::cout << argv[0] << ' ' << "[IPadres]\n"; return 0; } unsigned MessageSize = 32; try{ Initialize(); std::cout << "Creating Socket... "; SOCKET Sock = INVALID_SOCKET; if((Sock = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP)) == INVALID_SOCKET){ std::cout << "Failed!\n"; throw Error("Invalid Socket"); } std::cout << "Done.\n"; sockaddr_in dest; // Destination address to send the ICMP dest.sin_addr.S_un.S_addr = FindHostIP(argv[1]); dest.sin_family = AF_INET; SYSTEMTIME timeSend,timeRecv; fd_set fdRead; int result = 0; /* Create the message buffer */ char* SendBuff = new char[sizeof(ICMPHeader)+MessageSize]; ICMPHeader sendHdr; sendHdr.type = ICMP_ECHO_REQUEST; sendHdr.code = 0; sendHdr.checksum = 0; // checksum is calculated later on sendHdr.seq = 0; // this is the counter to keep track of the messages (in a loop this value will go up) memcpy(SendBuff,&sendHdr,sizeof(sendHdr)); memset(SendBuff+sizeof(sendHdr),'x',MessageSize); // fills the rest with x sendHdr.checksum = htons(CalcChecksum(SendBuff,sizeof(ICMPHeader)+MessageSize)); // copy the message header back into the buffer memcpy(SendBuff,&sendHdr,sizeof(sendHdr)); std::cout << "Sending... "; result = sendto(Sock,SendBuff,sizeof(ICMPHeader)+MessageSize,0,(sockaddr*)&dest,sizeof(dest)); ::GetSystemTime(&timeSend); // Save's the sending time if(result == SOCKET_ERROR){ delete[] SendBuff; std::cout << "Failed!\n"; throw Error("Can't Send\n"); } std::cout << "Done.\n"; FD_ZERO(&fdRead); FD_SET(Sock,&fdRead); timeval timeInterval = {0, 0}; timeInterval.tv_usec = 5 * 1000; // timeout = 5 sec if((result = select(0,&fdRead,0,0,&timeInterval)) == SOCKET_ERROR){ delete[] SendBuff; throw Error("Occured at select operation"); } if(result >0 && FD_ISSET(Sock,&fdRead)){ std::cout << "Receiving... "; char *RecvBuff = new char[1500]; // allocate recv buffer if((result = recvfrom(Sock,RecvBuff,1500,0,0,0)) == SOCKET_ERROR){ delete[] SendBuff; delete[] RecvBuff; std::cout << "Failed!\n"; throw Error("Can't receive"); } ::GetSystemTime(&timeRecv); // Get response time std::cout << "Done.\n"; /*construct IcMP hader and message out of response */ ICMPHeader recvHdr; char *ICMPBuff = RecvBuff + sizeof(IPHeader); // skip the ip header and go to ICMP message int ICMPMsgLen = result - sizeof(IPHeader); memcpy(&recvHdr,ICMPBuff,sizeof(recvHdr)); // constructs the ICMP header IPHeader IPHdr; memcpy(&IPHdr,RecvBuff,sizeof(IPHdr)); // check if the response is the right reply and if the checksum is correct if(recvHdr.type == 0 && ValidateChecksum(ICMPBuff,ICMPMsgLen) && recvHdr.id == sendHdr.id && recvHdr.seq == recvHdr.seq){ // all is ok int Sec = timeRecv.wSecond - timeSend.wSecond; if(Sec < 0) Sec+=60; int MilliSec = abs(timeRecv.wMilliseconds-timeSend.wMilliseconds); int RoundTripTime = abs(Sec*1000-MilliSec); std::cout << "Reply from " << argv[1] << ": bytes = " << result-sizeof(ICMPHeader)-sizeof(IPHeader) << ", time = " << RoundTripTime << "ms, TTL = " << (int)IPHdr.ttl << '\n'; } else std::cout << "The echo reply is not correct!\n"; delete[] RecvBuff; } else{ std::cout << "Request timed out.\n"; std::cout << result; // temp } delete[] SendBuff; } catch(Error(e)){ std::cout << "\nERROR!\n"; std::cout << e._ERROR << '\n'; UnInitialize(); return -1; } if(UnInitialize() == false) return -1; return 0; } |
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) |
trancethrust | donderdag 20 juni 2013 @ 00:54 |
Je kan er een struct van maken als in
1 2 3 | struct receive_buffer { char buffer[ 1500 ]; }; |
Een sizeof(receive_buffer) is dan 1500*sizeof(char).
(Overigens is dynamisch alloceren van de receive-buffer via new niet nodig) |
netolk | donderdag 20 juni 2013 @ 09:40 |
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) 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 Dan zou je zeggen dat dit ook zou moeten werken
1 | recvfrom(Sock,RecvBuff,sizeof(RecvBuff),0,0,0); |
Maar dat werkt dus niet en faalt de recvfrom functie |
trancethrust | donderdag 20 juni 2013 @ 09:51 |
quote: 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 Die struct stond er voor een reden 
Een 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. |
netolk | donderdag 20 juni 2013 @ 09:58 |
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. klinkt logisch idd maar dan zou sizeof(*recvBuff) ook moeten werken maar bij de dynamische allocatie kreeg ik daar ook een error van recvfrom |
trancethrust | donderdag 20 juni 2013 @ 10:04 |
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 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). |
netolk | donderdag 20 juni 2013 @ 10:08 |
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). k, dus sizeof neemt alleen de grote van het object wat je er instopt en niet waar het naar verwijst ongeacht het gebruikt van * ? |
t4rt4rus | donderdag 20 juni 2013 @ 10:19 |
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 * ? http://en.cppreference.com/w/cpp/language/sizeof
Wordt onder compile-time bepaald, dus niet onder runtime. |
trancethrust | donderdag 20 juni 2013 @ 10:20 |
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 * ? 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.
De * maakt in deze zin altijd een pointer data type. |
netolk | donderdag 20 juni 2013 @ 10:28 |
oke, bedankt dan snap ik het  |
Ai_KaRaMBa | vrijdag 21 juni 2013 @ 15:45 |
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. Uhm, nee?
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]); |
|
trancethrust | vrijdag 21 juni 2013 @ 16:32 |
quote: Oh. Redelijk stoned Blijkbaar wordt een (niet-dynamische array) als een soort struct gezien; nooit geweten!
SPOILER 1 2 3 4 5 6 7 | #include <iostream>
int main( int argc, char **argv ) { unsigned long int b[ 10 ]; std::cout << "sizeof(b)=" << sizeof( b ) << ", b=" << b << ", &b=" << (&b) << std::endl; return 0; } |
Output: 1 | sizeof(b)=80, b=0x7fffdd6281c0, &b=0x7fffdd6281c0 |
|
t4rt4rus | vrijdag 21 juni 2013 @ 19:10 |
quote: Op vrijdag 21 juni 2013 16:32 schreef trancethrust het volgende:[..] Oh. Redelijk stoned  Blijkbaar wordt een (niet-dynamische array) als een soort struct gezien; nooit geweten! SPOILER [ code verwijderd ]
Output: [ code verwijderd ]
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 |
netolk | vrijdag 21 juni 2013 @ 23:16 |
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 ahh, vandaar Ik heb het nu opgelost door de grote in een aparte (constante) int te zetten zodat ik alleen die hoef aan te passen als ik de grote wil veranderen |
trancethrust | vrijdag 21 juni 2013 @ 23:53 |
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 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. |
t4rt4rus | zaterdag 22 juni 2013 @ 00:15 |
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. Je weet dat het zetten van struct voor de typename C is en niet nodig (deprecated?) in C++?
Zie std::array als je een array als value will passen. In C++14 komt er waarschijnlijk een dynamic array. |
trancethrust | zaterdag 22 juni 2013 @ 01:24 |
quote: http://ideone.com/swuvZr
quote: Zie std::array als je een array als value will passen. In C++14 komt er waarschijnlijk een dynamic array.
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. |
t4rt4rus | zondag 23 juni 2013 @ 01:07 |
Is er al iemand die Stroustrups nieuwe boek heeft?
En zijn er mensen die C++14 een beetje volgen? |
netolk | zondag 23 juni 2013 @ 01:16 |
quote: 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) |
Holy_Goat | donderdag 5 december 2013 @ 12:29 |
Omdat het van GS42 hier moet  ------------------
Hai!
Ik heb een programma dat redelijk veel verschillende handelingen op dezelfde manier (maar toch altijd net even anders) uitvoert. Het gaat om bewerkingen / analyses over OpenCV matrices.
Voor het gemak een voorbeeldje:
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 loopt door alle pixels van een gegeven resolutie set heen, en geeft bijvoorbeeld een maximum terug, of een gemiddelde, of telt het aantal pixels > 0, soms voor de Y matrix, soms de Z, soms de X, soms een combinatie. Soms past het bovendien de matrixen aan.
Anyway, ik zou dit een beetje handiger willen verpakken want die nested for loop zit op heel veel plekken en ik heb het idee dat dit overzichtelijker kan.
Bovendien... Dit moet toch sneller kunnen? Iemand een idee of dit in C++ in een object class zou kunnen en zo ja hoe kan ik die dan toch dynamisch genoeg maken om er vanalles mee te doen? Of ben ik echt gebonden aan de huidige aanpak? |
Gehenna | donderdag 5 december 2013 @ 13:40 |
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. |
Holy_Goat | donderdag 5 december 2013 @ 14:14 |
quote: 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. Dit is een derde sneller
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); |
en de bijbehorende functie dan zoiets is als
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 } } |
Doeditendat is altijd iets simpels. Soms trekt het lijntjes als x = iets, soms somt het alle waarden op, etc.
Misschien maak ik het mijzelf hierin alleen maar moeilijker, dat begrijp ik ook wel, maar ik had stille hoop dat je iets kon doen als:
(syntax is uiteraard manco)
1 2 3 | matrixoperation( (if(px)<40 || px>80){px=2}); of matrixoperation((if(px)<40 || px>80){sumx++},pointertosumx); |
waarbij px, py, pz bijvoorbeeld standaardtermen zijn die ie herkent als 'een punt uit die en die matrix, een punt uit die en die matrix of die en die matrix' en het 2e voorbeeld een argument meegegeven moet worden (pointersumx) omdat ie anders niets heeft om op te tellen (de sumx++). Met andere woorden, de variabele sumx zelf komt helemaal niet voor in de matrixoperation functie |
Gehenna | donderdag 5 december 2013 @ 14:53 |
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. 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 |
Holy_Goat | donderdag 5 december 2013 @ 15:06 |
quote: 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) |
thabit | donderdag 5 december 2013 @ 19:59 |
quote: Ja, hier staat namelijk een oneindige loop.  |
t4rt4rus | donderdag 5 december 2013 @ 20:03 |
Wow topic is weer actief |
t4rt4rus | donderdag 5 december 2013 @ 20:06 |
quote: En in die oneindige loop nog een oneindige loop 
Holy_Goat lees je boek eens even over operator++ |
Holy_Goat | vrijdag 6 december 2013 @ 00:20 |
Typo jongens :p |
netolk | vrijdag 6 december 2013 @ 03:42 |
quote: Ja verbaasde mij ook al
Normaal was ik de gene die het actief hield met vragen |
#ANONIEM | vrijdag 6 december 2013 @ 08:06 |
quote:  |
t4rt4rus | vrijdag 6 december 2013 @ 11:51 |
quote: Kom maar op met de vragen  |
t4rt4rus | vrijdag 6 december 2013 @ 11:54 |
quote: Die for-loops van jou zijn niet zo groot. Kan je makkelijk in meerdere functies stoppen. |
Holy_Goat | vrijdag 6 december 2013 @ 14:06 |
quote: 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 |
netolk | vrijdag 6 december 2013 @ 19:19 |
quote: Sorry, momenteel met m'n minor bezig en daar moeten we een game in java maken
quote: 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 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 |
#ANONIEM | vrijdag 6 december 2013 @ 19:21 |
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 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.  |
netolk | vrijdag 6 december 2013 @ 19:25 |
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.  Ja, weet ook niet waarom ze dat bedacht hebben.... Zal wel zijn omdat we object georiënteerd programmeren in Java hebben gehad.
Maar mis de referentie dingen enzo heel erg. Java heeft rare regels met het doorgeven van dingen want primitives gaan bij value en de rest bij reference ofzo echt zo bagger Plus natuurlijk dat openGL voor Java ook niet echt geweldig is |
#ANONIEM | vrijdag 6 december 2013 @ 21:38 |
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.  |
Gehenna | vrijdag 6 december 2013 @ 22:24 |
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.  C# (c sharp) misschien?
En anders Python proberen  |
#ANONIEM | vrijdag 6 december 2013 @ 22:30 |
quote: CSharp lukt me ook prima, maar er zijn dingen waarvoor je liever C++ gebruikt. 
Ik moet me er gewoon iets beter in gaan verdiepen. |
Crutch | vrijdag 6 december 2013 @ 23:21 |
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.  Java is dan ook mijn favoriet, maar serieus, die header files zijn heus zo erg niet. |
#ANONIEM | vrijdag 6 december 2013 @ 23:48 |
quote: 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. |
Gehenna | zaterdag 7 december 2013 @ 02:20 |
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. 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) |
MichielPH | zaterdag 7 december 2013 @ 11:45 |
Het is eigen Java, maar volgens maar volgens mij komen C en Java op dit basale niveau precies overeen.
1 2 3 4 | int daysInstalled = util.getDaysInstalled(context); int random = new Random().nextInt(10);
if (random == 0 & daysInstalled > 2) { |
Dit is code uit een app die ik gepubliceerd heb en ben per ongeluk een & vergeten, wat het een bitwise AND maakt. De oplossing van het probleem is een & toevoegen. Doel van de vraag is dus enkel om te snappen wat er gebeurt.
In de logs die ik nu heb is daysInstalled 0 of groter en ik verwacht nog steeds dat hij altijd enkel groter dan 2 is. Wat gaat er mis?
[ Bericht 1% gewijzigd door MichielPH op 07-12-2013 11:58:32 ] |
GS42 | zaterdag 7 december 2013 @ 11:58 |
quote: 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.
> 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 geëvalueerd wordt, terwijl bij (A && B) de waarde van B alleen wordt geëvalueerd 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.
[ Bericht 1% gewijzigd door GS42 op 08-12-2013 23:16:16 ] |
MichielPH | zaterdag 7 december 2013 @ 12:13 |
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. Ah, leuk om te weten!
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. 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. |
GS42 | zaterdag 7 december 2013 @ 12:20 |
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. (Let op lezers: we hebben het nog steeds over Java.)
En dit gebeurt niet meer nadat je & hebt vervangen door &&? En dat is ook het enige dat je veranderd hebt?
Dan kan ik het niet verklaren. Het enige verschil tussen de bitwise & en de logische && voor Java Booleans heb ik uitgelegd en zou hier geen verschillend resultaat mogen geven. Dit wordt gegarandeerd door de Java standaard.
Dus of (I) er gaat iets anders fout dan het &-&& verschil, of (II) je Java implementatie is kapot (of (III) ik heb het helemaal verkeerd, natuurlijk, maar ik denk van niet ).
[ Bericht 0% gewijzigd door GS42 op 07-12-2013 12:27:39 ] |
Holy_Goat | maandag 9 december 2013 @ 09:29 |
Hello again!
Dit stukje had ik eerder al geplaatst:
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 } } |
En nu zit ik wat verder te prutsen en kom er achter dat dit ook zou mogen
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
} } |
Welke zou jullie voorkeur hebben? Ik neig naar dit nieuwe voorbeeld, omdat ik dan een extra reference kwijt ben. Qua snelheid zit er volgens mij geen enkel verschil in? Wel is het zo dat de eerste variant wellicht iets leesbaarder is
//edit moment. Nr 2 lijkt niet eens goed te werken 
[ Bericht 4% gewijzigd door Holy_Goat op 09-12-2013 09:35:56 ] |
Holy_Goat | maandag 9 december 2013 @ 09:56 |
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?
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?
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 } |
[ Bericht 70% gewijzigd door Holy_Goat op 09-12-2013 10:08:01 ] |
Gehenna | maandag 9 december 2013 @ 10:42 |
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? 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: 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 ]
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
[ Bericht 0% gewijzigd door Gehenna op 09-12-2013 10:48:30 ] |
trancethrust | maandag 9 december 2013 @ 10:53 |
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. Dan maak je er ints van, ook al maakt het niets uit qua snelheid.
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 ]
switch/case. Of je gaat richting ijle matrices voor de minder-voorkomende waarden? |
Holy_Goat | maandag 9 december 2013 @ 10:54 |
quote: 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 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 |
Ai_KaRaMBa | maandag 9 december 2013 @ 10:56 |
Ik mis een betje waarom je uberhaubt met OpenCV matrices aan het werken bent. Je lijkt de matrix te 'misbruiken' als canvas van 320x240 pixels, en daarmee ben je opzoek naar optimalisaties omdat het blijkbaar niet snel genoeg is? Wat doet OpenCV preceis voor je in deze casus?
Ik zou zeggen dat als je een 'echte' canvas alloceerd (aaneengesloten blok geheugen, wat een twee-dimensionale array van (signed) integers representeerd), dat dat veel sneller en overzichtelijker werkt?
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); |
|
Gehenna | maandag 9 december 2013 @ 11:00 |
quote: 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 oh wacht daar heb je gelijk in idd (Ik ben net wakker ), hij gaat bij die 2e natuurlijk de alle statements door als waarde==0. Dan zou idd die eerste wellicht de betere keuze zijn.. |