Limbajul de programare C este un limbaj de programare a calculatoarelor, conceput de Dennis Ritchie la începutul anilor 1970 pentru a scrie sistemul de operare UNIX. A rămas unul dintre cele mai folosite limbaje pentru scrierea programelor.

Există multe extinderi ale limbajului, printre care C++, Perl, Java, Javascript și C#.

"Hello, World!" în C modificare

Următorul program afișează mesajul "Hello, world!".

Versiunea C


#include<stdio.h>
int main(void)
{
printf("Hello,World!\n");
return 0;
}

Versiunea C++


#include<iostream.h>
int main(void)
{
cout<<"Hello,World!\n"; //sau cout<<"Hello,World!"<<endl;
return 0;
}

Structura unui program modificare

Un program C este alcătuit din funcții și variabile. Funcțiile C sunt echivalente cu subrutinele din Fortran și procedurile din Pascal. Funcția main este specială prin faptul că execuția programului debutează întotdeauna la începutul acestei funcții. Orice program trebuie să includă o funcție main.

Definiția unei funcții include următoarele componente: un tip de retur (int, în exemplul de mai sus), un nume, o listă de parametri (între paranteze rotunde) și un corp al funcției (cuprins între acolade).
float CalculeazaSuprafata(float Lungime, float Latime) {
float Suprafata;
Suprafata = Lungime*Latime;
return Suprafata;
}

Cuvinte cheie modificare

Există 32 de cuvinte rezervate în limbajul C, care au semnificație predefinită și nu pot fi folosite în alte scopuri într-un program. Cuvintele cheie trebuie scrise cu litere mici. Iată lista acestora, ordonată alfabetic:

  • 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

altă ierarhizare:

  • pentru controlul fluxului: if, else, switch, do, while, for.

Identificatori modificare

Identificatorii sunt folosiți pentru a indica variabile, tipuri de date, constante simbolice sau funcții. Primul caracter al identificatorilor trebuie să fie o literă sau underline, iar lungimea maximă a acestora este de 32 de caractere.

Separatori modificare

Separatorii au rolul de a delimita unitățile lexicale dintr-un program. Iată lista separatorilor admiși în limbajul C:

  • ( ) Parantezele rotunde încadrează lista de parametrii a unei funcții, sau precizează ordinea de efectuare a operațiilor pentru evaluarea unei expresii.
  • { } Acoladele încadrează instrucțiunile compuse, care se mai numesc și blocuri.
  • [ ] Parantezele drepte încadrează dimensiunile tablourilor
  • " " Ghilimelele încadrează șirurile de caractere
  • ' ' Apostrofii încadrează un singur caracter
  • ; Fiecare instrucțiune se încheie cu caracterul ;
  • /* */ Comentariile sunt încadrate de caracterele /* și */

Structura funcțiilor modificare

Funcțiile C sunt alcătuite dintr-un antet și un corp. Antetul specifică tipul rezultatului, numele funcției și lista de parametri. Corpul este alcătuit dintr-un bloc ce poate să conțină declarații și instrucțiuni care specifică prelucrările realizate de funcția respectivă.
Antetul unei funcții este de forma următoare:

tip_r nume_f(listă_p_f)

Corpul unei funcții este de forma următoare:

{
     declarații
     instrucțiuni
}

Instrucțiuni modificare

Prelucrările efectuate de un program sunt descrise cu ajutorul instrucțiunilor. Fiecare instrucțiune trebuie încheiată cu separatorul punct și virgulă (;). Instrucțiunile limbajului C pot fi împărțite în următoarele categorii: Expresii, Blocuri, Selecții, Iterații, Salturi.

Expresii modificare

O instrucțiune expresie este alcătuită dintr-o expresie urmată de punct și virgulă. Operațiile realizate de aceste instrucțiuni se fac simțite datorită efectelor ce se concretizează prin apeluri de funcții și modificarea valorilor unor variabile.
Exemplu de instrucțiuni expresie:

test();                  /* apelul unor funcții */
scanf("%d", &a);
a=b+c/2;        /* variabila a primește valoarea b+c/2 */
x++;            /* variabila x este incrementată */
a+f();   /* instrucțiunea este corectă, dar ciudată */
;               /* instrucțiune vidă */

Un caz particular de instrucțiune expresie este instrucțiunea vidă. Aceasta este alcătuită doar din terminatorul de instrucțiune ; și se folosește de obicei în situațiile în care sintaxa cere prezența unei instrucțiuni, însă în program nu mai este necesară o operație.
Instrucțiunea următoare așteaptă tastarea caracterului '€' și ignoră orice alt caracter:

while (getch()!='€')
      ;

Blocuri modificare

Blocurile se mai numesc și instrucțiuni compuse și sunt alcătuite din mai multe declarații și instrucțiuni cuprinse între acolade. Structura generală a unui bloc este următoarea:

{
   declarații
   instrucțiuni
}

Declarațiile din cadrul unui bloc se fac la început, înaintea instrucțiunilor!

Selecții modificare

