C (programmeertaal)

**C** is 'n hoëvlakprogrammeertaal wat in die vroeë 1970's deur Dennis Ritchie by Bell Laboratoriums ontwikkel is. Dit is oorspronklik gebruik vir stelselprogrammering, maar het gou getoon dat dit kragtig en buigsaam genoeg is vir ontwikkeling van 'n verskeidenheid van programmatuur.

Die eerste intensiewe program ontwikkel in C is die Unix-bedryfstelsel. Dit word steeds grootliks geassosieer met hierdie bedryfstelsel.

Alhoewel dit 'n hoëvlak programeertaal is, is dit soortgelyk aan laevlak programmeertale.

## Ontwerp 
C is 'n proseduregedrewe taal. Die ontwerp is so opgestel om baie direkte omskakeling vanaf kode- na mikroverwerkerinstruksies te doen, om minimale hardloop ondersteuning te kort vanaf die sisteem en laevlaktoegang tot geheue te verseker. C is dus ideaal om programme oor te skryf wat in samestellertaal geskryf is.

C is opgestel om redelik eenvoudig op verskillende platforms gebruik te kan word. 'n C-program wat die standaarde van die taal volg behoort op 'n verskeidenheid platforms te kan loop met minimale veranderinge aan die bronkode.

## Oorsig 
In C-taal word alle uitvoerbare kode omskryf in afsonderlike subroetines bekend as "funksies" (hierdie moet nie verwar word met funksionele programmering nie). Funksie parameters word altyd weergegee met hul waardes, aangesien verwysings nie werklik in C bestaan nie. Wanneer jy direk 'n veranderlike se waarde verander (meer bekend as werk met verwysings), dan word daar eintlik indirek aan die veranderlike verander deur gebruik te maak van wysers.

'n Enkele stelling in C word beëindig met 'n kommapunt, terwyl krulhakies gebruik word om groepe van stellings te vorm.

Die C-taal het ook die volgende eienskappe:
* Daar is 'n klein, vaste hoeveelheid beskikbare sleutelwoorde.
* Daar is 'n groot hoeveelheid beskikbare logiese en wiskundige operatore, soos `+`, `+=`, `++`, `&`, `~`, ens.
* Meer as een waarde mag aan 'n veranderlike toegeken word in 'n enkele stelling (slegs die laas toegekende waarde word egter behou)
* Die waarde wat deur funksies terug gestuur word, kan geïgnoreer word indien nodig.
* Alle datatypes het 'n swak vaste tipe - in ander woorde dit kan maklik omgestel word in 'n ander type (byvoorbeeld om die char 8 as die int 8 te gebruik).
* Die verklaringsintaksis stem oorreen met die gebruik van die taal. Daar is byvoorbeeld nie 'n defineer sleutelwoord om aan te dui jy defineer 'n nuwe veranderlike nie, eerder word die veranderlike se tipe gebruik om aan te dui dat 'n nuwe veranderlike gedefineer word (byvoorbeeld nie define num as int; nie maar slegs int num;) Daar is ook nie 'n sleutelwoord vir 'n funksie nie, in plaas daarvan word 'n funksie uitgeken deur rondehakies wat die argument lys omsluit.
* Deur gebruik te maak van die `typedef` sleutelwoord kan saamgestelde datatipes opgestel word ; daar is ook ander gedefineerde samegestelde tipes
** Verwante data element kan met die `struct` sleutelwoord as 'n eenheid behandel word 
** Skikkings kan gebruik word om verskeie elemente van 'n enkele data tipe te verklaar. Dit werk as 'n effektiewe groep van data wat osekwensieel in geheue gestoor word. Die soek van 'n spesifieke element kan dan met wyseroperasies uitgevoer word. Daar is geen skikking sleutelwoord nie, eerder word blokhakkies na die veranderlike gebruik om die skikking te defineer (byvoorbeeld int maande[12] defineer 12 int's, wat almal gevind kan word deur gebruik te maak van die maande veranderlike naam.)
** *Enumerated* tipes is ook moontlik met die `enum` sleutelwoord. Dit stel sekere terme direk gelyk aan spesifieke waardes.
** Strings word nie as 'n afsonderlike datatipe behandel nie, maar eerder as 'n skikking van karakters met "\0" aan die einde.
* Laevlak toegang tot geheue is moontlik deur masjienadresse na wysers toe om te skakel.
* Prosedures (funksies wat nie waardes terugvoer nie), is 'n spesiale tipe funksie wat met die tipe `void` gegee word.
* Funksies moet afsonderlik van mekaar gedefinieer word.
* Verskeie tipe komplekse funksies, soos nodig vir intree, uittree, string-manipulasie en ingewikkelde wiskundige operasies word gewoonlik gedefinieer in spesiale biblioteke.

