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]


1.1 identifiers

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.

1.2 standaardwoorden 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

1.3 een eerste programma

/* 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:

1.4 variabelen definiëren

/* 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)

1.5 qualificators

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 sparen

            bv: 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 is

            bv: 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

1.7.1 printf()

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: %%.

1.7.2 scanf()

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

[C Language Tutorial]

Gordon Dodrill

[C FAQ]

Steve Summit

 

Verder naar hoofdstuk 2

Terug naar inleiding