Functies mét parameters

We weten nu hoe we zelf een functie kunnen bouwen. Echter merken we iets speciaals op als we naar de functies kijken die we zoveel gebruiken: de functie ellipse() bijvoorbeeld, kan je helemaal niet gebruiken als je geen getallen invult tussen de () haken. Deze functie moet namelijk weten waar en hoe groot die ellips moet worden.

//dit kan niet:
ellipse();

//maar wel mét parameters:
ellipse(50,20, 10,10);

Als we die getallen aanpassen, verandert de plaats en de vorm van onze ellips, maar de functie blijft hetzelfde. Ze tekent nog steeds ellipsen. Deze functie werkt dus met variabelen, die wij bij het aanroepen van de functie vullen.

Onze eigen functie accepteert tot nu toe nog géén getallen of andere data. Wanneer dit wel het geval wordt, winnen we weer aan flexibiliteit.

van zonder naar mét parameters

De functie drawBlackCircle() werkt goed, maar als we bewegende zwarte cirkels willen tekenen met verschillende grootten, zullen we een variabele moeten introduceren die de diameter van de cirkel bevat. Het enige alternatief is anders voor elke cirkel een nieuwe functie schrijven, en dat kost alleen maar werk en maakt het geheel onoverzichtelijk.

Als we drawBlackCircle() in de draw() loop aanroepen, willen we dus eigenlijk dat we dit kunnen doen:

 drawBlackCircle(10,50,100,100);

De opgegeven waarden zouden dan kunnen staat voor de x,y, breedte en hoogte van onze zwarte cirkel.
Maar laten we beginnen met 1 variabele, voor de diameter.

In de draw loop willen we dus:

void draw(){
     drawBlackCircle(16);
}

Dat wil zeggen dat we in het ontwerp van onze functie met dat getal moeten rekening houden. Als we onze functie aanmaken, geven we binnen de ( en ) haak aan dat we hier een int verwachten, en we geven deze een naam (ik kies voor de naam “diam”) :

void setup(){
     size(500,500);
}

void draw(){
     drawBlackCircle(16);
}

void drawBlackCircle(int diam){ //lokale variabele diam
     stroke(255);
     fill(0);
     ellipse(50,50,diam, diam); //we gebruiken de lokale variabele diam als diameter van de cirkel 
}

and that’s it! Op deze manier wordt de “16” die we hebben ingegeven bij het aanroepen van onze functie gebruikt IN de functie.

Hier gebeurt erg veel, dus een overzicht van de flow is wel handig:

Screen Shot 2017-01-14 at 17.07.34

Als we de code van de bewegende cirkel met onze nieuwe functie aanvullen en een aantal keer drawBlackCircle() aanroepen met verschillende waardes, krijgen we:

int x = 0;
int speed = 2;

void setup(){
     size(500,500);
}

void draw(){
     background(255);
     drawBlackCircle(50);
     drawBlackCircle(20);
     drawBlackCircle(10);
}

void drawBlackCircle(int diam){
     x = x + speed;

     if(x > width || x < 0){
          speed = -speed;
     }

     stroke(255);
     fill(0);
     ellipse(x,100,diam,diam);
}

Oefening

breidt bovenstaand voorbeeld uit, zodat naast de diameter, ook de y-positie kan variëren

Lokale variabelen en functies

Wanneer we bovenstaand diagram van de flow bekijken, zien we duidelijk dat de waarde16” die we meegeven als we de functie aanroepen in een lokale variabele in de functie terecht komt. Dat wil zeggen dat deze variabele enkel voor de duur dat de functie wordt uitgevoerd bestaat (zie programming principles).

Natuurlijk kunnen we niet alleenhardcodedwaarden meegeven als we een functie aanroepen. Diezelfde 16 kunnen we in een globale variabelediameter” stoppen, en ook dan werkt onze functie nog:

drawBlackCircle(diameter);
int diameter = 16;

void setup(){
     size(500,500);
}
void draw(){
     drawBlackCircle(diameter);
}

void drawBlackCircle(int diam){
     fill(0);
     ellipse(width/2, height/2, diam, diam);
}

Waar echter vaak verwarring rond ontstaat is het volgende: Wat gebeurt er als ik in mijn functie 3 bij diam optel ?

int diameter = 16;

void setup(){
     size(500,500);
}
void draw(){
     drawBlackCircle(diameter);
}

void drawBlackCircle(int diam){
     diam = diam + 3;
     println(diam);
}

Als we kijken naar de output van deze code, zien we dat de print van de waarde die in diam zit altijd hetzelfde blijft, namelijk 19. Wat gebeurt hier precies ?

Screen Shot 2017-01-14 at 20.09.16

Een overzicht :
Screen Shot 2017-01-14 at 20.19.14Het is dus belangrijk om te onthouden dat de waarde uit de variabele die je in een functie meegeeft wordt gekopieerd naar de tijdelijke variabele(n) van de functie.

Return type

Dit bezorgt ons wel een probleem. Wat dan als we een functie willen schrijven waar wél een waarde wordt veranderd of berekend en weer terug moet naar een globale variabele ? Daarvoor is het eerste woord  van de functie van groot belang. Deze geeft namelijk het “return type” aan.

Een functie die een waarde teruggeeft begint altijd met als eerste woord het type van die waarde en eindigt met het woord “return“, met daarachter hetgeen er moet worden teruggegeven. Een voorbeeld:

int som(int a, int b, int c){
     return a+b+c;
}

Bovenstaande functie telt 3 gehele getallen met elkaar op, en geeft het resultaat terug.
Let op:

  • de functie begint met het woord “int“. Dit wil zeggen dat de waarde die uit de functie zal terugkomen een geheel getal is
  • de functie bevat als laatste zinreturn a+b+c”. Dit is de waarde die de functie teruggeeft
  • een functie die niet  “void” als type heeft, moet altijd als laatste zinreturn” bevatten

Deze functie geeft dus de som van 3 getallen terug. We roepen ze alsvolgt aan in setup() of draw():

 som(3,4,5);

Op deze manier wordt de functie wel uitgevoerd, maar wordt er niets met de waarde gedaan die wordt teruggegeven. We kunnen deze waarde opslaan in een globale variabele:

int mijnTotaal;

void setup(){
     size(500,500);
}

void draw(){
     mijnTotaal = som(3,4,5);
     println(mijnTotaal);
}

int som(int a, int b, int c){
     return a+b+c;
}

Ook hier duiden we de flow aan om duidelijkheid te scheppen:

Screen Shot 2017-01-14 at 20.36.19

Oefening

// Schrijf een functie die 1 argument accepteert: F voor Fahrenheit
// De functie berekent vervolgens de Celcius waarde

// C = (F - 32) * (5 / 9)


______ tempConverter(float ________) {
  _____ _______ = ______________
  _____________________________
}

Arrays >