Het heeft mij een hele tijd geduurd om door te krijgen wat pointers zijn en elke soort andere uitleg is een beetje op me afgeketst, dus ik snap de pijn. Het is niet voor niks dat andere talen om het probleem heen proberen te werken.
Het volgende is meer pseudocode dan correct C dus zie dat even over het hoofd. Kans zit er ook in dat er fouten in zitten; that's an exercise for the reader.
OK, het probleem is als volgt:
int function add(int a, int b){
return a+b;
}
Wat er hier gebeurt is dat je een functie hebt die
add heet. De functie krijgt twee argumenten met zich mee;
a en
b. De functie geeft de som terug. Simpeler kan het niet!
Als ik dit doe:
int first = 3;
int second = 4;
int sum = add(first,second);
Dan wordt er op de achtergrond iets gedaan wat je niet in de code ziet.
Er wordt bij
int first = 3 een geheugenlocatie gereserveerd en bij
int second = 4 ook. Deze hebben beiden een adres.
Als deze vervolgens de functie in worden geyeet worden er stiekem kopietjes van gemaakt. Die kopietjes staan op een andere locatie dan waar
first en
second op staan. Die kopietjes worden vervolgens bij elkaar opgeteld, en dan stuurt de functie het resultaat terug. Omdat je dan uit de functie springt mogen deze stukken geheugen weer als vrij worden gemarkeerd, want de levensduur van de variabele duurt net zo lang als de scope van de functie.
Vaak is dit wenselijk. Een functie rommelt niet met dingen in de omgeving en al het werk vind in een geisoleerd stukje plaats. No side-effects.
Dit op de achtergrond kopietjes maken heet
pass by value.
Als tegenhanger heb je
pass by reference.
Wat voor probleem los je hier mee op? Nou, een hele ris problemen. Een van de regeltjes in C is dat een functie altijd maar 1 return value heeft. Ik kan dus geen functie genaamd addAndMultiply schrijven die zowel a+b als a*b teruggeeft.
Maar, dat kan ik wel. Ik kan beide getallen in een struct stoppen en die struct teruggeven. Er zijn een hele ris workarounds die je kunt verzinnen van ontzettend goor en niet te onderhouden tot redelijk maar eigenlijk nog steeds rommel.
Maar - we kunnen ook dit doen:
We maken een functie:
void addAndMultiply(int a, int b, int &mult, int &sum){
*mult = a*b;
*sum = a+b;
}
Je ziet dat deze functie niks meer teruggeeft. Dat hoeft ook niet meer.
En zo roepen we 'm aan:
int multiplyResult = 0;
int sumResult = 0;
int *multiplyPointer = &multiplyResult;
int *sumPointer = &sumResult;
int first = 3;
int second = 4;
addAndMultiply(first, second);
Als ik nu kijk wat er in
multiplyResult en
sumResult zit is dat 12 en 7 respectievelijk.
Dus nu heeft de functie een soort achterdeurtje - zonder iets in de achtergrond te kopieren en zonder ergens naar toe te springen kan de functie nu met een waarde rommelen die er buiten ligt. Een functie krijgt een soort lijntje mee dat naar een adres leidt en die kan daar waardes in dumpen of uit lezen.
Dit zit eigenlijk best dicht tegen de machine aan, want je weet zo dingen die je eigenlijk niet hoeft te weten. Voor performance is dat mooi, want je kunt je geheugen zodanig inrichten dat dingen altijd op dezelfde plaats staan of allemaal netjes naast elkaar staan, en dat is weer fijn voor performance. Het is ook minder fijn voor veiligheid, want als een ander programma gewoon doodleuk mag uitlezen wat je in je geheugen hebt is dat een gapend veiligheidslek. Zie ook
Real mode - Wikipedia .
Een int is natuurlijk supersimpel. Een struct is al minder simpel, en je kunt hele complexe objecten maken die best wel een ris geheugen innemen. Als je die elke keer
by value moet meegeven wordt er een hoop geheugen van A naar B gekopieerd terwijl dat eigenlijk niet nodig is.
Zoals je begrijpt maakt dit dingen ook wat minder transparant. Omdat een functie nu op deze manier dingen kan aanpassen krijg je een hoop void functies waarvan je niet weet wat ze doen, en als je je pointers niet netjes initialiseert en opruimt is dat een recept voor crashes.
De rest mag je zelf uitvinden, maar ga gewoon een cursus op Udemy of zo doen, want dat werkt veel beter dan hier vragen en hopen dat je een antwoord krijgt.
Maar om even terug te komen op het commentaar:
Denk je even in dat iemand vragen stelt over synthesizers die voor ervaren gebruikers superbasic lijken. Voor elk stapje moet de hand vastgehouden worden.
Op een gegeven moment word je daar zelf behoorlijk gefrustreerd van want je bent voor niks helpdeskmedewerker aan het spelen. Op een gegeven moment moet de persoon die de vragen stelt gewoon de shit aansluiten en dingen zelf proberen en door fouten te maken er achter komen hoe het wel werkt. Maar - zonder proberen geen leren, en zonder fouten geen leren.
Toch?
Communities work because of reciprocity. Ik doe iets voor jou, jij doet iets voor mij. Als het niet lijkt alsof jij er iets voor terugkrijgt word je daar ook niet vrolijk van.
"Dan klik niet op de thread" - nee, zo werkt het niet. Dan begin je er gewoon een nieuwe, want je krijgt niet de antwoorden die je wil
En wat je nu vraagt komt eigenlijk neer op een 4-jarige HBO-opleiding. Dat kun je niet met 15 pagina's discussie op een forum overbrengen. Programmeren leren breekt je hersens op een speciale manier.