thumb|right|The C Programming Language - Limbajul de programare C, de Brian Kernighan și Dennis Ritchie, ediția originală ce a servit pentru mulți ani ca manual de referință al limbajului C.

C () este un limbaj de programare standardizat. Este implementat pe majoritatea platformelor de calcul existente azi, și este cel mai popular limbaj de programare pentru scrierea de software de sistem. Este apreciat pentru eficiența codului obiect generat de compilatoarele C, și pentru portabilitatea sa.

A fost dezvoltat la începutul anilor 1970 de Ken Thompson și Dennis Ritchie, care aveau nevoie de un limbaj simplu și portabil pentru scrierea nucleului sistemului de operare UNIX.

Sintaxa limbajului C a stat la baza multor limbaje create ulterior și încă populare azi: C++, Java, JavaScript, C#, D.Overview - D Programming Language

C este un limbaj de programare relativ minimalist ce operează în strânsă legătură cu hardware-ul, fiind cel mai apropiat de limbajul de asamblare față de majoritatea celorlalte limbaje de programare.

Scurtă introducere în C C este prezentat uneori ca „asamblor portabil”, făcându-se astfel diferențele principale față de limbajele de asamblare: codul unui program C poate fi compilat și rulat pe aproape orice tip de mașină (calculator), asemănător altor limbaje de programare, în timp ce limbajele de asamblare sunt specifice unui anumit model de mașină. Limbajul C aparține clasei limbajelor de nivel scăzut sau de nivel mediu, aceasta indicând strânsa legătură între interoperabilitate și echipamentul hardware.

C a fost creat având drept scop important de a face ca programele mari să poată fi scrise mai ușor și cu mai puține erori în paradigma programării procedurale, dar fără a pune obstacole în scrierea compilatorului de C, care este încărcat de caracteristicile complexe ale limbajului. C are urmatoarele caracteristici importante: Este un limbaj de bază simplu, cu importante funcționalități cum ar fi funcțiile matematice sau cele de manipulare ale fișierelor Este focalizat pe paradigma programării procedurale, care facilitează programarea într-un mod structurat Utilizează un set simplu de tipuri de date ce împiedică multe operații neintenționate Folosește un limbaj preprocesor, preprocesorul C, pentru sarcini cum ar fi definirea de macrouri și includerea mai multor fișiere sursă Permite accesarea la nivel scăzut a memoriei calculatorului prin utilizarea pointerilor Permite folosirea parametrilor, care sunt comunicați funcțiilor prin valoare și nu prin referință Pointeri la funcții, ce permit forme rudimentare de închidere (engleză closure) și polimorfism Declararea variabilelor Structuri de date sau tipuri de date agregate, definite de utilizator prin (struct), ce permit ca date înrudite să fie combinate și manipulate ca un întreg

Printre caracteristicile ce lipsesc în C, dar care pot fi găsite în alte limbaje de programare se enumeră: Un sistem automat de colectare a reziduurilor (de memorie) (engleză Garbage collection) Clasele și obiectele (programarea orientată pe obiecte) Un sistem avansat de tipuri de date Programarea generică Supraîncărcarea Procesarea listelor

Deși lista minusurilor limbajului C este destul de lungă, aceasta nu reprezintă un dezavantaj suficient de mare pentru inhiba utilizarea limbajului C în practică, deoarece permite ca noi compilatoare să poată fi scrise pe noi tipuri de platforme și pentru că permite programatorului să țină bine sub control programul pe care îl scrie. Acesta este unul din motivele care face ca un cod scris în C să fie mult mai eficient decât dacă ar fi scris în alte limbaje de programare. Numai un cod scris cu foarte mare grijă într-un limbaj de asamblare poate fi mai performant, deoarece are control integral asupra mașinii, dar performanța avansată a compilatoarelor, combinată cu complexitatea noilor tipuri de procesoare, a făcut ca limbajul C să fie preferat și să fie acceptat din ce în ce mai mult de programatori.

