# Expressies en operators

### Expressies en operators

Zonder expressies is programmeren saai: je kan dan enkel variabelen aan elkaar toewijzen. Expressies zijn als het ware eenvoudige tot complexe sequenties van bewerkingen die op 1 resultaat uitkomen met een specifiek datatype. De volgende code is bijvoorbeeld een expressie: `3+2`.

Het resultaat van deze expressie is **`5`** (type `int`).

#### Expressie-resultaat toewijzen

Meestal zal je expressies schrijven waarin je bewerkingen op en met variabelen uitvoert. Vervolgens zal je het resultaat van die expressie willen bewaren voor verder gebruik in je code. In de volgende code kennen we het **expressie**-resultaat toe aan een variabele:

```csharp
int temperatuursVerschil = temperatuurGisteren - temperatuurVandaag;
```

Hierbij zal de temperatuur uit de rechtse 2 variabelen worden uitgelezen, van elkaar worden afgetrokken en vervolgens bewaard worden in `temperatuursVerschil`.

Een ander voorbeeld van een **expressie**-resultaat toewijzen maar nu met literals:

```csharp
int temperatuursVerschil = 21 - 25;
```

Uiteraard mag je ook combinaties van literals en variabelen gebruiken in je expressies:

```csharp
int breedte = 15;
int oppervlakte = 20 * breedte;
```

#### Operators en operanden

Om expressies te gebruiken hebben we ook zogenaamde **operators** nodig. Operators in C# zijn de wiskundige bewerkingen zoals optellen, aftrekken, vermenigvuldigen en delen. Deze volgen de klassieke wiskundige regels van **volgorde van berekeningen**:

1. **Haakjes**
2. **Vermenigvuldigen, delen en modulo**: `*`, `/` , `%` (rest na deling, ook modulo genoemd).
3. **Optellen en aftrekken**: `+` en `-`

{% hint style="info" %}
We spreken over operators en **operanden**. Een operand is het element dat we links en/of rechts van een operator zetten. In de som `3+2` zijn `3` en `2` de operanden, en `+` de operator. In dit voorbeeld spreken we van een **binaire operator** omdat er twee operanden zijn.

Er bestaan ook **unaire operators** die maar 1 operand hebben. Denk bijvoorbeeld aan de `-` operator om het teken van een getal om te wisselen: `-6`.

In hoofdstuk 5 zullen we nog een derde type operator ontdekken: de **ternaire operator** die met 3 operanden werkt!
{% endhint %}

Net zoals in de wiskunde kan je in C# met behulp van de haakjes verplichten het deel tussen de haakjes eerst te berekenen, ongeacht de andere operators en hun volgorde van berekeningen:

```csharp
3+5*2 // zal 13 (type int) als resultaat geven
(3+5)*2 // zal 16 (type int) geven
```

Je kan nu complexe berekeningen doen door literals, operators en variabelen samen te voegen. Bijvoorbeeld om te weten hoeveel je op Mars zou wegen:

```csharp
double gewichtOpAarde = 80.3; //kg
double gAarde = 9.81;  
double gMars = 3.711; 
double gewichtOpMars = (gewichtOpAarde/gAarde) * gMars; //kg
Console.WriteLine("Je weegt op Mars " + gewichtOpMars + " kg");
```

**Modulo operator `%`**

De modulo operator die we in C# aanduiden met `%` verdient wat meer uitleg. Deze operator zal als resultaat de gehele rest teruggeven wanneer we het linkse getal door het rechtse getal delen:

```csharp
int rest = 7%2; 
int resultaat2 = 10%5;
```

Lijn 1 resulteert in de waarde `1` die in `rest` wordt bewaard: 7 delen door 2 geeft 3 met rest 1. Lijn 2 zal 0 geven, want 10 delen door 5 heeft geen rest.