## Geskiedenis 
### Vroeë opvattings 
Die ontstaan van C hou verband met die ontwikkeling van die Unix-bedryfstelsel wat oorspronklik geïmplementeer is in saamsteltaal op 'n PDP-7 deur Ken Thompson en Dennis Ritchie. Hulle wou later die nuwe bedryfstelsel gebruik op 'n PDP-11. Hul eerste oorweging was om die sisteem te herskryf met die B programmeertaal, maar daardie taal kon nie die PDP-11 ten volle benut nie.

C se ontwikkelling het dus in 1972 begin op die PDP-11 Unix-sisteem en het eerste verskyn in Unix-2. Die taal is nie oorspronklik geskryf om gebruik oor 'n verskeidenheid platforme te vergemaklik nie, maar met samestellers soos Honeywell 600 kon verskeie ander sisteme ook C gebruik. Die naam C is slegs die volgende letter in die alfabet na die vorige programmeertaal, B.
Die Unix-bedryfstelsel is daarna herontwikkel in C. Teen 1973, met die gebruik van saamgestelde datatipes, was C kragtig genoeg sodat die meerderheid van die Unix-opstellings in C gedoen kon word.

### K&R C 
In 1978 is die eerste uitgawe van *The C Programming Language* gedruk. Die boek het gedien as die eerste basiese omskrywing van die programmeertaal. Programmeerders het na die boek verwys as "K&R" en die boek het vir jare as die informele spesifisering van die C-taal gedien. Die tweede uitgawe van die boek het die ANSI C-standaard gedek.

K&R het verskeie eienskappe van die C-taal beskryf:
* Die standaard invoer/afvoer biblioteek
* `long int` datatipe
* `unsigned int` datatipe
* Samestellings tussen toekenning en operatore in die vorm (operator=). Dit is gedoen om moontlike dubbelsinnigheid te verwyder met uitdrukkings soos  `i =- 10` waar dit geïnterpreteer kan word as `i =- 10` of as `i = -10`.
Baie jare nadat 1989 ANSI C bekend gestel is, het mense steeds K&R C gebruik om te verseker dat dit op die maksimum hoeveelheid platforms kan werk (om te verseker dat die kode steeds sal werk selfs op ouer samestellers).

K&R C se funksiedefinisies het geen inligting bevat oor die argument van die funksie nie, dus kon daar foute wees met 'n aantal parameters wat 'n samesteller nie sou uitwys nie.

Die volgende addisionele funksies is bygevoeg tot K&R C:
* `void` funksies (funksies wat geen afvoer het nie)
* funksies wat `struct` of `union` tipes as afvoer het (eerder as wysers na die datastrukture)
* waarde toekenning vir `struct`  datatipes 
* *enumerated* datatipes
Die gebrek aan 'n ooreenkoms by een standaardbiblioteek sowel as die C-taal se hoë gebruik het daartoe gely dat 'n sekere mate van standaardisering vir die taal nodig was.

### Ansi C en ISO C 
In 1983 het die Amerikaanse Nasionale Standaarde Instituut (ANSI) begin om 'n standaardspesifikasie vir C te skep. In 1990 het die Internasionale Organisasie vir Standaardisering (ISO) hul eie weergawe van C, ISO C, geskep.

### C99 
Die C-standaardtaal is herontwerp in die vroeë 1990's, met die nuwe weergawe bekendgestel as C99. Dit was sedert sy vrystelling reeds 3 keer aangepas deur *Technical Corrigenda.* 

