Programmeerimiskeel C on protseduraalse iseloomuga, s.o. enamus tööst tehakse funktsioonides ja loodud programm transleeritakse otse masinkoodi. Peale protseduraalsete programmeerimiskeelte on olemas ka funktsionaalsed (Lisp), loogilised (Prolog) ja objektorienteeritud (Smalltalk) programmeerimiskeeled. Olgu juba ette ära öeldud, et C++ ei ole puhas objektorienteeritud programmeerimiskeel, vaid hübriidkeel, s.o. midagi protseduraalsete ja objektorienteeritud keelte vahepealset.
Funktsioonid on programmi osad, mis täidavad mingit eriülesannet. Funktsioon omab nime, mille abil teda saab välja kutsuda. Programmeerimiskeele C funktsioonid vastavad näiteks keele BASIC alamprogrammidele (SUBROUTINE). Funktsiooni juurde kuuluv programmilõik on ümbritsetud looksulgudega. Kui teie programm peab sageli täitma sarnaseid ülesandeid, siis on kasulik see ülesanne kodeerida omaette funktsioonina. Nii loodud programm on lühem, kuna sama ülesande mitmekordsel täitmisel ei pea vastavat programmilõiku mitu korda programmi sisestama, vaid selle asemel kasutatakse funktsiooni. Peale selle on niimoodi programmi lihtsam koostada. Suurem probleem jaotatakse omaette ülesanneteks, mis igaüks moodustavad eraldi funktsiooni.
Funktsioonid võivad omada parameetreid, s.o. väärtusi, mis selle tööd mõjutavad ja mis antakse funktsioonile üle seda välja kutsuva funktsiooni poolt. Funktsioon võib omada ka väärtust - nn. funktsiooni oma väärtust. See väärtus on sageli funktsiooni poolt lahendatava ülesande tulemus ja ta antakse peale funktsiooni töö lõppu funktsiooni välja kutsunud funktsioonile tagasi. Funktsioon näeb seega välja järgmiselt:
int funktsioon1(int parameeter1, int parameeter2)
{
return parameeter1 + parameeter2;
}
Antud näitefunktsioon on tüübist int (täisarv).
Iga programm peab sisaldama funktsiooni, mille nimi on main(). Programmi töö alguses laadib operatsioonisüsteem selle programmi mällu ja kutsub välja programmis sisalduva funktsiooni main(). Funktsioon main() võib omakorda vajaliku töö täitmiseks kutsuda välja teisi funktsioone .
Translaatori komplektis on teeke enamkasutatavate funktsioonidega. Programmeerimiskeel C ei sisalda mingeid käske teksti väljastamiseks ekraanile, failide avamiseks jms. Kõigi nende ülesannete täitmiseks on olemas vastavad funktsioonid. Need funktsioonid on juba masinkoodi transleeritud ja teekidesse kogutud. Selleks, et teie programm neid kasutada saaks, tuleb vastavad teegid transleeritud programmile lisada. Seda tööd teeb linker.
Nagu juba öeldud, on kõik funktsioonid võrdväärsed. Kui nüüd translaator leiab programmitekstis mingi funktsiooni nime, siis otsib ta vastavast failist selle funktsiooni definitsiooni. Kui translaator seda failist ei leia, siis otsib ta kasutatud funktsiooni programmiga lingitavatest teekidest. Kui ka seal vastavat funktsiooni ei leidu, siis väljastatakse veateade. Translaator üritab ka kontrollida, kas funktsioonile anti üle õige arv õiget tüüpi parameetrid. Selleks aga peab translaator teadma, millist tüüpi parameetreid antud funktsioon vajab. Nimetatud andmed kogutakse sageli päisefailidesse.
Päisefailid .H sisaldavad ka muid vajalikke andmeid. Neid faile ei transleerita, vaid kasutatakse üksnes andmete üleandmiseks. Enamasti sisestatakse päisefailid programmi translaatori käsu #include abil. Joonisel 1. näete programmeerimiskeeles C koostatud programmi struktuuri.
Joonis 1: Programmeerimiskeele C programmi struktuur
Jooniselt on näha, et programmi alguses on translaatori käsk #include <stdio.h>. Selle käsuga teatatakse translaatorile, et ta peab faili enne transleerimist lisama päisefaili nimega STDIO.H. Nimetatud päisefail sisaldab paljude vajalike funktsioonide deklaratsioone, nende poolt kasutatavaid konstante jms. Translaatori teine levinud käsk on #define. Selle käsuga defineeritakse sümboolseid konstante ja makrosid.
Sellele järgneb rida funk1(char, char);. See on funktsiooni deklaratsioon. Selline rida teatab translaatorile, et kusagil selles failis on defineeritud sellenimeline funktsioon ja et sellel on kaks parameetrit tüübist char. Kuna rea lõpus on kohe semikoolon ja mingeid looksulge ei järgne, siis teab translaator, et see ei ole veel vastava funktsiooni definitioon. Leidnud nüüd selle funktsiooni nime funktsioonist main(), saab translaator ka kohe kontrollida, kas üleantud parameetrid olid õiget tüüpi.
Selle koha peal defineeritakse sageli ka mõned uued tüübid ja muutujad. Muutujad on nimelised mälupesad, millesse võite salvestada oma töö tulemused. Muutujad peavad alati omama mingit tüüpi ja translaator kontrollib, kas te omistate neile väärtusi sobivast tüübist. Kui te defineerite nimetatud kohal failis muutuja, siis on too muutuja globaalne, s.o. te saate tema väärtust lugeda ja ka muuta igast funktsioonist. Kui te aga deklareerite muutuja mingis funktsioonis, siis kehtib nn. "nähtavuse" printsiip. Seda muutujat saate nüüd kasutada ainult selles funktsioonis.
Programmeerimiskeeles C on kõik funktsioonid võrdväärsed. Erinevalt programmeerimiskeelest PASCAL ei saa te siin defineerida mingi funktsiooni sees omakorda uusi funktsioone, mis oleksid ka kättesaadavad ainult sellele funktsioonile. Kordloodud funktsioonid on C - keeles kasutatavad kõigi teiste funktsioonide poolt. Ainult funktsiooni main() ei tohi enam teiste funktsioonide poolt välja kutsuda.
Näites INTEGRAL.C on toodud lihtsa C programmi tekst.
1./********************************************************/
2./*** ***/
3./*** Integral.c ***/
4./*** ***/
5./*** See on lihtne programm,mis iseloomustab ***/
6./*** C - keele programmidepõhistruktuuri. Programm ***/
7./*** arvutab määratudintegraali kasutaja ***/
8./*** poolt sisestatud rajades. ***/
9./********************************************************/
10./*----------------<Päisefailid >----------------------*/
11.#include <stdio.h> /* seda päisefaili on vaja
12. mitmete teegis defineeritud
13. funktsioonide kasutamiseks */
14.#include <math.h> /* selles päisefailis on defineeritud
15. matemaatilised funktsioonid */
16.#include <ctype.h> /* toupper() */
17.#define MINPIIR 0.0
18.#define MAXPIIR M_PI / 2.0
19.#define EPS 0.0001
20./*----------------<Globaalsed muutujad >--------------*/
21.typedef double REAL; /* esialgu kasutame tüüpi double.
22. hiljem ehk ka long double, kui
23. soovime suuremat täpsust*/
24./*----------------<Funktsioonide prototüübid >--------*/
25.REAL IntFunc(REAL); /* integreeritava funktsiooni
prototüüp */
/* interpolatsiooni funktsioon */
26.REAL Ristkuelik(REAL, REAL, unsigned long);
27./*-----------------------------------------------------*/
28./*--- ---*/
29./*--- IntFunc() ---*/
30./*--- ---*/
31./*--- arvutab integreeritava funktsiooni väärtuse ---*/
32./*--- kohal x. ---*/
33./*-----------------------------------------------------*/
34.REAL IntFunc(REAL x)
35.{
36. return 5.0 * exp(2.0 * x) / (exp(M_PI) - 2.0) * cos(x);
37.} /* IntFunc() */
38./*-----------------------------------------------------*/
39./*--- ---*/
40./*--- Ristkuelik() ---*/
41./*--- ---*/
42./*--- arvutab funktsiooni IntFunc määratud inte- ---*/
43./*--- graali soovitud rajades ja nõutud täpsusega. ---*/
44./*--- Nagu funktsiooni nimest näha, ei ole C-keeles---*/
45./*--- funktsioonide ja muutujate nimedes lubatud ---*/
46./*--- kasutada täppidega tähti jms. ---*/
47./*-----------------------------------------------------*/
48.REAL Ristkuelik(REAL MinRaja, REAL MaxRaja, unsigned long n)
49.{
50. REAL h, sum;
51. int i;
52. sum = 0.0;
53. h = (MaxRaja - MinRaja) / n;
54. for(i = 0; i < n; i++) {
55. sum += IntFunc(MinRaja + i * h);
56. }
57. return sum * h;
58.} /* Ristkuelik */
59./*=====================================================*/
60./*=== ===*/
61./*=== main() ===*/
62./*=== ===*/
63./*=== See funktsioon on programmi peamine funkt- ===*/
64./*=== sioon. Igas programmis peab olema funktsioon ===*/
65./*=== main(). Programmi algul stardib operatsiooni- ===*/
66./*=== süsteem selle funktsiooni ja selle lõppedes ===*/
67./*=== on ka programm lõppenud. ===*/
68./*=====================================================*/
69.int main( void )
70.{
71. char Vastus = 'n';
72. unsigned long Num;
73. REAL MinRaja, MaxRaja, Tulemus, Epsilon, Temp;
74. /* teatame kõigepealt, mida see programm teeb */
75. puts("See programm arvutab funktsiooni: ");
76. puts("5 * e**2x / (e**Pi - 2) * cos(x)) ");
77. puts("määratud integraali teie poolt sisestatud rajades ja täpsusega.");
78. puts("Programmi lõpetamiseks vajutage klahvile 'j'");
79. /* initsialiseerime vajalikud muutujad */
80. MinRaja = MINRAJA;
81. Tulemus = Temp = 0.0;
82. MaxRaja = MAXRAJA;
83. Epsilon = EPS;
84. Num = 1;
85. /* alustame arvutamisega */
86. do {
87. /* Loeme sisse uued rajad ja täpsuse */
88. puts("Sisestage uued rajad ja täpsus");
89. printf("Alumine raja [%f]: ", MinRaja);
90. scanf("%f", &MinRaja);
91. printf("Ülemine rada [%f]: ", MaxRaja);
92. scanf("%f", &MaxRaja);
93. printf("Täpsus [%f]: ", Epsilon);
94. scanf("%f", &Epsilon);
95. /* interpoleerime seni, kuni soovitud täpsus on saavutatud */
96. do {
97. Tulemus = Temp;
98. Temp = Ristkuelik(MinRaja, MaxRaja, Num);
99. Num = Num * 2;
100. } while(Epsilon < fabs(Tulemus - Temp));
101. /* trükime tulemuse ja anname kasutajale võimaluse
102. arvutusi uute väärtustega korrata */
103. printf("\n\nIntegral = %f", Temp);
104. puts("\nSoovite te uuesti arvutada (J/E)?");
105. fflush(stdin);
106. scanf("%1c", &Vastus);
107. } while (toupper(Vastus) == 'J');
108. return 0;
109.}
Programmeerimiskeel C kasutab kommentaaride jaoks sümboleid /* ja */. Translaator ignoreerib kõike, mis on piiratud nende sümbolitega. Programmeerimiskeel C++ kasutab kommentaaride jaoks veel sümbolit //. See sümbol määrab kommentaari, mis ulatub rea lõpuni. Sellist kommentaari on lihtsam sisestada, kuna tuleb määrata vaid kommentaari algus, kuid ta on ka mitmeti piiratud. Sageli ostub kasulikuks ümbritseda mingi programmilõik kommentaarisümbolitega, et seda sel kombel mitte transleerida (välja kommenteerida). Nii saab programmi tööd jätkata ilma selle programmilõiguta ja nimetatud lõiku ei ole vaja kustutada. Sageli on vaja mingi osa ühest reast välja kommenteerida. Sel juhul tuleb kasutada sümboleid /* ja */. Näiteprogrammis INTEGRAL.C kasutatakse kommentaare mitmete programmi osade tähenduse selgitamiseks ja erinevate osade alguse ja lõpu märkimiseks. Kommentaarid muudavad programmi teksti paremini loetavaks. Read 1 kuni 9 on kommentaarid ja sisaldavad andmeid selle kohta, mida antud programm teeb ja demonstreerib.
Read 10 kuni 19 sisaldavad translaatori käske. Selles osas lisatakse käsu #include abil kolm päisefaili, mis sisaldavad programmis kasutatud standardsete funktsioonide definitsioone. Ilma nende päisefailidete ei oskaks translaator programmi õigesti luua ega teaks, milliseid teeke on vaja. Enne transleerimist kasutab translaator käskude täideviimiseks eeltranslaatorit (precompiler). Käsu #include puhul lisab eeltranslaator kogu vastava päisefaili sisu määratud kohta programmi tekstis. Selliselt muudetud programmi tekst salvestatakse ajutisse faili, mis antakse nüüd üle tegelikule translaatorile.
Peale selle defineeritakse siin kolm sümboolset konstanti. Käsu #define abil saab defineerida makrosid ja sümboolseid konstante. Sümboolne konstant vastab mingile konstantsele väärtusele. Eeltranslaator asendab programmi tekstis vastavate konstantide nimed nagu näiteks MINRAJA, tema väärtusega, mis siin on 0.0. Sümboolsed konstandid muudavad teie programmi teksti paremini loetavaks. Nii on näiteks konstandi nimi MAKSUPROTSENT palju väljendusrikkam kui arv 0.35. Peale selle saab niiviisi konstante defineerida ühes kohas, kus neid on lihtsam muuta. Kui nimetatud protsent muutub, on vaja ainult muuta vastavat definitsiooni. Vastasel juhul peaksite otsima üles kõik kohad oma programmi tekstis, kus te olete seda konstanti kasutanud ja ta seal asendama. Suurema programmi puhul on see tülikas ja võib kergesti vigu tekitada. Lihtsam on lasta asendused teha translaatoril.
Read 20 kuni 23 sisaldavad globaalseid muutujaid ja definitsioone. Toodud programm ei vaja mingeid globaalseid muutujaid. Mõned üksikud siiski defineeritakse funktsioonis main(), kuid need on tegelikult funktsiooni main() kohalikud muutujad. Globaalsete muutujate kasutamine on sageli vigade põhjustajaks, kuna nende väärtusi tohib muuta iga funktsioon ja seega võivad funktsioonid üksteise tööd mõjutada. Muutujate asemel defineeritakse siin uus andmetüüp - REAL.
Read 24 kuni 26 sisaldavad funktsioonide prototüüpe ehk deklaratsioone. Funktsiooni deklaratsioon võib asuda suvalisel kohal programmi tekstis, kuid ta peab asuma enne vastava funktsiooni definitsiooni ja enne iga funktsiooni, mis seda funktsiooni kasutab. Seega on soovitav lisada funktsioonide definitsioonid faili algusesse. Samal põhjusel tuleks ka päisefailid sisestada faili algusesse, kuna funktsioonide definitsioone on ka päisefailides.
Funktsiooni deklaratsioon näeb välja nagu funktsioon, kuid tal puudub kood ja ta lõpeb kohe peale parameetrite loetelu semikooloniga. Ka parameetrite nimede lisamine ei ole vajalik, ainult parameetri tüüp on tähtis. Selles programmis ei ole need deklaratsioonid küll vajalikud, kuna funktsioonide definitsioonid annavad translaatorile samasugused andmed. Funktsioonide definitsioonid on aga siin sisestatud just sellises järjekorras, et definitsioon paikneb enne funktsioone, mis seda funktsiooni kasutavad. Keerukamas programmis on selle üle raskem arvet pidada ja seepärast on soovitav luua iga funktsiooni jaoks deklaratsioon programmi algul või sobivas isiklikus päisefailis. Muid programmilõike käsitleme järgnevates peatükkides.
Kui olete programmi tekstifaili (INTEGRAL.C) sisestanud, võite programmi transleerimiseks kasutada suvalist C translaatorit. Joonisel 2 näete C - keele programmi transleerimist.

