1.1. Introducere
Limbajul C este un limbaj de programare universal, caracterizat printr-o exprimare
concisa, un control modern al fluxului executiei, structuri de date, si un bogat
set de operatori. i1e18ep
Limbajul C nu este un limbaj de „nivel foarte inalt” si nu
este specializat pentru un anumit domeniu de aplicatii. Absenta restrictiilor
si generalitatea sa il fac un limbaj mai convenabil si mai eficient decit
multe alte limbaje mai puternice.
Limbajul C permite scrierea de programe bine structurate, datorita constructiilor
sale de control al fluxului: grupari de instructiuni, luari de decizii (if),
cicluri cu testul de terminare inaintea ciclului (while, for) sau dupa
ciclu (do) si selectia unui caz dintr-o multime de cazuri (switch).
Limbajul C permite lucrul cu pointeri si are o aritmetica de adrese puternica.
Limbajul C nu are operatii care prelucreaza direct obiectele compuse cum sint
sirurile de caractere, multimile, listele sau masivele, considerate fiecare
ca o entitate. Limbajul C nu prezinta facilitati de alocare a memoriei altele
decit definitia statica sau disciplina de stiva relativa la variabilele
locale ale functiilor. In sfirsit, limbajul C nu are facilitati
de intrare-iesire si nici metode directe de acces la fisiere. Toate aceste mecanisme
de nivel inalt sint realizate prin functii explicite.
Desi limbajul C este, asadar, un limbaj de nivel relativ scazut, el este un
limbaj agreabil, expresiv si elastic, care se preteaza la o gama larga de programe.
C este un limbaj restrins si se invata relativ usor, iar subtilitatile
se retin pe masura ce experienta in programare creste.
1.2. Primele programe
In aceasta sectiune sint prezentate si explicate patru programe
cu scopul de a asigura un suport de baza pentru prezentarile din capitolele
urmatoare.
Prin traditie primul program C este un mic exemplu din lucrarea devenita clasica
-; „The C programming language”, de Brian W Kernigham si Dennis
M Ritchie.
#include <stdio.h> main() A printf("Hello, world\n"); return 0;
S
Acest program afiseaza un mesaj de salut.
Prima linie indica faptul ca se folosesc functii de intrare / iesire, si descrierea
modului de utilizare (numele, tipul argumentelor, tipul valorii returnate etc)
a acestora se afla in fisierul cu numele stdio.h .
A doua linie declara functia main care va contine instructiunile programului.
In acest caz singura instructiune este un apel al functiei printf care
afiseaza un mesaj la terminal. Mesajul este dat intre ghilimele si se
termina cu un caracter special new-line ('\n').
Instructiunea return preda controlul sistemului de operare la terminarea programului
si comunica acestuia codul 0 pentru terminare. Prin conventie aceasta valoare
semnifica terminarea normala a programului - adica nu au aparut erori in
prelucrarea datelor.
Corpul functiei main apare intre acolade.
Al doilea program asteapta de la terminal introducerea unor numere intregi
nenule si determina suma lor. In momentul in care se introduce o
valoare zero, programul afiseaza suma calculata.
#include <stdio.h> main() A int s,n; s = 0; do A scanf("%d",&n); s += n;
S while (n!=0); printf("%d\n",s); return 0;
S
In cadrul functiei main se declara doua variabile s si n care vor memora
valori intregi. Variabila s (care va pastra suma numerelor introduse)
este initializata cu valoarea 0.
In continuare se repeta o secventa de doua instructiuni, prima fiind o
operatie de intrare si a doua o adunare.
Primul argument al functiei scanf - formatul de introducere "%d" -
indica faptul ca se asteapta introducerea unei valori intregi in
format zecimal de la terminal (consola). Al doilea argument indica unde se va
depune in memorie valoarea citita; de aceea este necesar sa se precizeze
adresa variabilei n (cu ajutorul operatorului &).
In a doua instructiune la valoarea variabilei s se aduna valoarea variabilei
n. Operatorul += are semnificatia aduna la.
Aceasta secventa se repeta (do) cit timp (while) valoarea introdusa (n)
este nenula. Operatorul != are semnificatia diferit de.
In final functia printf afiseaza pe terminal valoarea variabilei s in
format zecimal.
Al treilea program asteapta de la terminal introducerea unei valori naturale
n, dupa care mai asteapta introducerea a n valori reale (dubla precizie): a0,
a1, ..., an?1. In continuare se parcurge aceasta lista si se determina
produsul valorilor strict pozitive. In final programul afiseaza produsul
calculat.
#include <stdio.h> main() A int n,i; double aa100i, p; scanf("%d",&n); for (i=0; i<n; i++) scanf("%lf",&aaii); p = 1; for (i=0; i<n; i++) if (aaii>0) p *= aaii; printf("%lf\n",p); return 0;
S
In cadrul functiei main se declara doua variabile n si i care vor memora
valori intregi. Variabila n pastreaza numarul de valori reale din lista
a. Se declara de asemenea un tablou unidimensional a care va memora 100 de valori
de tip real (dubla precizie), si o variabila p care va memora produsul cerut.
Se citeste de la terminal o valoare n. In continuare se introduc valorile
reale ai (i ? 0, 1, ..., n?1). Formatul de introducere "%lf" indica
faptul ca se asteapta introducerea unei valori reale de la terminal, care va
fi depusa la locatia de memorie asociata variabilei ai. In locul constructiei
&aaii se poate folosi forma echivalenta a+i.
Pentru a introduce toate valorile ai se efectueaza un ciclu for, in cadrul
caruia variabila i (care controleaza ciclul) ia toate valorile intre 0
(inclusiv) si n (exclusiv) cu pasul 1. Trecerea la urmatoarea valoare a variabilei
i se face cu ajutorul operatorului ++.
In continuare variabila p, care va memora produsul valorilor cerute, se
initializeaza cu 1. Fiecare valoare ai este verificata (instructiunea if) daca
este strict pozitiva si in caz afirmativ este inmultita cu valoarea
p. Operatorul *= are semnificatia inmulteste cu.
Al patrulea program este o ilustrare a unor probleme legate de capacitatea
reprezentarilor valorilor de tip intreg si virgula mobila.
#include <stdio.h> int main() A short k,i; float a,b,c,u,v,w; i=240; k=i*i; printf("%hd\n",k); a=12345679; b=12345678; c=a*a-b*b; u=a*a; v=b*b; w=u-v; printf("%f %f\n",c,w); if (c==w) return 0; else return 1;
S
Variabila k, care ar trebui sa memoreze valoarea 57600, are tipul intreg
scurt (short), pentru care domeniul de valori este restrins la -;32768
? 32767. Astfel ca valoarea 1110000100000000(2) (in zecimal 57600), in
reprezentare intreaga cu semn este de fapt -;7936.
Al doilea set de operatii necesita o analiza mai atenta; explicatiile sint
valabile pentru programe care ruleaza pe arhitecturi Intel. Variabila c, care
ar trebui sa memoreze valoarea 2461357 (rezultatul corect), va avea valoarea
2461356, deoarece tipul float are rezervate pentru mantisa doar 24 de cifre
binare. Rezultatul este foarte apropiat de cel corect deoarece rezultatele intermediare
se pastreaza in registrii coprocesorului matematic cu precizie maxima.
Abia la memorare se efectueaza trunchierea, de unde rezulta valoarea afisata.
Cu totul altfel stau lucrurile in cazul celui de al treilea set de operatii.
Aici rezultatele intermediare sint memorate de fiecare data cu trunchiere
in variabile de tip float. In final se calculeaza si diferenta dintre
cele doua valori trunchiate, de unde rezulta valoarea 16777216.
Inainte de terminare se verifica daca valorile c si w sint egale.
In caz afirmativ se comunica sistemului de operare un cod 0 (terminare
normala). In caz contrar se comunica un cod 1 (terminare anormala).
Rulati acest program pe diferite sisteme de calcul si observati care este rezultatul.
1.3. Meta-limbajul si setul de caractere
Meta-limbajul care serveste la descrierea formala a sintaxei limbajului C
este simplu.
Categoriile sintactice sau notiunile care trebuie definite sint urmate
de simbolul ':'.
Definitiile alternative de categorii sint listate pe linii separate. Daca
o linie nu este suficienta, se trece la linia urmatoare, aliniata la un tab
fata de linia precedenta.
Un simbol optional, terminal sau neterminal este indicat prin adaugarea imediata
dupa el a configuratiei de caractere „?opt?”.
Setul de caractere al limbajului C este un subset al setului de caractere
ASCII, format din:
-; 26 litere mici a b c d e f g h i j k l m n o p q r s t u v w x y z
-; 26 litere mari
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
-; 10 cifre
0 1 2 3 4 5 6 7 8 9
-; 30 simboluri speciale
Blanc ! " # % & ' ( ) * ? , ? . / : ; ? ? ? ? a \ i ^ _ I A | S
-; 6 simboluri negrafice
\n, \t, \b, \r, \f, \a