Limbajul C acceptă două tipuri de instrucțiuni de selecție: if - care se mai numește și instrucțiune decizională - și switch. În plus, operatorul ?: poate constitui, în anumite situații, o alternativă la instrucțiunea decizională.

Instrucțiunea decizională modificare

Acestă instrucțiune are următoarele două variante:
a)

if(expresie)
     instr_a

b)

if(expresie)
     instr_a
else
     instr_b

Execuția instrucțiunii decizionale începe cu evaluarea expresiei. Valoarea expresiei poate fi de orice tip scalar. Dacă valoarea expresiei este diferită de 0, atunci se execută instrucțiunea instr_a, altfel se execută instr_b. Limbajul C nu operează cu tipul boolean, valorile de adevăr fiind codificate numeric, după următoarea regulă: o valoare nulă este echivalentă cu fals iar o valoare ne-nulă cu adevărat.
Exemplu:

if(a>0)
     printf("pozitiv");
else
     printf("negativ");

Instrucțiunea de mai sus afișează textul "pozitiv" dacă a > 0 și "negativ" în caz contrar.
În cazul în care alternativele de prelucrare se codifică prin secvențe de instrucțiuni, acestea trebuie grupate în instrucțiuni compuse. De exemplu secvența

if(a>0)
     printf("pozitiv");
     np++;   /* incrementează variabila np */

este diferită de

if(a>0){
     printf("pozitiv");
     np++;
}

deoarece în primul caz incrementarea variabilei np se realizează în afara instrucțiunii decizionale, și deci se efectuează în orice situație. În al doilea caz, instrucțiunea decizională are asociată o instrucțiune compusă (bloc), iar incrementarea se realizează numai dacă condiția este adevărată (a>0).
Deoarece alternativa else a unei instrucțiuni decizionale este opțională, poate să apară o ambiguitate legată de asocierea ei în cazul unor instrucțiuni decizionale imbricate.
Exemplu:

if( op =='/')
     if(a!=0)
          c=b/a;
     else
          printf("eroare, împărțire prin 0");

În aceste situații, regula este următoarea: Alternativa else se asociază ultimei decizii incomplete. Dacă se dorește o altă asociere se pot folosi acoladele:

if( a!=0){
       if(op=='/')
              c=b/a;
}else
      printf("valoare nulă");

sau se poate completa alternativa else a instrucțiunii decizionale interioare cu o instrucțiune vidă:

if( a!=0)
       if(op=='/')
              c=b/a;
       else
              ;
else
       printf("valoare nulă");

Instrucțiunea decizională multiplă modificare

O selecție multiplă se poate realiza cu mai multe instrucțiuni decizionale în cascadă. În cazul general în care există n alternative posibile selectate pe baza a n-1 condiții, se recomandă folosirea următoarei structuri:

if(expr_1)
   ins_1
else if(expr_2)
   ins_2
...
else if(expr_n-1)
   ins_n-1
else
   ins_n

Expresiile se evaluează în ordinea în care sunt scrise. Dacă se întâlnește o expresie adevărată, atunci se execută instrucțiunea care-i este asociată și astfel se încheie întregul lanț. Instrucțiunea de după ultimul else se execută doar când nici una dintre expresii nu a fost adevărată.

Instrucțiunea de selecție modificare

Dacă o selecție multiplă este controlată de valoarea unei singure expresii, programarea se poate face mai eficient cu ajutorul instrucțiunii de selecție (switch). Sintaxa generală a acestei instrucțiuni este:

switch(expresie){
     case k1    : prelucrare_1opt
     case k2    : prelucrare_2opt
     ...
     case kn-1  : prelucrare_n-1opt
     defaultopt : prelucrare_nopt
}

Expresia pe baza căreia se efectuează selecția trebuie să fie de tip întreg (nu poate să fie de exemplu float, double sau un tip structurat).
k1, k2, ..., kn-1 sunt expresii constante, cu valori distincte, ce pot fi convertite la tipul expresiei de selecție.
Prelucrările se reprezintă prin secvențe de instrucțiuni, dar ele pot fi și vide. În cazul în care o prelucrare este compusă din mai multe instrucțiuni, acestea nu trebuie puse între acolade.
Execuția instrucțiunii de selecție începe cu evaluarea expresiei. Valoarea rezultată este comparată succesiv cu constantele k1, k2, ..., kn-1. Dacă se găsește o constantă ki de valoare egală cu cea a expresiei, se trece la execuția prelucrării asociate și se continuă cu toate prelucrările ce au mai rămas, până la sfârșitul instrucțiunii de selecție. Dacă nu se găsește o astfel de constantă, dar este definită o alternativă default, se execută prelucrarea asociată acesteia, altfel selecția se încheie fără nici o prelucrare.
Exemplu de utilizare a instrucțiunii de selecție:

/* calculează b = a la puterea n, 1 < n < 4 */
b=a;
switch(n){
     case 4 : b=b*a;
     case 3 : b=b*a;
     case 2 : b=b*a;
}

