Zie Scherp Scherper - Hoofdstuk 8
Na dit hoofdstuk kan je:
System.Array-methoden gebruiken (Sort, Copy, IndexOf, …)paramsZeven losse variabelen voor zeven dagen regen?
De index tussen [ ] mag een variabele zijn, dus genereer je ze in een loop:
Tip
Vanaf 3 of meer variabelen van dezelfde soort is een array bijna altijd het antwoord.
Sorry dat we weer in het diepe duiken. Maar kijk eens achterom: schrik je hé? Je hebt al een aardige weg afgelegd sinds ik je voor het eerst in het zwembad gooide.
Alles wordt kinderspel als je er maar lang genoeg mee bezig bent.
Belangrijk
Eens de lengte vastligt, kan een array niet meer groeien of krimpen. (Lists in hoofdstuk 12 lossen dat op.)
Tip
Sinds C# 12 mag je in de plaats van de accolades ook vierkante haken schrijven: string[] kleuren = ["red", "green", "blue"];. Die vorm mag ook ná de declaratielijn, de accolades niet.
new int[3] maakt drie vakjes die meteen de defaultwaarde van hun type bevatten:
int, double: 0bool: falsechar: \0string: nullWaarschuwing
new string[5] geeft je geen vijf lege teksten, maar vijf keer null. myColors[0] == "" is dus false, en myColors[0].Length crasht. Vul een string-array eerst zelf in.
List?List nodig (hoofdstuk 12)Waarschuwing
Een array heeft Length, een List heeft Count. Een array heeft geen Count, en de foutmelding die je dan krijgt zegt niet bepaald duidelijk wat er scheelt.
Tip
Array.Resize(ref cijfers, 5) lijkt een uitweg, maar maakt achter de schermen een nieuwe array en kopieert alles over. Bij grote arrays neem je beter meteen een List.
array[index]Een Vlaamse ezelsbrug voor 0-gebaseerde indexering:
Waarschuwing
array[array.Length] valt er altijd net naast: dat is precies de IndexOutOfRangeException.
array.Length geeft het aantal elementen. Ideaal als grens van een loop:
Waarschuwing
Console.WriteLine(myColors) toont niet de inhoud. Overloop de array element per element.
Belangrijk
De compiler vangt dit niet: je ontdekt het pas bij de uitvoer. Hackers misbruiken net dit soort fouten in buffer overflow attacks.
int, double, …) bevatten de waarde zelfBelangrijk
Arrays werken by reference. Een array-variabele bevat dus niet de array zelf, maar een verwijzing ernaar.
= maakt een alias. Kopieer dus element per element, in een array die even groot is:
Tip
Of gebruik Array.Copy(bron, doel, aantal) uit de System.Array-bibliotheek.
Je roept deze methoden op Array op en geeft jouw array als argument mee:
Ze geven niets terug: ze krijgen de referentie naar jouw array en herschikken die ter plekke. Na die ene regel is myColors zelf veranderd.
Tip
Van groot naar klein sorteren doe je met een Sort() gevolgd door een Reverse().
Allebei werken ze met een startindex en een aantal elementen:
Opmerking
Clear verandert enkel de inhoud, niet de lengte. Bij Copy moet de doel-array al bestaan, en krijg je wél twee aparte arrays in het geheugen.
Array.IndexOf laat je array met rust en geeft een getal terug:
Die -1 is de afspraak voor “niet gevonden”: een index kan nooit negatief zijn. Intern overloopt de methode je array element per element, precies zoals je het zelf zou schrijven.
Belangrijk
Test op -1 vóór je het resultaat als index gebruikt, anders vlieg je met myColors[-1] tegen een IndexOutOfRangeException aan.
Staat je array gesorteerd, dan hoef je niet alles te overlopen:
BinarySearch kijkt in het midden en weet na die ene vergelijking al in welke helft het element moet liggen.
Belangrijk
Op een ongesorteerde array krijg je geen foutmelding, wel af en toe een fout antwoord. Gebruik dan IndexOf of een eigen loop.
Zodra je iets wil optellen of tellen helpt geen enkele kant-en-klare methode je nog. Je resultaat-variabele maak je aan vóór de loop:
Waarschuwing
De cast naar double is nodig: som en Length zijn allebei int, dus zonder cast doe je een gehele deling. Wil je tellen in plaats van optellen, dan staat er enkel een if in de loop.
Hiervoor bestaat geen kant-en-klare methode. Je houdt de beste kandidaat tot nu toe bij, en meteen ook zijn index:
Belangrijk
Start met punten[0], niet met 0. Met int hoogste = 0; krijg je een fout antwoord zodra alle waarden negatief zijn. Daarom start de loop ook bij index 1.
Staat rugnummer 12 in de top 5? Je loop heeft twee redenen om te stoppen: het einde van de array, of een geslaagde zoektocht.
Waarschuwing
index++ staat in de else. Verhoog je de teller altijd, dan wijst index achteraf één positie te ver. Met een for-loop en een break mag ook: je bewaart de index dan in een variabele die op -1 start.
Naam en prijs staan op dezelfde index in twee aparte arrays:
Links staan naam en prijs op dezelfde index. Rechts verhuisden de namen wel, de prijzen niet.
Waarschuwing
Array.Sort(producten) breekt de link: de namen verhuizen, de prijzen blijven staan. In hoofdstuk 9 bewaart één object de naam én de prijs samen.
Lezen mag, met vierkante haken en Length, precies zoals bij een array:
Belangrijk
Ze geven allemaal een nieuwe string terug en laten het origineel ongemoeid. boek.Trim(); op zichzelf doet dus niets: je gooit het resultaat weg. Schrijf boek = boek.Trim();. Merk het verschil met Array.Sort, die jouw array wél ter plekke aanpast.
Split levert een array op, Join voegt er terug één string van. Hoeveel elementen Split oplevert weet je op voorhand niet, dus gebruik ook hier delen.Length in je loop.
Tip
Console.WriteLine(string.Join(", ", myColors)); is meteen de kortste manier om een hele array op één lijn te tonen.
Tip
Wil je dat een methode je origineel niet aanraakt, geef dan een kopie mee die je zelf element per element hebt gevuld.
In de signatuur geef je geen grootte mee; gebruik .Length in de methode:
Waarschuwing
static void LeesData(int[6] arr) is fout: een grootte in de parameterlijst mag niet.
Nu snap je de params object[] arg in de signatuur van Console.WriteLine. Zet je params voor een array-parameter, dan steekt C# de losse waarden zelf in een array:
Waarschuwing
Er mag maar één params-parameter zijn, en die staat achteraan: static void Log(string titel, params string[] regels).
Steven wil de scores herstellen naar een verse, lege array. De A.I. gaf hem dit:
“Reset zet er een nieuwe, lege array in de plaats, dus dit toont 0”, zegt hij.
Opmerking
Er verschijnt gewoon 10. Wat je meegeeft is een kopie van de wegwijzer: die kopie mag je in de methode naar iets anders laten wijzen, de variabele in Main blijft naar de originele array kijken. Een element aanpassen (scores[0] = 99) werkt wél door, de hele array vervangen niet.
Nu snap je string[] args in Main: het zijn de opstartparameters.
Belangrijk
Test eerst args.Length >= 3, dan pas args[2]. De && stopt links bij false en zo vermijd je een crash.
Met een komma in de haken maak je een rechthoekig rooster:
Eerst de rij, dan de kolom. Beide starten bij 0.
Tip
.Length geeft het totaal (hier 28); GetLength(0) en GetLength(1) de afzonderlijke dimensies, .Rank het aantal dimensies.
Twee geneste loops: de buitenste over de rijen, de binnenste over de kolommen van die rij.
Ook een rooster gaat by reference naar een methode; in de parameter herhaal je de komma: static void ToonRooster(int[,] rooster).
Waarschuwing
Gebruik GetLength(...) en geen harde getallen. En verwissel de indices niet: regen[dag, week] compileert perfect, maar crasht bij de uitvoer.
Een 2D-array werkt zolang ieder vakje hetzelfde betekent: een spelbord, een doolhof, pixels, regen per dag.
Hier betekent elke kolom iets anders: alles moet string zijn, en boeken[1, 1] zegt nergens dat kolom 1 de auteur is.
Tip
Vanaf hoofdstuk 9 wordt dit een klasse Boek, in hoofdstuk 12 bewaard in een gewone 1D-array. De tweede dimensie verdwijnt.
Een array van arrays met verschillende lengtes. Let op de dubbele [][]:
Opmerking
Je moet ze vooral kunnen herkennen. Zelf schrijf je liever een rechthoekige [,]-array, of een collectie uit hoofdstuk 12: iedere rij apart aanmaken en apart op zijn lengte controleren is omslachtig en foutgevoelig.
Tip
En vanaf hoofdstuk 12 maken collecties veel van dit werk een stuk aangenamer.
.Length; let op de IndexOutOfRangeException= maakt een alias, kopieer dus element per elementSystem.Array en de string-methoden besparen werk; optellen, tellen en de grootste zoeken schrijf je zelfparams voor een los aantal argumenten); een 2D-array dient voor een rooster, jagged moet je enkel herkennenTip
Volgende halte: object-georiënteerd programmeren, met klassen en objecten.
Kennisclips
Dezelfde concepten uit dit hoofdstuk, maar dan in andere talen. Handig om later code in Python of JavaScript te leren lezen.
In Python bestaat geen array met vaste grootte, wel een dynamische list:
Totaal anders dan een C#-array (vaste lengte, 1 type). Lijkt eerder op de List uit hoofdstuk 12.
C# gooit netjes een IndexOutOfRangeException. In C is er geen enkele grenscontrole:
Je leest dan zomaar willekeurige geheugeninhoud of je programma crasht. Net dat maakt buffer overflow attacks mogelijk.
Ook JavaScript-arrays werken by reference, dus = maakt een alias, geen kopie:
Heel gelijkaardig aan C#. Een echte kopie: let kopie = [...ploegen];.
Een handige samenvattende poster (Opgelet: gemaakt m.b.v. ChatGPT Image Gen 2).