Hallo, en welkom terug. In deze lezing wil ik
een demonstratie
geven van onze vorige uitdaging, waarbij je leerde hoe
je geheugen dynamisch kunt toewijzen met malloc.
We gaan gewoon wat eenvoudig lezen vanaf het toetsenbord en
dan een tekenreeks weergeven, maar we gaan
het gebruiken met dynamisch toegewezen
aanwijzers, tekenaanwijzers.
Dus laten we codeblokken naar voren brengen om een nieuw project te maken.
En we gaan dit ene voorbeeld van dynamische geheugentoewijzing noemen.
En het eerste dat u moet doen wanneer
u dynamische geheugentoewijzing gaat gebruiken, is dat u ervoor moet zorgen dat u de standaard lib opneemt.
Als je een project in codeblokken aanmaakt, wordt het
gelukkig automatisch voor je opgenomen.
Maar de reden dat we standaard lib moeten opnemen, is omdat malloc,
de malloc-functie erin zit. En malloc, onthoud, is de belangrijkste functie
om geheugen toe te wijzen. Je hebt ook calloc.
Calloc is erg belangrijk omdat calloc een deel van
de mooie berekeningen zal doen van het aantal bytes dat je nodig
hebt, want dat zijn twee parameters.
Maar het echte goede aan calloc is dat het alle gegevens initialiseert
naar nullen als ze ints zijn enzovoort, echt een leuke functie.
Je hebt realloc. Realloc breidt het geheugen uit dat
al is toegewezen. Dus je passeert het in een aanwijzer.
Vanaf die aanwijzer bepaalt het hoeveel geheugen ervoor is toegewezen
en het kopieert alles wat daar was naar een nieuwe geheugenlocatie, en
dan specificeer je ook hoeveel meer bytes je
wilt toewijzen, voegt het gewoon toe aan de nieuwe geheugenlocatie, echt waar leuke eigenschap.
Maar onthoud dat wanneer u geheugen toewijst voor gehele getallen met malloc,
u moet bepalen hoeveel geheugen u bytes wilt toewijzen, maar meestal
wilt u de operator sizeof gebruiken.
Dus laten we daar naar toe gaan.
In mijn hoofdmethode ga ik een geheel getal maken, en ik ga gewoon
zeggen dat dat gewoon grootte zal zijn. gaat de grootte invoeren van het aantal
bytes dat ze tijdens runtime willen toewijzen, dus dat gaat de grootte opslaan.
Het andere dat ik wil maken, is dat ik een char-aanwijzer wil maken,
en dit wordt gewoon tekst. En ik ga dit
initialiseren op null omdat het niet meteen naar iets verwijst.
Het eerste wat ik nu wil doen, is de gebruiker vragen om de maat in te voeren.
Dus ik ga zeggen printf,
ik ga zeggen voer de limiet van de tekst in.
En ze gaan een getal invoeren voor het aantal bytes dat moet worden
toegewezen, in feite het aantal tekens.
En dan ga ik dat inlezen met scanf.
Scanf, de eerste parameter is het type formaatspecificatie voor het type gegevens.
Dit wordt procent d omdat ik een geheel getal lees.
En onthoud dan, scanf neemt een aanwijzer.
We weten nu dat voor functies die
pointers nodig hebben, je een adres nodig hebt om door te geven.
Dus als ik de grootte wil doorgeven, is grootte geen adres, tenzij ik het adres van de operator gebruik.
Dus ik ga naar ampersand en ik
ga zeggen grootte, dat gaat het aantal bytes inlezen.
Zodra ik het aantal bytes heb, kan ik er nu geheugen voor toewijzen met behulp van de malloc-functie.
En Malloc gaat een lege wijzer teruggeven.
En de aanwijzer wordt het eerste adres voor
dat nieuw toegewezen geheugen. U kunt het dus recht aan tekst toewijzen.
Want onthoud, tekst is een pointer.
We willen de tekst verwijzen naar dit nieuwe adres dat wordt geretourneerd.
Omdat malloc een lege aanwijzer retourneert, moeten we deze casten.
Het type gegevens waarnaar we verwijzen is een teken, dus we willen char star
zeggen, en dan kunnen we de malloc-functie aanroepen.
De malloc-functie neemt het aantal bytes.
En dus het aantal bytes, als je net het aantal bytes hebt doorgegeven, zal
het alleen zoveel bytes toewijzen. Maar afhankelijk van het type
gegevens, kan het type gegevens twee of vier bytes zijn.
Dus als u 10 tekens wilt toewijzen, moet
u ervoor zorgen dat u 10
tekens vermenigvuldigt met de grootte van char.
Dus nu gaan
we zeggen n keer sizeof. De operator sizeof wordt vaak gebruikt in
de malloc-functie omdat het machine-onafhankelijk is,
en het zal je vertellen hoeveel je eigenlijk moet toewijzen.
Dit is meer relevant als je gehele getallen hebt. Onthoud dat gehele getallen, afhankelijk van het
systeem waarop u zich bevindt, de architectuur die u gebruikt,
gehele getallen kunnen worden weergegeven door vier bytes, twee bytes, meestal
twee of vier bytes.
Als je zou zeggen dat ik één geheel getal wil
opslaan, dus ik ga gewoon vier bytes geheugen maken, nou, dat is misschien niet
correct, want wat als het twee bytes is.
U wilt dus altijd doen
hoeveel gehele getallen of hoeveel tekens u wilt maken en dat vervolgens vermenigvuldigen met de
grootte van het teken op uw systeem. De operator Sizeof geeft u het aantal bytes
dat een teken in beslag neemt. Dus als je 10 tekens wilt maken,
zeg je 10 keer de grootte van tekens. Als je 10 gehele getallen wilt
maken om 10 gehele getallen
op te slaan, zeg je 10 keer de grootte van int, dat is echt belangrijk.
Nu met de calloc-functie hoeft u dat niet te doen. Calloc heeft
eigenlijk twee parameters. En de eerste parameter
is de aanwijzer die ik denk en dan
is de tweede parameter de grootte van bytes.
Dus als u 24 int zegt, hoeft u alleen maar 24 in te
voeren en automatisch voor u toe te wijzen.
Dus calloc is een heel leuk hulpmiddel om te gebruiken, omdat je deze vermenigvuldiging niet hoeft te doen.
Dus voor calloc is de eerste parameter de grootte.
Dus als je 10 int wilt maken, zou je gewoon in 10 passen.
En dan is de tweede parameter
de grootte van de byte. Je hoeft dus niet te vermenigvuldigen. Het bespaart je een klein stukje van de stap.
Nu we geheugen hebben toegewezen, wil je
ervoor zorgen dat de tekst niet null is voordat je de verwijzing naar tekst probeert te verwijderen.
Dus je wilt dit altijd rond een niet-tekst wikkelen, en dat zal zeggen dat het
niet null is of je kunt het gewoon expliciet doen en zeggen
als tekst niet gelijk is aan null.
Ik wil dat altijd doen omdat het heel, heel gevaarlijk is om
te proberen een verwijzing naar een pointer te verwijderen.
Er kan van alles gebeuren. Mogelijk kunt u er gegevens in schrijven.
erin. Het zou het gewoon ergens anders in het geheugen schrijven. Dus het
zou je programma verpesten of je zou een segmentatiefout kunnen hebben en het programma kan crashen.
Maar zolang je dat geheugen echt toewijst, kun
je nu ook daadwerkelijk wat gegevens inlezen.
Je kunt git s gebruiken of je kunt scanf hier gebruiken.
Maar wat u wilt doen,
is afdrukken, wat tekst invoeren en
we willen hier ook regelfeeds toevoegen, zodat ze gemakkelijk te lezen zijn.
En we zullen scanf gebruiken, omdat we daar bekend mee zijn.
En scanf gaat gewoon in procenten
lezen.
Eigenlijk ga ik je een trucje laten zien.
Ik ga scanf gebruiken om het volgende teken in te lezen, dus
het pauzeert en dan ga ik get s gebruiken om in de tekst te lezen.
En krijgt is gewoon een andere functie die je meestal kunt gebruiken met de f krijgt. U hoeft het alleen maar in te
stellen op de invoerstroom.
Maar krijgt gaat lezen van de standaard invoerstroom, die standaard het toetsenbord is.
En krijgt gaat een wijzer nemen. Dus alles wat we hoeven te doen is tekst doorgeven omdat
het al een aanwijzer is, we hoeven het adres van de operator niet in te voeren.
En het leuke van get ask is dat je in meerdere strings kunt lezen, gescheiden door spaties.
Zodra we daadwerkelijk inlezen krijgen, kunnen
we het gewoon uitprinten. We kunnen dus zeggen ingevoerde tekst
als ingevoerd een woord procent s backslash n
is en dan kommatekst. Tekst is een aanwijzer.
Printf neemt een aanwijzer. We hoeven het niet te de-refereren.
Want als u alleen tekst weergeeft,
geeft tekst de waarde van de aanwijzer weer die een adres wordt.
We willen eigenlijk de waarde weergeven van waar tekst naar verwijst.
En dan zijn we klaar. Oh nee, we zijn zeker nog niet klaar. Wij willen onze gratis bellen.
We willen onze aanwijzer vrijgeven.
Ook al zal de herinnering vrij zijn als we afsluiten. We willen er nog steeds zeker van zijn
dat we het vrijgeven, en dan willen we waarschijnlijk ook gewoon voor de bewaring, we willen de tekst gelijk stellen aan null.
Dus laten we doorgaan en dit bouwen en kijken wat er gebeurt.
En ik heb een probleem omdat ik niet in de
juiste variabele lees.
dus hier gebruik ik niet de juiste variabele. Ik wil maat gebruiken, en het
lijkt erop
dat we goed zitten.
Dus hier gaan we, het enige verschil is dat je de tekst
niet hoeft te de-referentie omdat tekst een tekenaanwijzer is.
U hoeft alleen te de-refereren als in de aanwijzer enzovoort. Dus wanneer u de
procent s gebruikt, weet het automatisch de tekenaanwijzer
te de-referentie.
Dat is een verschil wanneer u tekenaanwijzers
gebruikt versus andere aanwijzers. De andere pointers die
je moet de-refereren om de waarde te krijgen, omdat je
strings niet echt naar string-arrays kunt kopiëren, enzovoort.
Je zou nooit in staat zijn om stertekst gelijk
te maken, je zou altijd de str-kopie moeten gebruiken als je tekst wilt kopiëren.
Want onthoud van de lezingen, je kunt eigenlijk
geen gegevens aan een array toewijzen, en een tekenaanwijzer is een array.
Dus hier lijkt dit correct. Geen reden om het te de-refereren.
We willen dit bouwen, en dan willen we het uitvoeren.
En je zult merken dat we de limiet van de tekst stellen.
Dus stel dat we 5, 6 invoeren voor jason en
dat de invoer jason is.
En je kunt spelen met dit programma. Maar nogmaals, de afhaalrestaurants
hiervan omvatten standaard lib wanneer je malloc doet.
Initialiseer uw karakteraanwijzers naar null. Voer een scan
uit, gebruik de ampersand omdat grootte geen pointer is.
Als je aan het malloceren bent, geeft malloc een lege aanwijzer terug, dus je moet casten.
Je wilt altijd binnen in je malloc. Voer de operator
sizeof uit voor wat u wilt toewijzen. Tijden, hoeveel werkelijke tekens of
gehele getallen zijn. Dit is technisch gezien meer van toepassing
op gehele getallen en primitieve gegevenstypen voor tekens. Je kunt gewoon de maat nemen, dat zou goed moeten werken.
Als je altijd op null wilt controleren, zorg er dan voor dat het niet null is.
Wanneer u tekenreeks gaat gebruiken.
En dan voeren we gewoon wat tekst in, opgeslagen in onze Gets en printen het uit.
En dan, last but not least, we willen altijd onze aanwijzingen vrijgeven, zodat we die terug
kunnen geven aan de hoop. Ik hoop dat dit helpt. Dank u.