De modulo-operator zal je geregeld gebruiken om bijvoorbeeld te weten of een getal een veelvoud van iets is. Als de rest dan 0 is weet je dat het getal een veelvoud is van het getal waar je het door deelde.

Bijvoorbeeld om te testen of getal even is gebruiken we **`%2`**:

```csharp
int getal = 1234234;
int rest = getal%2;
Console.WriteLine("Indien het getal als rest 0 geeft is deze even."); 
Console.WriteLine("De rest is: " + rest);
```

**Verkorte operator notaties**

Heel vaak wil je de inhoud van een variabele bewerken en dan terug bewaren in de variabele zelf. Bijvoorbeeld een variabele vermenigvuldigen met 10 en het resultaat ervan terug in de variabele plaatsen. Hiervoor zijn enkele verkorte notaties in C#. Stel dat we een variabele `int getal` hebben:

| **Verkorte notatie** | **Lange notatie**  | **Beschrijving**                         |
| -------------------- | ------------------ | ---------------------------------------- |
| `getal++;`           | `getal = getal+1;` | variabele met 1 verhogen                 |
| `getal--;`           | `getal = getal-1;` | variabele met 1 verlagen                 |
| `getal+=3;`          | `getal = getal+3;` | variabele verhogen met een getal         |
| `getal-=6;`          | `getal = getal-6;` | variabele verminderen met een getal      |
| `getal*=7;`          | `getal = getal*7;` | variabele vermenigvuldigen met een getal |
| `getal/=2;`          | `getal = getal/2;` | variabele delen door een getal           |

{% hint style="info" %}
Je zal deze verkorte notatie vaak tegenkomen. Ze zijn identiek aan elkaar en zullen dus je code niet versnellen. Ze zal enkel compacter zijn om te lezen. Bij twijfel, gebruik gewoon de lange notatie.
{% endhint %}

{% hint style="danger" %}
De verkorte notaties hebben ook een variant waarbij de operator links en de operand rechts staat. Bijvoorbeeld `--getal`. Beide doen het zelfde, maar niet helemaal. Je merkt het verschil in volgende voorbeeld:

```csharp
int getal = 1;
int som = getal++; //som wordt 1, getal wordt 2
int som2 = ++som; //som2 wordt 2, som wordt 2
```

Als je de operator achter de operand zet (`som++`) dan zal eerst de waarde van de operand worden teruggegeven, vervolgens wordt deze verhoogd. Bij de andere (`++som`) is dat omgekeerd: eerst wordt de operand aangepast, vervolgens wordt nieuwe waarde als resultaat van de expressie teruggegeven.
{% endhint %}