C99 het verskeie nuwe eienskappe van die taal bekend gestel, insluitend inlynfunksies, nuwe datatipes (insluitende `long long int` en 'n `complex` tipe om komplekse getalle voor te stel), skikkings met verstelbare lengtes, veranderlike skikkingslede, ondersteuning vir nuwe makros en ondersteuning vir kommentaar wat begin met `//` (op voorwaarde dat dit op een lyn geskryf word). Baie van hierdie eienskappe was reeds ingesluit as deel van sekere C-vertalers.

### C11 
Teen 2007 is die C-taal weereens herontwerp, en die informele naam "C1X" daaraan gegee totdat dit amptelik vrygestel is op 8 Desember 2011.

## Sintaksis 
### Karakters 
Die basiese C-opstelling herken die volgende karakters:
* Hoofletters en kleinletters :`a`–`z` `A`–`Z`
* Desimale syfers: `0`–`9`
* Grafiese karakters ! " # % & ' ( ) * + , - . / : ;  ? [ \ ] ^ _ { | } ~
* *Whitespace* karakters

### Sleutelwoorde 
C het 32 standaard sleutelwoorde. Hulle verwys na spesifieke programmeerinstruksies wat vir geen ander doel as dit waarvoor hulle gedefineerd is, gebruik kan word nie. Hierdie woorde se gebruik is dus beperk tot 'n spesifieke doel en mag nie as veranderlikes, funksie of ander name gebruik word nie.

:`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`
:`volatile`
:`while`

Soos gesien kan word uit die "Hello World" voorbeeld hieronder, is die funksie `printf` nie 'n sleutelwoord nie, terwyl `return` wel is. Dit is omdat `printf` op 'n verskeidenheid maniere vir verskillende platforme gedefineer kan word. In die voorbeeld is `printf` in stdio.h gedefineer en sal dit 'n string op die relevante venster vertoon. `printf` kan byvoorbeeld op 'n verwerkerbord gedefineer word om data oor 'n konneksie te stuur. Die ander datapunt is dan verantwoordelik om iets met die data te doen. Hierdie verskil van return, wat altyd in enige C-program dieselfde sal doen (naamlik dit sal teruggaan na die roeperfunksie met die argument wat saam daarmee gegee is.)

C99 het vyf addisionele sleutelwoorde bygedra:  `_Bool` , `_Imaginary`, `restrict` , `_Complex` ,`inline` 

C11 het 11 addisionele sleutelwoorde bygedra: `_Alignas` , `_Atomic`, `_Noreturn`, `_Thread_local`,`_Alignof`,`_Generic`,`_Static_assert`

### Operatore 
Operatore is die simbole wat C gebruik om te bepaal wat gedoen moet word vir 'n gegewe stelling.
* Toekenning: `=`
* Gelykheid : `==` , en ongelykheid: `!=`
* grootte van objekte:`sizeof`
* wiskundig: `+`, `-`, `*`, `/`, `%`
* aangepaste toekenning: `+=`, `-=`, `*=`, `/=`, `%=`, `&=`, `|=`, `^=`, , `>>=`
* boolse logika: `!`, `&&`, `||`
* tipe verandering: `*(nuwe tipe bv int)*`
* per-bis logika:`~`, `&`, `|`, `^`
* per-bis skyf: , `>>`
* voorwaardelike evaluering: `? :`
* roep van funksies: `( )`
* inkrement en dekrement: `++`, `--`
* kies van lede: `.`, `->`
* verhouding van ordes: , , `>`, `>=`
* volgordes: `,`
* groepering van substellings: `( )`
* *referencing and dereferencing:* `&`, `*`, `[ ]`

## Datatipes 
Die datatipes in C is staties en swak (met ander woorde, dit is moontlik om een veranderlike met 'n sekere datatipe in 'n ander datatipe om te sit), wat dit soortgelyk maak aan ander tale soos Pascal. Daar is ingeboude tipes vir meeste heelgetalle met verskeie groottes, beide *signed en unsigned* en karakters. C99 het 'n boolse datatipe bygevoeg. Daar is ook afgeleide tipes soos skikkings, wysers en saamgestelde datatipes (`struct`).

C word gereeld gebruik in laevlak stelselprogrammering waar dit nodig mag wees om die tipesisteem te manipuleer. Byvoorbeeld, die programmeerder kan twee veranderlikes met verskillende datatipes met mekaar vergelyk deur die een veranderlike se tipe te verander, of van wysers gebruik maak om die veranderlikes op ander maniere te vergelyk.

### Wysers 
C laat die gebruik van wysers toe, wat die adres van 'n objek of funksie in die geheue stoor. Wysers kan dan gebruik word om die data by die adres waarna dit *wys* te gebruik. Daar is ook spesiale wiskundige operasies wat gedefinieerd is vir wysers. 'n Wyser se tipe word bepaald deur die datatipe waarna dit *wys*. (Byvoorbeeld 'n int wyser sal die adres van 'n int stoor). Die wyserwiskunde word outomaties aangepas vir die grootte van die datatipe waarna dit wys.  

Strings kan gemanipuleer word deur gebruik te maak van wysers na karakterskikkings. Dinamiese geheuetoekenning kan gedoen word met wysers. Verskeie saamgestelde datatipes, soos binêrebome word geïmplementeer deur gebruik te maak van wysers. Wysers na funksies kan nuttig wees om funksies as argumente aan hoërordefunksies te gee.  

'n *Null* wyser wys direk na 'n geen geldige adres. Om na daardie adres toe te gaan sal dus meestal 'n segmentfout tot gevolg hê. *Null* wysers word dus gebruik vir spesiale gevalle wat "nie bestaan nie", soos om die volgende objek in die laaste objek in 'n tou te beskryf.  

### Skikkings 
Skikkings in C is gewoonlik van 'n vaste grootte en tipe soos gedefinieer teen vertaaltyd.

## Geheuebestuur 
'n Kritiese funksionaliteit van 'n programeringstaal is om die bestuur van geheue en stoor van objekte te beheer.  C bied drie maniere om geheue toe te ken vir objekte.
* Statiese geheue toekenning: geheue for die objek word toegeken teen vertaaltyd. 
* Outomatiese geheue toekenning: tydelike objekte kan op die *stack* gestoor word en die hulle geheue word outomaties vrygestel en geherbruik na die die funksieblok waarin hulle verklaar is klaar uitgevoer is.
* Dinamiese geheue toekening:  segmente van geheue van arbitrêre geheue kan toegeken word tyden die uitvoer van die program deur gebruik te maak van funksies soos `malloc` wat geheue kry vanaf die *heap.* Hierdie geheue bly egter in gebruik totdat hulle weer gereed gestel word vir gebruik met `realloc`  of  `free`.
Die drie metodes om geheue te bestuur het verskillende voordele en nadele. 

## Biblioteke 
Die C programmeertaal gebruik biblioteke as sy hoofmetode van uitbreiding. In C is 'n biblioteek n stel funksies wat behou word in 'n enkel argief lêer.

Die mees algemeenste C bibliokteek is die C standaard biblioteek wat gespesifiseer word deur die ISO en ANSI C standarde. Hierdie biblioteek kom met elke C implementering , terwyl sekere implementerings vir beperkte rekenaarstelsels partykeer net 'n onderafdeling van die biblioteek bevat. Die biblioteek ondersteuen intree en afvoer , geheue toekenning , wiskunde, karaktering *strings*  en tydwaardes.

Biblioteke vir ander programmeertale word gereeld in C gesrkyf aangsein die C saamestellers effektiewe objekkode genereer. Die programmeerders sal dan koppelstelsels in die biblioteek skep sodat die roetines in hoërvlaktale soos Java , Perl of Python  gebruik kan word.

## Verwante programmeertale 
C het direk of indirek baie tale beïnvloed soos byvoorbeeld C# , D , Go , Java , JavaScript , Limbo , LPC , Perl , PHP , Python en Unix's C shell. Die grootste invloed van C was die sintaksis.

## "Hello, world!" Voorbeeld 
Die volgende C kode is 'n eenvoudige program wat bloot die string "Hello, world!" druk op die skerm:

```

```

#include 
Hierdie lyn veroorsaak die voorverwerker ('n program wat die kode verwerk voordat dit vertaal word) om die inhoud van die `stdio.h` lêer in die plek van hierdie lyn in te voeg. `stdio.h` vorm deel van die standaard C biblioteek, en bevat definisies vir verskeie funksies om I/O te behandel, soos `printf`.

```
int main() {
```

Die volgende lyn verklaar die `main` funksie. In C-programme dien die `main` funksie as beginpunt vir die program deurdat dit die eerste funksie is wat geroep word deur die bedryfstelsel wanneer die program uitgevoer word. Die `int` spesifiseer dat die funksie 'n heelgetalwaarde as afvoer lewer. Die hakies aan die einde van `main` spesifiseer dat die funksie geen argumente neem nie; dit kan ook as `(void)` geskryf word. Die krulhakies dui die bestek van die funksie aan.

```
printf("Hello, world!\n");
```

Hierdie lyn roep die `printf` funksie met een argument (die string `"Hello, world!\n"`) om die boodskap te vertoon op die skerm. Die funksie se implementering word bevat in 'n sogenaamde biblioteek wat bekend staan as die standaard C biblioteek, wat 'n groot hoeveelheid nuttige funksies bevat.

```
return 0;

}
```

Omdat `main` verklaar is met 'n `int` afvoer, moet die funksie spesifiseer watter waarde teruggestuur gaan word na die funksie/omgewing wat dit geroep het. In hierdie geval word 'n 0 terug gestuur. In UNIX-stelsels is die konvensie dat 'n afvoer van 0 van die program (in hierdie geval, vanaf die `main` funksie) beteken dat die program suksesvol uitgevoer is, terwyl enige ander waarde 'n fout aandui.

## Verwysings