În majoritatea situațiilor se dorește separarea prelucrărilor asociate unei instrucțiuni de selecție. Aceasta se poate realiza prin includerea instrucțiunii break la sfârșitul tuturor prelucrărilor. Instrucțiunea break are ca efect, în cazul în care apare în interiorul unei instrucțiuni de selecție, terminarea imediată a acesteia. Execuția programului va continua cu instrucțiunea următoare (ceea ce urmează după switch).
Exemplu:

switch(op){
      case '*' : inmulteste(a,b);
                 break;
      case '+' : aduna(a,b);
                 break;
      case '-' : scade(a,b);
                 break;
      default  : printf("eroare");
}

Iterații modificare

Execuția repetată a unei prelucrări este folosită foarte frecvent în rezolvarea problemelor de cele mai diverse tipuri. Instrucțiunile repetitive care descriu astfel de prelucrări sunt alcătuite din două componente: Corpul instrucțiunii (care este alcătuit din instrucțiuni care se repetă) și Testul (pe baza căruia se stabilește dacă este sau nu necesară reluarea execuției corpului).
În limbajul C există trei instrucțiuni repetitive, dintre care două cu test la început (while și for) și una cu test la sfârșit (do while). Instrucțiunile repetitive cu test la început plasează testul înaintea corpului, astfel corpul este parcurs numai dacă testul este trecut de la început. În cazul celor cu test la sfârșit, corpul este executat cel puțin o dată în orice condiții.
Instrucțiunile repetitive se mai numesc și cicluri sau bucle.

Instrucțiunea while modificare

Această instrucțiune are următoarea sintaxă:

while(expresie)
      instrucțiune

Expresia poate fi de orice tip scalar. Instrucțiunea specifică prelucrările ce se efectuează în corpul buclei și se repetă atâta timp cât expresia este adevărată, mai exact diferită de zero.

Instrucțiunea do - while modificare

Această instrucțiune are următoarea sintaxă

do
     instrucțiune
while(expresie);

Ea are rolul de a repeta instrucțiunea până când expresia este adevărată. Diferența față de instrucțiunea while constă în faptul că testul este plasat la sfârșitul buclei, deci instrucțiunea se execută cu siguranță cel puțin o dată, indiferent de valoarea expresiei.
Exemplul următor citește numere de la tastatură, până când numărul tastat este mai mic sau egal cu 10.

#include <stdio.h>
int main()
{
   char n;
        do{
              printf("\nTastați un număr < 10 ");
              scanf("%d", &n);
        }while(n>10);
}

Instrucțiunea for modificare

Această instrucțiune are o formă generală care-i extinde mult domeniul de aplicare față de instrucțiunile de același tip existente în alte limbaje de programare. Este cea mai utilizată instrucțiune repetitivă, deoarece în afară de testul de rămânere în buclă, oferă două elemente necesare în majoritatea situațiilor: inițializare și actualizare.
Sintaxa instrucțiunii for:

for(expresie_intopt;expresie_condopt;expresie_actopt)
       
       instrucțiune


- expresia_initializare constituie inițializarea buclei și se evaluează o singură dată.
- expresia_actualizare trebuie să fie de tip scalar și este evaluată înaintea fiecărei iterații. Valoarea acestei expresii este interpretată ca și condiție de rămânere în buclă.
- În interiorul buclei se realizează, la fiecare parcurgere, două operațiuni: se execută prelucrările specificate prin instrucțiune, după care se evaluează expresie_act.
Oricare dintre expresiile instrucțiunii for (sau chiar toate) pot să lipsească, dar delimitatorul ';' asociat trebuie să fie prezent.
Dacă lipsește expresie_cond, se consideră implicit că aceasta este tot timpul adevărată și deci bucla nu se va încheia niciodată. O astfel de buclă poate fi însă încheiată cu instrucțiunea break.
Prelucrările efectuate cu instrucțiunea for, pot fi descrise și cu ajutorul unei bucle while, care se aseamănă cu for prin faptul că este tot cu test la început. Secțiunea următoare este echivalentă cu instrucțiunea for a cărei sintaxă a fost prezentată mai sus:

expresie_init
while(expresie_cond){
      instrucțiune
      expresie_act
}

Exemplul următor prezintă o buclă care va rula la infinit:

#include <stdio.h>
int main()
{
for( ; ; )
       printf("Buclă infinită\n");
}

Salturi modificare

Există trei instrucțiuni de salt în limbajul C: break, continue și goto. Tot la această categorie putem vorbi și despre instrucțiunea return, care marchează încheierea prelucrărilor dintr-o funcție și revenirea în programul apelant.

Instrucțiunea break modificare

Această instrucțiune poate să apară numai în corpul instrucțiunilor while, do-while, for și switch; având ca efect terminarea imediată a acestor instrucțiuni. Programul continuă cu instrucțiunea imediat următoare celei întrerupte. În cazul unor bucle imbricate, o instrucțiune break aflată într-o buclă interioară nu le afectează pe cele exterioare. Aceași situație apare în cazul instrucțiunilor switch imbricate, sau care conțin bucle.