Una din consecințele acceptării și eficienței C-ului este aceea că multe compilatoare, biblioteci și interpretoare ale limbajelor de nivel înalt sunt adesea implementate în C.

Un exemplu de program C („Hello World!”) O variantă a următorului exemplu de program a apărut în prima ediție a cărții lui Brian Kernighan și Dennis Ritchie și a devenit un exemplu standard de program introductiv în majoritatea cărților de programare, indiferent de limbajul de programare. Programul afișează „Hello, World!“ la ieșirea standard, care este, de obicei, un terminal sau monitor. Poate să fie, totuși, și un fișier sau alt dispozitiv hardware, depinzând de maparea ieșirii standard în momentul execuției programului. #include <stdio.h>

int main(void) { printf("Hello, World!\n");

return 0; }

Urmează o discuție linie cu linie a programului prezentat mai sus:

#include <stdio.h>

Prima linie a programului reprezintă o directivă preprocesor, #include. Aceasta face ca preprocesorul să substituiască linia respectivă cu conținutul unui fișier sau al entității la care se face referire. În acest caz, antetul standard stdio.h — care conține definițiile funcțiilor de manipulare a intrării și ieșirii standard — va înlocui acea linie.

int main(void)

Următoarea linie definește funcția numită main. Funcția main are un loc bine stabilit în programele C. Când un program C este executat, aceasta este prima funcție executată (punctul de intrare în program). Prezența acesteia este obligatorie pentru ca un program să poată fi executat. Porțiunea de cod int indică faptul că valoare întoarsă — valoare pe care funcția main o va întoarce procesului apelant — este un întreg. (void) indică faptul că funcția main nu primește nici un argument la apelare.

{ Paranteza acoladă deschisă indică începutul codului pentru funcția main.

printf("Hello World\n"); Aceasta linie apelează — caută și execută codul — funcția printf, care a fost definită în fișierul header stdio.h. În cadrul acestui apel, funcției printf îi este pasat (transmis) un singur argument, șirul de caractere "Hello, World!\n". Secvența \n este denumită secvență escape (cu semnificație specială), care se traduce prin caracterul EOL (end-of-line, sfârșitul liniei), pentru a muta cursorul pe linia următoare. Valoarea de întoarcere a funcției printf este un întreg int, dar nu este folosită în acest caz (este "ignorată").

return 0; Această instrucțiune termină execuția codului funcției main și face ca aceasta să întoarcă valoarea 0 procesului apelant, în cazul acesta sistemului de operare. } Paranteza acoladă închisă indică terminarea codului funcției main.

Tipuri de date C are un sistem de tipuri de date similar cu cel al descendenților ALGOL, cum ar fi Pascal, dar totuși cu anumite diferențe. Cuprinde tipuri de date cum ar fi întregi de diferite dimensiuni, cu sau fără semn, numere în virgulă mobilă, enumerări (enum), structuri de date (struct) și uniuni (union).

C utilizează foarte mult pointerii, un tip de referință foarte simplu, care păstrează adresa unui obiect din memorie. Adresa poate fi manipulată cu ajutorul aritmeticii pointerilor. În momentul compilării, un pointer este un tip de dată complex, ce reprezintă atât adresa de memorie cât și tipul de dată. Acest lucru permite expresiilor ce utilizează pointeri să fie evaluate după tipul de dată. Pointerii au mai multe utilizări în C. De exemplu, șirurile de caractere (engleză text string) sunt adesea reprezentate printr-un pointer la un vector de caractere. Alocarea dinamică a memoriei este realizată tot cu ajutorul pointerilor.

