C-taal voor beginners - hoofdstuk 1
identifiers, declaraties, types, scherminput/output
[1.1 identifiers] [1.2 standaardwoorden in C] [1.3 een eerste programma] [1.4 variabelen definiëren] [1.5 qualificators] [1.6 geheugengebruik: bits en bytes] [1.7 standaard invoer- en uitvoer]
Vooraleer ook maar iets in C te programmeren moet u een identifier kunnen benoemen of declareren. Een identifier wordt gebruikt voor variabelen, functies, data definities, enz. Het declareren gebeurt voordat de variabele gebruikt wordt, zodat het programma weet wat ermee aan te vangen. In C is een identifier een combinatie van alfanumerieke karakters, met als eerste letter een alfabetisch teken of een underline.
Belangrijk:
Wat spaties, lege lijnen, enz. betreft kan u bijna doen wat u wilt. Tijdens het compileren worden de lege ruimtes als het ware weggegooid. Het is echter wel aan te raden na elke nieuwe opdracht een nieuwe regel te beginnen en inspringingen en dergelijke te gebruiken. Dit vergemakkelijkt het lezen voor uzelf én voor degenen die het misschien ooit zullen moeten aanpassen. Hoofdstuk 10 spitst zich toe op stijlen die u het best kan gebruiken bij het programmeren in C.
C op zichzelf herkent slechts 32 woorden. Deze zijn
voorgeprogrammeerd en kunnen niet voor andere zaken gebruikt worden. Ze moeten in kleine
letters toegepast worden. De lijst:
| auto break case char const continue default do |
double else enum extern float for goto if |
int long register return short signed sizeof static |
struct switch typedef union unsigned void volatitle while |
/* Dit is mijn eerste programma */#include<stdio.h>int main(void) { printf("Hallo wereld, dit is mijn eerste programma!\n");return 0; }
Dit simpele programma zal de zin afdrukken die tussen de dubbele quotes " " staat.
Belangrijke componenten:
/* Dit programma berekent de som van 2 getallen */#include<stdio.h>int main(void) { int som; int getal1; int getal2; printf("Geef het eerste getal: "); scanf("%d",&getal1); printf("Geef het tweede getal: "); scanf("%d",&getal2); som=getal1+getal2; printf("De som van %d en %d is %d\n",getal1,getal2,som);return 0; }
Het programma zal twee getallen vragen, daarvan de som berekenen en afdrukken op het scherm.
U merkt een paar nieuwe dingen op:
int som; int getal1; int getal2;
op deze manier wordt een variabele
gedefinieerd. M.a.w. we zeggen tegen het programma wat voor type variabelen het
zijn. In dit geval is dat van het type integer. Som, getal1
en getal2 zijn de desbetreffende variabelen. De waarde van de getallen
wordt door het programma opgenomen van de gebruiker met het commando scanf("%d",&getal1).
Dit leest een waarde in en wijst die toe aan de variabele getal1. Met
%d duiden we aan dat het om een integer gaat. Let ook op het &
teken (ampersand). Dit wil letterlijk zeggen "adres van". (zie 1.6)
Merk op dat variabelen van hetzelfde type ook in één lijn mogen gedeclareerd worden.
int som; int getal1; int getal2;
is hetzelfde als:
int som, getal1, getal2;
Ook is het mogelijk om een integer in de declaratie al een waarde te geven, zoals in de volgende voorbeelden getoont wordt:
int som, getal1 = 10, getal2;int som, getal1 = 10, getal2 = 300;float getal = 1.34542;
Volgende types variabelen zijn mogelijk:
1.4.1 constanten: const
Constanten leveren een manier om een variabele te definiëren die nergens anders in het programma kan aangepast worden:
decimaal: van 0 tot 9, voorgesteld met %d
octaal: van 0 tot 7, voorgesteld met %o en aangeduid met 0, bv: 0357 om het octale getal 357 aan te geven
hexadecimaal: van 0 tot F, voorgesteld met %x en aangeduid met 0X, bv: 0X1A om het hexadecimale getal 1A aan te geven
1.4.2 integer: int
16 bits: van -32768 tot 32767
32 bits: heeft een veel hoger bereik, het UNIX-systeem gebruikt 32 bits
1.4.3 floating point (met enkelvoudige precisie): float
dit type laat toe om (grote) kommagetallen te gebruiken, bv: 95846.9478573532
let op: een komma wordt voorgesteld door een punt "."
1.4.4 floating point met dubbele precisie: double
voor grotere floats met grotere precisie
een double gebruikt meer geheugen dan een gewone float
1.4.5 karakters: char
één of twee tekens tussen enkele quotes ' '. Toegelaten karakters zijn degenen uit de ASCII code (decimaal tussen 0 en 127)
Daarnet zag u dat u de precisie van een float variabele kunt verhogen door aan de variabele het type double toe te wijzen. Het is ook mogelijk om het waardenbereik van een integer variabele te regelen. Volgende qualificators zijn mogelijk:
1.5.1 long
voor de typespecificator int, geeft de gedeclareerde integer een uitgebreid waardenbereik
bv: long int groot; long groot;een long gebruikt 4 bytes geheugenruimte
1.5.2 short
voor de typesecificator int geeft de genoemde variabele een beperkt waardenbereik
dit wordt vooral gebruikt om geheugenruimte te sparenbv: short int teller; short teller;een short gebruikt 2 bytes geheugenruimte
1.5.3 unsigned
geeft aan dat de integer variabelen tot positieve waarden beperkt zijn
unsigned geeft een dubbel waardenbereik, aangezien de ruimte voor negatieve getallen niet nodig isbv: unsigned int geheel; unsigned geheel;een unsigned gebruikt 4 bytes geheugenruimte
1.6 geheugengebruik: bits en bytes
Bij de beschrijving van de verschillende types hierboven mag u de aanduidingen voor het geheugengebruik niet strikt nemen. Deze gelden voor het Windows besturingssysteem, draaiende op een intel PC. Je kunt er niet vanuit gaat dat een integer 16 of 32 bits is. Onder DOS is een integer meestal 16-bits en een long 32-bits. Onder Windows is een integer meestal 32-bits en een long 32-bits. Er zijn echter ook systemen waar een long 64-bits is.
De representaties en waardes van de verschillende types van integers:
| 16-bit | 16-bit | 16-bit | 32-bit | 32-bit | 32-bit | |
| type | bytes | minimum | maximum | bytes | minimum | maximum |
| char | 1 | -128 | 127 | 1 | -128 | 127 |
| signed char | 1 | -128 | 127 | 1 | -128 | 127 |
| unsigned char | 1 | 0 | 255 | 1 | 0 | 255 |
| signed short | 2 | -32768 | 32767 | 2 | -32768 | 32767 |
| unsigned short | 2 | 0 | 65535 | 2 | 0 | 65535 |
| signed int | 2 | -32768 | 32767 | 4 | -2147483648 | 2147483647 |
| unsigned int | 2 | 0 | 65535 | 4 | 0 | 4294967295 |
| signed long | 4 | -2147483648 | 2147483647 | 4 | -2147483648 | 2147483647 |
| unsigned long | 4 | 0 | 4294967295 | 4 | 0 | 4294967295 |
| float | 4 | 3.4 E-38 | 3.4 E+38 | 4 | 3.4 E-38 | 3.4 E+38 |
| double | 8 | 1.7 E-308 | 1.7 E+308 | 8 | 1.7 E-308 | 1.7 E+308 |
| long double | 10 | 1.2 E-4923 | 1.2 E+4923 | 10 | 1.2 E-4923 | 1.2 E+4923 |
De standaard ANSI-header limits.h bevat een aantal macro's (voor een uiteenzetting over macro's, zie later hoofdstuk), die erg nuttig kunnen zijn bij het bepalen van de minimum en maximumwaardes. Een overzicht:
| CHAR_BIT | Aantal bits in een byte |
| SCHAR_MIN | Minimum waarde voor een signed char |
| SCHAR_MAX | Maximum waarde voor een signed char |
| UCHAR_MAX | Maximum waarde voor een unsigned char |
| CHAR_MIN | Minimum waarde voor een char |
| CHAR_MAX | Maximum waarde voor een char |
| SHRT_MIN | Minimum waarde voor een short int |
| SHRT_MAX | Maximum waarde voor een short int |
| USHRT_MAX | Maximum waarde voor een unsigned short int |
| INT_MIN | Minimum waarde voor een int |
| INT_MAX | Maximum waarde voor een int |
| UINT_MAX | Maximum waarde voor een unsigned int |
| LONG_MIN | Minimum waarde voor een long int |
| LONG_MAX | Maximum waarde voor een long int |
| ULONG_MAX | Maximum waarde voor een unsigned long int |
Dit kan u dan bijvoorbeeld als volgt toepassen:
printf("Aantal bits in een byte is %d en de maximum waarde voor short int is %d\n",
CHAR_BIT, SHRT_MIN);
Om het aantal bytes van een expressie of type te achterhalen gebruiken we het sizeof sleutelwoord:
printf("Het aantal bytes in een integer is %d.\n", sizeof(int));
1.7 standaard invoer- en uitvoer
U zag reeds eerder het gebruik van printf() in het voorbeeldprogramma. Deze functie bevindt zich in de stdio.h bibliotheek en zorgt voor een output op het scherm. Alles tussen " " noemt men de string en wordt op het scherm getoond; \n zorgt ervoor dat er een nieuwe regel begonnen wordt. Voorbeeld:
printf("Dit is de eerste regel\n");
printf("Dit is de tweede regel\n");
geeft als output:
Dit is de eerste regel Dit is de tweede regel
maar:
printf("Dit is de eerste regel");
printf("Dit is de tweede regel");
geeft als output:
Dit is de eerste regelDit is de tweede regel
Om tekens weer te geven die in de gewone code moeilijk of niet weer te geven zijn, kan u gebruik maken van escape sequenties. Een escape sequentie begint met een backslash \ gevolgd door één karakter:
| \a | waarschuwingsbel | |
| \r | carriage return | |
| \n | regelovergang | |
| \t | horizontale tab | |
| \v | verticale tab | |
| \f | form feed | |
| \b | backspace | |
| \' | enkel aanhalingsteken | |
| \'' | dubbel aanhalingsteken | |
| \\ | backslash | |
| \? | vraagteken |
U zag ook reeds eerder op welke manier een variabele
opgenomen wordt in het argument, namelijk met het % teken gevolgd
door een karakter, afhankelijk van het type variabele. Na de string - dat is na de dubbele
quotes " " -staat er telkens een komma en daarna de naam van de
variabele waarop het procentteken en karakter betrekking hebben.
Voorbeeld:
int prijs = 157;
int aantal = 23;
printf("U kocht %d produkten tegen de prijs van %d Bef.\n",aantal,prijs);
dit levert u het volgende op:
U kocht 23 produkten tegen de prijs van 157 Bef.
Enkele andere mogelijke voorbeelden:
int getal1 = 10, getal2 = 300; produkt = getal1 * getal2; printf("Het produkt van %d en %d is %d\n",getal1,getal2,produkt);
float getal, opl; getal = 20.43234; opl = getal / 5.0; printf("Het kommagetal %f gedeeld door 5 geeft %f\n",getal,opl);
int aantal; float prijs, bedrag; aantal = 234; bedrag = 12.5; prijs = aantal * bedrag; printf("De totale kostprijs: %f",prijs);
Om het procentteken weer te geven in een string moet u het tweemaal naast elkaar plaatsen: %%.
Scanf is de theoretische tegenhanger van printf(), om output op het scherm te tonen. De syntax verschilt nauwelijks:
scanf("%d", &getal);
Nieuw is het adresteken &. Dit wil eenvoudig uitgedrukt zeggen: "adres van". In feite wordt een ingescande waarde dus niet in de variabele geplaatst, maar wel in het geheugenadres ervan. Dit is nu niet belangrijk. Wanneer we later met pointers gaan werken wordt de betekenis van geheugenplaatsen duidelijker.
De functie scanf() leest een invoerlijn in, totdat er een eerste dataveld gevonden wordt. Leidende blanco's worden genegeerd en de waarde wordt ingelezen tot aan de volgende blanco of illegaal karakter, dan stopt het lezen en wordt de waarde teruggestuurd. Onthoudt dat scanf() niets doet, vooraleer er een return gegenereerd wordt, zelfs niet als er verschillende spaties ingegeven worden. Om input op te nemen en te gebruiken kunnen we als volgt tewerk gaan:
#include<stdio.h>int main(void) { int prijs; float te_betalen, BTW; printf("Geef de prijs van het artikel in -> "); scanf("%d", &prijs"); printf("Wat is het BTW tarief? "); scanf("%f", &BTW); te_betalen = prijs * BTW / 100; printf("Het te betalen bedrag is %f", te_betalen);return 0; }
1.7.3 getchar()
De functie getchar() leest één enkel karakter in van het standaard invoerapparaat, het toetsenbord:
#include<stdio.h>main(void) { int karakter;printf("Geef een karakter in -> "); karakter = getchar(); printf("U gaf het volgende karakter in: %c", karakter); }
Let op: een variabele die gebruikt wordt met een getchar(), is van het type integer. Om het karakter te tonen gebruiken we de %c specificatie, niettegenstaande de integer declaratie. Het gebruik van %d zou natuurlijk een decimale waarde tonen.
1.7.4 putchar()
De tegenhanger putchar(), gebruikt het standaard uitvoerapparaat om één enkel karakter te tonen. Merk op dat na de uitvoer van het karakter de cursor reeds een plaats opschuift, klaar voor het volgende karakter. Op deze manier bespaart de compiler ons een paar, anders noodzakelijke, ingrepen. Voorbeeld:
#include<stdio.h>int main(void) { int karakter;printf("Geef een karakter in -> "); karakter = getchar(); getchar(); printf("U gaf het volgende karakter in: ); putchar(karakter);return 0; }
Let op de tweede getchar(). Dit is een standaardmethode om de return, die volgt na het ingeven van het karakter, op te vangen en als het ware tegen te houden. Op die manier kan deze bij een volgende getchar() geen problemen geven.
1.7.5 lengtespecificatie
Alhoewel er een reeks opties zijn om uitvoer en invoer te formatteren zal ik op dit moment enkel de lengtespecificatie bespreken. Met de lengtespecificatie kan de manier waarop iets uitgevoerd wordt aangepast worden:
| printf("De oplossing is %5d\n", opl); | voorziet een veldlengte van 5 bytes |
| printf("De som is %.4f\n, som); | toont de inhoud van de float variabele met 4 bytes na de komma |
| printf("De BTW bedraagt %5.2f\n, btw); | een totaallengte van 5, met 2 plaatsen na de komma |
| printf("Het getal is %.0f\n", getal); | toont de inhoud van de float variabele zonder cijfers na de komma |
Ook bij de invoer kan men de lengtespecificatie toepassen. Een voorbeeld:
printf("Geef een cijfer in -> ");
scanf("%1d", &cijfer);
In dit geval zal enkel het eerste teken van het antwoord in de variabele cijfer gestoken worden. Het is echter duidelijk dat hier even goed -of zelfs beter- een getchar() kan gebruikt worden.
Opmerking: mintekens, decimale punten, enz... nemen ook een byte in beslag. Wanneer de inhoud van een variabele groter is dan de breedte die voorzien werd, zal deze toch volledig getoond worden.
opdrachten
1.1 Schrijf een programma dat twee getallen vraagt, deze dan van plaats verwisseld en op het scherm toont.
1.2 Schrijf een programma dat een integer, een karakter en een float vraagt en deze dan in één string op het scherm toont.
1.3 Schrijf een programma dat de volgende 3 zinnen drukt:
Een tab is \t Een backspace is \b Een waarschuwingsbel is \a Hij zei: "C is 10% verstand en 90% oefenen".
1.4 Schrijf een programma dat de prijs excl BTW vraagt en daarna de prijs incl BTW berekent en weergeeft. Het BTW-percentage is 20.5% en is een constante.
1.5 Schrijf een programma om de verschillende mogelijkheden van de lengtespecificatie aan te tonen. Experimenteer voldoende met deze vorm van geformatteerde uitvoer en invoer.
1.6 Experimenteer voldoende met alle onderwerpen uit dit hoofdstuk, om een goede basis te hebben voor de volgende delen van de cursus.
voorbeelden
1-1.c: Druk 2 ingegeven getallen in omgekeerde volgorde af
1-2.c: Druk de ingetikte gegevens af
1-3.c: Het aantal seconden in dit jaar berekenen
referenties
[The C Library Reference Guide]
Eric Huss
Gordon Dodrill
[C FAQ]
Steve Summit