Joonis 2: Programmeerimiskeele C programmi transleerimine
Programmi transleerimiseks võib kasutada ainult C - keele translaatorit, näiteks:
BCC [<valikud>] INTEGRAL.C
Sel juhul kutsub translaator (BCC.EXE) kõigepealt välja eeltranslaatori (CPP.EXE), mis sisestab teksti vajalikud päisefailid ja asendab sümboolsete konstantide makrode nimed vastavate väärtustega. Tulemus salvestatakse ajutisse faili. Nüüd transleerib BCC.EXE faili assemblerkoodi, seejärel masinkoodi ja lingib teekidega. Tulemuseks on valmis programm - INTEGRAL.EXE.
Kui te soovite näiteks oma makrode kontrollimiseks näha eeltranslaatori töö tulemust, siis kasutage käsureal enne faili nime valikut -i. Sel puhul ei kustuta translaator loodud ajutist faili peale töö lõppu. Sageli kasutatakse ka valikut -c, mis sunnib translaatorit oma tööd peale objektfaili loomist lõpetama. Sel juhul tuleb ise objektfail teekidega linkida. Translaator kasutab valmis faili jaoks sama nime, mis oli *.C failil, lisades vaid uue nimelaiendi .EXE. Mitme faili transleerimisel valitakse programmi nimeks esimese faili nimi. See ei ole aga alati nii. Näiteks operatsioonisüsteemi UNIX C - translaatorid panevad loodud faili nimeks A.OUT. Kui te soovite anda valmis failile mingi teise nime, siis kasutage valikut -o <uus nimi>. Näiteks, nimetamaks valmis programmi INTR.EXE:
BCC -o INTR INTGRAL.C
Tähtis valik on ka -v, mis lisab objektfailile kodeeritud kujul andmeid muutujate jms. kohta ja võimaldab seega loodud programmist hiljem siluriga vigu otsida. Osa translaatoreid kasutab objektfaili andmete sisestamiseks siluri jaoks valiku -v asemel valikut -g .
Kui teie programm koosneb mitmest eraldi *.C ja *.H failist, siis on sageli sobiv kasutada valikut -c. Kui te nüüd muudate ainult üht faili, siis tuleb üksnes see fail uuesti transleerida ja teiste objektfailide ja teekidega uuesti linkida.
Programm INTEGRAL.EXE arvutab funktsiooni:

määratud integraali rajades 0 kuni p/2. Määratud integraal on teatavasti võrdne funktsioonialuse pindalaga nimetatud rajades. Selle pindala arvutamiseks kasutatakse siin lihtsat ristkülikumeetodit, mispuhul kogu pindala jaotatakse elementaarseteks ristkülikuteks ja nende pindalad summeeritakse.

Joonis 3: Määratud integraali arvutamine ristkülikureegli järgi
Programmi tulemuseks peaks olema:
D:\SAMPLES\CSAMPLES\INTEGRAL>integral See programm arvutab funktsiooni: 5 * e**2x / (e**Pi - 2) * cos(x)) määratud integraali teie poolt sisestatud rajades ja täpsusega. Programmi lõpetamiseks vajutage klahvile 'j' Sisestage uued rajad ja täpsus Alumine raja [0.000000]: 0.0 Ülemine raja [1.570796]: 1.570796 Täpsus [0.000100]: 0.000001 Integraal = 1.000090 Soovite te uuesti arvutada (J/E)? e D:\SAMPLES\CSAMPLES\INTEGRAL>