Un pointer null are o valoare rezervată, indicând faptul că face referire la o locație nevalidă. Acest lucru este folositor în cazuri speciale cum ar fi pointerul next (următorul) în nodul final al unei liste înlănțuite. Dereferențierea unui pointer null poate cauza un comportament imprevizibil al aplicației. De asemenea, există și pointeri de tip void, fapt ce indică referirea la un obiect de tip necunoscut. Acești pointeri sunt foarte folositori în programarea generică. Deoarece dimensiunea și tipul obiectelor la care acest tip de pointeri face referire sunt necunoscute, aceștia nu pot fi dereferențiați, dar pot fi convertiți la alt tip de pointeri.

În C, anterior standardului C99, tablourile (vectorii) sunt de dimensiune fixă, statică, cunoscută la momentul compilării; în practică, acest lucru nu reprezintă o piedică, având în vedere că se pot aloca blocuri de memorie în momentul rulării, tratându-le ca pe tablouri utilizând librăria standard. Spre deosebire de multe alte limbaje de programare, C evalueaza numele tablourilor ca și pointeri: o adresă și un tip de dată. Prin urmare, valorile index pot depăși dimensiunea actuală a unui tablou.

De asemenea, C oferă posibilitatea de lucru cu tablouri multidimensionale. Din punct de vedere semantic, tablourile multidimensionale sunt tablouri de tablouri.

Alocarea memoriei Una din cele mai importante funcții ale unui limbaj de programare este ca acesta să furnizeze metode de management a memoriei și al obiectelor stocate în memorie. C furnizează trei metode distincte de alocare a memoriei pentru obiecte:

Alocarea statică a memoriei: adresele și dimensiunile obiectelor ce fac uz de alocarea statică a memoriei sunt fixate în momentul compilării și pot fi plasate într-o zonă de dimensiune fixă ce corespunde unei secțiuni din cadrul fișierului linkedidat final. Acest tip de alocare a memoriei se numește statică deoarece locația și dimensiunea lor nu variază pe durata de execuție a programului. Alocarea automată a memoriei: obiectele temporare (variabilele locale declarate în cadrul unui bloc de cod) sunt stocate în cadrul de stivă asociat funcției apelate, iar spațiul alocat este automat eiberat și reutilizat după ce s-a părăsit blocul în care acestea au fost declarate. Alocarea dinamică a memoriei: blocuri de memorie de orice dimensiune pot fi alocate într-o zonă de memorie numită heap prin intermediul funcțiilor malloc(), calloc() și realloc(). Aceste blocuri de memorie pot fi reutilizate după ce zona de memorie a fost eliberată prin apelul funcției free().

Nu toate variabilele sunt automat alocate. Următoarele tipuri de variabilă sunt alocate static: toate variabilele globale, indiferent dacă au fost sau nu declarate ca statice; variabilele locale declarate explicit ca fiind statice. Variabilele alocate static au alocată locația lor de memorie și inițializată înainte ca funcția main să fie executată și nu sunt dealocate până când se termină execuția funcției main. Variabilele alocate static nu sunt reinițializate la fiecare apel al funcției în cadrul cărora au fost declarate. O variabilă alocată static are avantajul că își păstrează valoarea, chiar dacă funcțiile care accesează acea valoare nu mai sunt active.

Acolo unde este posibil, alocarea automată sau statică este preferată deoarece alocarea memoriei este coordonată de compilator, nemaifiind nevoie ca programatorul să aloce iar apoi să elibereze memoria - operație ce adesea generează erori. Totuși, multe structuri de date sunt variabile în dimensini și deoarece alocarea automată și cea statică trebuie să fie de dimensiune fixă în momentul compilării, sunt multe situații în care alocarea dinamică trebuie folosită. Un exemplu ar fi tablourile de dimensiuni variabile.

Sintaxa Vezi și Sintaxa limbajului C

Spre deosebire de alte limbaje de programare cum ar fi Fortran 77, C-ul are o formă liberă, lăsând programatorul să-și organizeze codul folosind spațiile albe. Comentarii pot fi înserate oriunde în cadrul programului utilizând delimitatorii /* și */.