> ![](https://2320684026-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FouoIA7Dvx8ty0RZ0Hqs1%2Fuploads%2Fgit-blob-ccb1523c1944719db33fc89944ba5374decaa4a9%2Fattention.png?alt=media)Gegroet! Zet je helm op en let alsjeblieft goed op. Als je de volgende sectie goed begrijpt dan heb je al een grote stap vooruit gezet in de wondere wereld van C#.
>
> Ik zei je al dat variabelen het hart van programmeren zijn. Wel, expressies zijn het bloedvatensysteem dat ervoor zorgt dat al je variabelen ook effectief gecombineerd kunnen worden tot wondermooie nieuwe dingen.
>
> Succes!

{% hint style="info" %}
De voorman verschijnt wanneer er iets beschreven wordt waar véél fouten op gemaakt worden, zelfs bij ervaren programmeurs. Opletten geblazen dus.
{% endhint %}

### Expressiedatatypes

Lees deze zin enkele keren luidop voor, voor je verder gaat: **De types die je in je expressies gebruikt bepalen ook het type van het resultaat.** Als je bijvoorbeeld twee `int` variabelen of literals optelt zal het resultaat terug een `int` geven (klink logisch, maar lees aandachtig verder):

```csharp
int result = 3 + 4;
```

Je kan echter geen kommagetallen aan `int` toewijzen. Als je dus twee `double` variabelen deelt is het resultaat terug een `double` en zal deze lijn een fout geven daar je probeert een `double` aan een `int` toe te wijzen:

```csharp
int otherResult = 3.1 / 45.2; //dit is fout!!!
```

Bovenstaande code geeft volgende fout: *"Cannot implicitly convert double to int."*

**Let hier op!**

#### But wait... it gets worse!

Wat als je een `int` door een `int` deelt? Het resultaat is terug een `int`. Je bent echter alle informatie na de komma kwijt. Kijk maar:

```csharp
int getal1 = 9;
int getal2 = 2;
int result = getal1/getal2;
Console.WriteLine(result);
```

**Er zal `4` op het scherm verschijnen!** (niet `4.5` daar dat geen `int` is).

#### Datatypes mengen in een expressie

Wat als je datatypes mengt? Als je een berekening doet met bijvoorbeeld een `int` en een `double` dan zal C# het 'grootste' datatype kiezen. In dit geval een double.

Volgende code zal dus werken:

```csharp
double result = 3/5.6;
```

Volgende code niet:

```csharp
int result = 3/5.6;
```

En zal weer dezelfde fout genereren: *"Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)"*

Wil je dus het probleem oplossen om 9 te delen door 2 en toch 4.5 te krijgen (en niet 4) dan zal je minstens 1 van de 2 literals of variabelen naar een double moeten omzetten.

Het voorbeeld van hierboven herschrijven we daarom naar:

```csharp
int getal1 = 9;
double getal2 = 2.0; //slim he
double result = getal1/getal2;
Console.WriteLine(result);
```

En nu krijgen we wel `4.5` aangezien we nu een `int` door een `double` delen en C# dus ook het resultaat dan als een `double` zal teruggeven.

{% hint style="warning" %}
Begrijp je nu waarom dit een belangrijk deel was? Je kan snel erg foute berekeningen en ongewenste afrondingen krijgen indien je niet bewust omgaat met je datatypes.

Laten we eens kijken of je goed hebt opgelet, het kan namelijk subtiel en ambetant worden in grotere berekeningen.
{% endhint %}

Stel dat ik afspreek dat je van mij de helft van m'n salaris krijgt[^1]. Ik verdien 10 000 euro per maand (*I wish*).

Ik stel je voor om volgende expressie te gebruiken om te berekenen wat je van mij krijgt:

```csharp
double helft = 10000.0 * (1 / 2);
```

Hoeveel krijg je van me?

**0.0 euro, MUHAHAHAHA!!!**

Begrijp je waarom? De volgorde van berekeningen zal eerst het gedeelte tussen de haakjes doen:

* 1 delen door 2 geeft 0, daar we een `int` door een `int` delen en dus terug een `int` als resultaat krijgen.
* Vervolgens zullen we deze `0` vermenigvuldigen met `10000.0` waarvan ik zo slim was om deze in `double` te zetten. Niet dus. We vermenigvuldigen weliswaar een `double` (`10000.0`) met een `int`, maar die `int` is reeds `0` en we krijgen dus `0.0` als resultaat.

Als ik dus effectief de helft van m'n salaris wil afstaan dan moet ik de expressie aanpassen naar bijvoorbeeld:

```csharp
double helft = 10000.0 * (1.0 / 2);
```

Nu krijgt het gedeelte tussen de haakjes een `double` als resultaat, namelijk `0.5` dat we dan kunnen vermenigvuldigen met het salaris om `5000.0` te krijgen, wat jij vermoedelijk een fijner resultaat vindt.

[^1]: Voorgaande voorbeeld is gebaseerd op een oefening uit het handboek "Programmeren in C#" van Douglas Bell en Mike Parr, een boek dat werd vertaald door collega lector Kris Hermans bij de Hogeschool PXL. Als je de console-applicaties beu bent en liever leert programmeren door direct grafische Windows-applicatie te maken, dan raad ik je dit boek ten stelligste aan!
