Hallo, en welkom terug.
In deze lezing wil ik het hebben over enkele veelvoorkomende fouten die je zult maken
tijdens het programmeren in c.
Sommige hiervan ken je misschien van je vorige uitdagingen,
en je bent deze fouten al tegengekomen, maar dit
zijn de meest voorkomende soorten fouten.
De eerste is heel, heel duidelijk. Er ontbreekt een puntkomma.
Onthoud dat alle uitspraken in c eindigen op een puntkomma.
Als je het daar niet hebt, gaat de compiler klagen.
Dus ofwel het verkeerd plaatsen van een puntkomma of het volledig missen van een
puntkomma is een veel voorkomende fout. In dit geval plaatsen we een puntkomma verkeerd.
We hebben een if-statement. We plaatsen een puntkomma aan het einde van het if-statement.
En dit zorgt er eigenlijk voor dat het gedrag van het programma totaal anders is.
Dit zal daadwerkelijk compileren.
Als u een puntkomma mist en deze niet eens heeft opgenomen, wordt deze niet gecompileerd.
Maar in dit geval wordt de waarde van j altijd op nul
gezet omdat de puntkomma op het if-statement is geplaatst.
Dus de puntkomma is perfect geldig om het na de if-instructie te hebben.
Het vertegenwoordigt eigenlijk de nulverklaring.
En daarom heb je geen fout van de
compiler, maar dit zal een probleem veroorzaken omdat j nooit op nul zal worden gezet.
En dit soort fouten kan ook veel voorkomen bij looping.
Als je een lus hebt en je zet de puntkomma
aan het einde van de for-lus en dan heb je misschien een haakje, waar je
het haakje niet hebt omdat je een fout hebt als je het haakje hebt, heel gebruikelijk.
Een andere is het verwarren van de is gelijk aan operator met de is gelijk is aan de operator.
Specifiek vermeld dat de operator is gelijk aan
is geen tekenreeksen vergelijkt. Dus als u is gelijk aan is gelijk aan
wanneer u tekenreeksen vergelijkt, is dat niet geldig. Het gaat gewoon om de referenties te vergelijken.
Maar als je echt een waarde aan een variabele wilt toewijzen en in
plaats daarvan de equals is equals wilt gebruiken, heb je een compiler.
Als je nu twee items probeert te vergelijken, zoals
twee gehele getallen in een if-statement en in plaats daarvan de
toewijzingsoperator gebruikt, heb je eigenlijk geen compilerfout,
maar die expressie zal altijd worden geëvalueerd als waar.
Dus als je de equals gebruikt en niet de equals is
gelijk aan, dan wordt dit meestal gedaan in de if while do-instructie, binnen de Booleaanse expressie.
En dit is geldig, behalve dat het het effect
heeft iets toe te wijzen in plaats van iets uit te voeren.
Dus in dit
voorbeeld, als a gelijk is aan 2, wijst het 2 toe aan a.
Het is altijd ingesteld op waar, want dat is een waar statement, omdat je
nooit faalt als het een opdracht uitvoert. En dus zal printf altijd worden uitgevoerd.
Wat je hier echt wilde doen, is zeggen als a gelijk is aan.
Het is dus heel gebruikelijk om de gelijken te gebruiken in plaats van de gelijken
is gelijk aan en dan is er geen compilerfout.
Als u in de verkeerde situatie de
gelijken is gelijk aan,
kunt u ook onverwacht gedrag vertonen, maar u
krijgt een compilerfout als u deze verkeerd gebruikt voor toewijzing.
Maar wees hier voorzichtig mee met de gelijken in plaats van de gelijken gelijken.
Prototypeverklaringen weglaten.
Ik zei al dat het erg belangrijk is om je functies altijd
bovenaan het bestand te declareren voordat je ze gebruikt.
Dit gebeurt echter niet altijd en het is een veel voorkomende fout.
En meestal krijg je een impliciete declaratiefout in
de compiler.
In dit voorbeeld, als je vierkantswortel later in het programma
hebt gedefinieerd dan waar je het aanroept of in een ander
bestand en je hebt het
niet expliciet aangegeven, krijg je enkele waarschuwingen.
De compiler gaat ervan uit dat de functie een int teruggeeft.
Het is altijd het veiligst om die prototypeverklaring bovenaan op te
nemen voor alle functies die
u aanroept, expliciet
of impliciet door het juiste headerbestand in uw programma op te nemen.
Maar als je dat niet opneemt, kunnen die prototype-declaraties
fouten bevatten.
Het niet opnemen van het headerbestand dat de definitie bevat voor
een c-programmeerbibliotheekfunctie die in het programma wordt gebruikt.
Dus in dit geval wil je wat code hergebruiken. Misschien heb je de printf-functie
waarvan je wat uitvoer wilt weergeven, maar je hebt niet het standaard lib-headerbestand.
Dat is een vergissing. En dat wordt je meestal verteld door de compiler.
Er zal een koppelingsprobleem zijn
met die functie.
Dus in dit geval hebben we dubbel antwoord gelijk aan vierkantswortelwaarde 1.
Als dit programma de wiskunde niet bevat. header-bestand, zal dit
een fout genereren dat de vierkantswortel niet gedefinieerd is.
Het zal gaan proberen om de objectbestanden te koppelen. Het zal geen wiskunde hebben. O.
En het zal zeggen, hé, je noemt de vierkantswortel, maar er is geen implementatie voor.
Zorg er dus voor dat u de juiste
headers opneemt voor al uw aanroepen van functies, vooral uit de standaardbibliotheek.
Een tekenconstante in een tekenreeks verwarren.
Dus hier, als we tekst hebben die gelijk is aan een binnen enkele aanhalingstekens,
is dat een enkel teken dat aan tekst is toegewezen.
Als we een variabele hebben met de naam tekst en we wijzen deze toe
tussen dubbele aanhalingstekens, dan is dat een verwijzing naar de tekenreeks.
Dat geldt niet voor een enkel
teken.
En dit hebben we eigenlijk gehad
over stringconstanten en ze toe te wijzen aan karakterarrays.
En hoe je dat niet kunt doen met de gelijken en je
ze daadwerkelijk moet doen met de sterkopie.
In dit geval, als we zeggen dat tekst gelijk is aan a, wijst het een
aanwijzer toe en dit is eigenlijk ook niet
geldig en kijk wat je zou moeten doen, je zou moeten doen
dat de stertekst gelijk is aan a of de sterkopie als je niet wil
het niet zo direct toewijzen.
Maar je snapt de essentie.
Het gebruik van een binnenkant van enkele aanhalingstekens versus een teken tussen
dubbele aanhalingstekens is totaal anders, teken versus tekenreeks.
In het eerste geval wordt tekst normaal gesproken gedeclareerd als een char-variabele.
En in het tweede geval moet het worden gedeclareerd als een typeaanwijzer naar een char.
En als u een andere waarde aan die aanwijzer wilt toewijzen
dan de aanwijzer zelf, moet u de verwijzing ernaar verwijderen.
Dit is eigenlijk onjuist, want als het een aanwijzer is
in plaats van een adres toe te wijzen, wijst u er een tekenreeks aan toe, dus
dat is niet logisch.
Gebruik van de verkeerde grenzen voor een array, array out-of-bounds-uitzondering.
Hier declareren we een integer-array met een grootte van 100 en vervolgens
een paar variabelen I en som, waarbij slechts enkele worden geïnitialiseerd.
En we gaan door onze lus, we zeggen voor I is gelijk aan 1 I is kleiner dan gelijk aan 100.
Dat is onjuist, want de grootte van honderd betekent dat er honderd elementen
in de array zitten. Maar arrays zijn gebaseerd op nul.
Het eerste element is dus nul. De maximale index die u
kunt toewijzen of openen in de a-array is 99.
Dit gaat naar minder dan gelijken.
Dus je gaat hier een fout maken die buiten de grenzen valt.
Dit is geen geldig
subscript omdat deze lus helemaal naar 100 gaat.
Het is waarschijnlijk ook onjuist omdat je begint bij 1.
Als je echt het eerste element van deze array zou willen, zou je beginnen bij 0.
Het vergeten om een extra locatie in een array te
reserveren voor het afsluitende null-teken van een string
is ook een veelvoorkomend probleem.
Wanneer u uw tekenreeksen declareert, moeten ze groot genoeg zijn om alleen het afsluitende teken te bevatten.
Dit is de reden waarom ik u zou aanraden
om geen grootte in een array te plaatsen wanneer u deze maakt als u deze initialiseert.
Je zou het formaat er alleen in zetten als je het niet initialiseert.
Als u initialisatie op dezelfde regel maakt, laat c het werk
voor u doen, het zal automatisch de juiste maat plaatsen en het bevat die nulterminator.
Dus als je bijvoorbeeld een tekenreeks hebt met de naam
hallo, dit zijn meer dan vijf geheugenlocaties, het zijn er zes vanwege die nul-terminator aan het einde.
Vergeet de grootte van uw arrays niet.
Dit is een veelvoorkomend probleem met pointers waar we nog niet veel over hebben besproken, maar ik
wilde het toch even noemen omdat het heel gewoon is.
In aanwijzers, wanneer u toegang wilt krijgen of zelfs instructies wilt geven,
wanneer u iets wilt openen
met een aanwijzer, moet u het streepje groter dan het symbool gebruiken.
Dat wordt gebruikt wanneer u een pointer-element opent.
Dus als je een aanwijzer hebt die naar een structuur verwijst, is dat hoe je er toegang toe krijgt.
Als u een structuur heeft,
is het geen aanwijzer, maar opent u deze met een puntoperator.
Vaak wordt deze puntoperator en dit streepje dan groter
dan verkeerd gebruikt.
Punt voor niet-aanwijzers, aanwijzers streepje groter dan, dit zal in meer
van onze voorbeelden duidelijk worden.
Het weglaten van de ampersand vóór niet-pointervariabelen in een scanf-aanroep.
Onthoud dus dat onze scanf-aanroep een pointer als tweede argument verwacht, en
dat betekent een adres.
Wanneer we een gegevenstype declareren als een variabele van het type int, is
dat geen pointer.
Dus om scanf in staat te stellen die gegevens in onze int-variabele op te slaan, moeten we het de ampersand
doorgeven om te zeggen dat het een adres is.
Dit is dus onjuist,
zonder de ampersand voor het nummer en scan f omdat het
tweede argument niet geldig is. De enige keer dat u de ampersand niet hebt, is als u
een aanwijzer gebruikt, zoals een tekenreeks.
Alle argumenten die verschijnen na de format string en scanf moeten pointers zijn.
Een aanwijzervariabele gebruiken voordat deze wordt geïnitialiseerd.
Dus hier is een voorbeeld van het maken van een aanwijzer en het vervolgens proberen toe te wijzen.
En dit is de juiste toewijzing waarbij je een waarde toekent die je de-refereert.
Maar wat we hier niet hebben gedaan, is dat we de aanwijzer hebben geïnitialiseerd om er daadwerkelijk
geheugen voor te krijgen en je kunt
dit niet doen in c.
U kunt de indirecte-operator, het sterretje
ervoor, alleen toepassen op een
punt of variabele nadat u de variabele ergens hebt ingesteld.
Dus het moet ergens naar wijzen, op dit moment is het nul, het wijst nergens omdat je
geen geheugen hebt toegewezen.
Dus de char-aanwijzer is nooit ingesteld om naar iets te verwijzen, dus de toewijzing heeft geen betekenis.
Dit zou in feite een segmentatiefout veroorzaken.
Een andere veelvoorkomende fout is het weglaten van de break-instructie aan het einde van een case in een switch-instructie.
Als pauze niet is opgenomen aan het einde van een zaak, wordt de uitvoering voortgezet naar de volgende zaak.
Dus dit is wat ik zei als je een zaak hebt, het wordt geëvalueerd.
En als je die break daar niet hebt, gaat het direct
naar het volgende geval en zal de code in dat volgende geval uitvoeren.
U wilt dus altijd pauzes in uw case-statements hebben.
Er zijn momenten waarop u een vervolgzaak naar een andere zaak
wilt hebben en ze doen precies hetzelfde, in
dat geval zou u niets in de zaakverklaring hebben.
Een puntkomma invoegen aan het einde van een preprocessor-definitie.
Preprocessor-definities onthouden beginnen met het
nummer, het hekje. De preprocessor wordt meestal vóór de compiler
uitgevoerd voor optimalisatie.
De juiste syntaxis voor preprocessordefinities mag geen puntkomma bevatten.
In c maakt u er echter een gewoonte van om altijd een puntkomma achter alles te plaatsen.
Maar je moet onthouden dat als je een aantal constante gegevens definieert waarvan
je de puntkomma niet nodig hebt, dit onjuist is.
Dit leidt tot een syntaxisfout als
een dergelijke expressie wordt gebruikt.
zoals dat. Dus als je dat echt probeert te
gebruiken om te vinden, is het oké om die puntkomma aan het einde te hebben.
Maar wanneer de preprocessor draait, gaat hij precies invoegen wat er in dat gedefinieerd staat.
Dus het gaat naar het einde van de gegevens 999 dubbele punt.
Dit is wat de compiler het gaat zien en het zal daadwerkelijk een fout veroorzaken,
dat zou een syntaxisfout zijn.
Het weglaten van een haakje sluiten of aanhalingstekens sluiten op
een verklaring, heel gebruikelijk. Dit is dus ook direct gerelateerd
aan haakjes, een beginnende accolade hebben en dan de accolade niet beëindigen,
hetzelfde met haakjes. In dit geval
hebben we twee beginnende linkerhaakjes of drie, maar we
hebben slechts twee eindhaakjes. We missen een eindigend rechter haakje.
Dat zou een syntaxisfout zijn die de compiler zou vinden.
Dus wanneer u insluiten tussen haakjes gebruikt om elk deel van een vergelijking te onderscheiden, zorgt
dit voor een beter leesbare regel code.
U wilt haakjes gebruiken.
Als je er echter zeker van wilt zijn
dat ze allemaal overeenkomen, moet je een haakje beginnen, je moet een haakje sluiten dat eindigt, hetzelfde met accolades.
Je begint een accolade, deze moet een eindigende accolade hebben.
Dus of je hebt te veel of je hebt
te weinig, maar de compiler gaat klagen, en dit is heel, heel gebruikelijk.
Dus de tweede regel hier mist ook een afsluitend aanhalingsteken, dit printstatement.
We hebben geen eindofferte.
De compiler zal daarover klagen.
Beide zullen een compileerfout genereren.
Soms is de compiler echter erg misleidend omdat hij niet
echt weet waar de fout optreedt. Het denkt dat de fout op een volgende regel is opgetreden.
Dus de regel die u de fout vertelt, kan misleidend zijn.
Dus afhankelijk van of de compiler
een haakje of een aanhalingsteken gebruikt op een volgende
regel, zal hij die uitdrukking daadwerkelijk voltooien.
Dus het zal de fout naar een andere regel verplaatsen.
En dat is wat het zal klagen en zeggen dat daar de fout zit. Maar de eigenlijke
fout is hoger dan waar je hem wilde plaatsen.
Dit zijn enkele veelvoorkomende fouten die ik veel c-programmeurs zie
maken.
Ze zijn eenvoudig te repareren. En als je ze begrijpt en
dit bestudeert, weet je
dat je ze niet moet maken. Het is prima om ze
als beginner te maken, maar naarmate je meer en meer codeert
en meer oefent, zul je je realiseren, hey, ik ben een haakje
vergeten, ik ben een haakje vergeten, ik heb de gelijken en de gelijken gelijken niet
correct gebruikt , Ik gebruik pointers verkeerd, ik heb geen geheugen toegewezen.
Al deze dingen zullen meer een tweede natuur worden. Dank u.