C

The C Programming Language,[1] manualul de referință pentru C
C
Extensii fișiere.c, .h
ParadigmăImperativ (procedural), structurat
Apărut în1972; acum 52 ani (1972)[2]
Proiectat deDennis Ritchie
DezvoltatorDennis Ritchie & Bell Labs (creatori); ANSI X3J11 (ANSI C); ISO/IEC JTC1/SC22/WG14 (ISO C)
TipareStatic, slab, manifest, nominal
Implementări majoreGCC, Clang, Intel C, MSVC, Pelles C, Watcom C
DialecteCyclone, Unified Parallel C, Split-C, Cilk, C*
Influențat deB (BCPL, CPL), ALGOL 68,[3] Assembly, PL/I, FORTRAN
InfluențeNumeroase: AMPL, AWK, csh, C++, C--, C#, Objective-C, BitC, D, Go, Rust, Java, JavaScript, Limbo, LPC, Perl, PHP, Pike, Processing, Python, Seed7, Verilog (HDL)[4]
Sistem de operareMultiplatformă
Tip MIMEtext/plain[5]  Modificați la Wikidata
Prezență onlinesite web oficial
Wikibooks logo C Programming la Wikibooks
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 (/ˈs/) 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.[6]

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

[modificare | modificare sursă]

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:

Printre caracteristicile ce lipsesc în C, dar care pot fi găsite în alte limbaje de programare se enumeră:

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!”)

[modificare | modificare sursă]

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

[modificare | modificare sursă]

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

[modificare | modificare sursă]

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:

Nu toate variabilele sunt automat alocate. Următoarele tipuri de variabilă sunt alocate static:

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

[modificare | modificare sursă]
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 */.

Fiecare fișier sursă conține declarații de variabile și definiții de funcții. Funcțiile, la rândul lor, conțin alte declarații de variabile și comenzi. Declarațiile de variabile fie definesc noi tipuri folosind cuvinte cheie precum struct, union și enum sau atribuind un tip de date predefinite, prin scrierea tipului de dată și urmat de numele variabilei. Cuvinte cheie precum char, int, precum și pointerul la unul din aceste tipuri * reprezintă tipuri de date implementate nativ în C. Secțiuni de cod sunt incluse între paranteze acolade ({ și }), pentru a indica pentru ce porțiune a codului se aplică declarațiile de variabile și celelalte structuri de control.

Comenzile execută acțiuni cum ar fi cele de modificare ale valorii unei variabile sau afișarea unui text la consolă. Structurile de control sunt variabile pentru execuții condiționale sau iterații, realizate cu ajutorul cuvintelor rezervate if, else, switch, do, while și for. Salturi arbitrare sunt posibile prin folosirea cuvântului cheie goto. Cu ajutorul unei varietăți de operatori implementați în C, se pot realiza operații aritmetice, logice, comparative, pe biți, indexarea tablourilor și atribuiri. Comenzile pot de asemenea apela funcții, incluzând un număr mare de funcții din bibliotecile standard ale limbajului C, necesare pentru realizarea diferitelor sarcini cerute de programator.

Istoric

[modificare | modificare sursă]

Începuturile limbajului de programare C

[modificare | modificare sursă]

Etapa inițială de dezvoltare a limbajului de programare C a avut loc în cadrul laboratoarelor AT&T Bell între anii 1969 și 1973. După spusele lui Dennis Ritchie, cea mai creativă perioadă a avut loc în 1972. A fost denumit „C“ deoarece multe din caracteristicile sale au fost derivate din limbajul de programare „B“.

Sunt multe legende despre originea limbajului C și legătura sa cu sistemul de operare Unix, cum ar fi:

Începând cu anul 1973, limbajul de programare C a devenit destul de robust, astfel încât mare parte a kernelului Unix, scris inițial în limbaj de asamblare pentru PDP 11/20, a fost rescris în C. Acesta a fost unul din primele kernele ale unui sistem de operare scris într-un limbaj de programare, altul decât limbajul de asamblare. Încercări anterioare au fost pentru scrierea sistemului Multics (scris în PL/I) și TRIPOS (scris în BCPL).

K&R C

[modificare | modificare sursă]

În 1978, Dennis Ritchie și Brian Kernighan au publicat prima ediție a cărții Limbajul de programare C (eng. The C Programming Language). Această carte, cunoscută în cercul programatorilor sub numele K&R, a servit pentru mulți ani ca un mijloc de informare asupra specificațiilor limbajului C. Versiunea limbajului C descrisă este cunoscută sub numele K&R C.

K&R aduce în discuție următoarele caracteristici ale limbajului:

K&R C este adesea considerat limbajul de bază pe care orice compilator C trebuie să-l suporte. Pentru mulți ani, chiar și după introducerea standardului ANSI C, a fost considerat ca fiind „cel mai mic numitor comun“ pe care programatorii în C trebuie să-l respecte atunci când se vorbește de portabiliitate maximă, deoarece nu toate compilatoarele sunt scrise încă să suporte standardul ANSI C, iar o secvență de cod scrisă în K&R C respectă și ANSI C.

În primele versiuni C, numai funcțiile care returnau o valoare non-integer trebuiau să fie definite sau declarate înainte de folosire. Despre o funcție folosită fără ca aceasta să fi fost declarată în prealabil se presupunea că întoarce un întreg. Parametrii funcțiilor nu erau verificați după tip, totuși unele compilatoare afișau un mesaj de atenționare dacă o funcție era apelată cu un număr greșit de argumente.

În anii ce au urmat publicației K&R C, câteva caracteristici „neoficiale“ au fost adăugate limbajului C, fiind suportate de compilatoarele celor de la AT&T, precum și de alți producători. Acestea includ:

ANSI C și ISO C

[modificare | modificare sursă]

La sfârșitul anilor 1970, C a început să înlocuiască limbajul BASIC devenind cel mai utilizat limbaj de programare. În anii 1980 a fost adoptat și de calculatoarele IBM PC, popularitatea acestuia începând să crească semnificativ. În acest timp, Bjarne Stroustrup împreună cu alți colegi de la Bell Labs au început să adauge limbajului C caracteristici ale programării orientate pe obiecte. Limbajul rezultat a fost denumit C++ și este cel mai popular limbaj de programare pe sistemele de operare Microsoft Windows; totuși C-ul rămâne cel mai popular limbaj de programare în Unix. Alt limbaj de programare dezvoltat în acea vreme se numește Objective-C care adaugă de asemenea C-ului caracteristici ale programării orientate pe obiecte. Deși nu la fel de popular ca C++, Obejective-C este folosit pentru dezvoltarea aplicațiilor pe ce folosesc interfața Cocoa a sistemului de operare Mac OS X.

În 1983, American National Standards Institute (ANSI) a format un comitet, X3J11, pentru a stabili specificațiile unui limbaj C standard. După un proces îndelungat, standardul a fost terminat în 1989 și ratificat ca ANSI X3.159-1989 "Programming Language C". Această versiune a limbajului ne este cunoscută sub numele ANSI C. în 1990, standardul ANSI C (cu mici modificări) a fost adoptat de International Organization for Standardization (ISO) ca ISO/IEC 9899:1990.

Una din țintele procesului de standardizare ANSI C a fost acela de a produce un superset al K&R C, încorporând multe dintre caracteristicile neoficiale introduse secvențial. Totuși, comitetul pentru standardizare a introdus câteva caracteristici noi, cum ar fi prototipul funcțiilor (împrumutat din C++) și un preprocesor mult mai capabil.

ANSI C este suportat de marea majoritate a compilatoarelor folosite astăzi. Mare parte din codul C scris acum este bazat pe ANSI C. Orice program scris exclusiv în standardul C este garantat să funcționeze corect pe orice platformă cu o implementare C conformă. Totuși, multe programe sunt scrise astfel încât aceste vor putea fi compilate numai pe anumite platforme, sau folosind un anumit compilator, deoarece (i) se folosesc biblioteci non-standard, de exemplu pentru interfața grafică, (ii) unele compilatoare ce nu respectă standardul ANSI C, deci și urmașii lor în mod implicit sau (iii) bazarea pe dimensiunea unui anumit tip de date pe anumite platforme.

C99

[modificare | modificare sursă]

După procesul de standardizare ANSI, specificațiile limbajului de programare C au rămas nemodificate pentru o perioadă, în timp ce C++ a continuat să evolueze. (Amendamentul Normativ I a creat o nouă versiune a limbajului C în 1995, dar această versiune este prea puțin cunoscută.) Totuși, la sfârșitul anilor 1990, standardul a suferit o revizie, conducând la publicarea standardului ISO 9899:1999 în anul 1999. Acest standard este cunoscut sub numele „C99“. A fost adoptat ca standard ANSI în martie 2000.

Noile aspecte ale limbajului C includ:

În ceea ce privește interesul în adoptarea noului standard C99, dacă GCC și alte compilatoare suportă noile caracteristici C99, compilatoarele celor de la Microsoft și Borland nu suportă C99 și cele două companii nu par interesate în a oferi nici un fel de suport.

Diferențe între C, C++ și Pascal

[modificare | modificare sursă]

Comparație cu limbajul Pascal

[modificare | modificare sursă]
Sintaxa Pascal Sintaxa C și C++ Explicații
 
begin
{
Început bloc de instrucțiuni
end. / end
}
Sfârșit bloc de instrucțiuni
if (<cond>) then
if(<cond>)
Instrucțiune condițională: <cond> adevarată determină execuția codului după if (<cond>)
while(<cond>) do
while(<cond>)
Repetă cat timp <cond> adevărat
a<> b
a!=b
Valoarea variabilei a e diferită de valoarea variabilei b
for i:=1 to n do
for(i=1;i<=n;i++)
Buclă (ciclu) for: se va repeta până la verificarea condiției de ieșire din ciclu (valoarea variabilei i egale cu cea a lui n)
i:=a;
i=a;
Atribuire: în locația de memorie corespunzătoare variabilei i se copiază valoarea din locația lui a
i:=i+1 sau inc(i);
i++;
Incrementare
i:=i-1
i--;
Decrementare
var i: integer
int i;
Declarare variabilă (în C++ și C99 se poate declara oriunde în program/funcție)
if(a=b) then 
if(a==b)
Dacă a egal cu b
read(var); 
scanf("%s", &var);
Citire de la intrarea standard (de obicei tastatură)
write('text ', var);
printf("text %s", var);
Scriere la ieșirea standard (de obicei ecran)
writeln; 
printf("\n");
Tipărește o linie nouă

C și C++

[modificare | modificare sursă]

Limbajul de programare C++ a fost inițial derivat din C. Totuși, nu absolut orice program scris în C este valid C++. Deoarece C și C++ au evoluat independent, au apărut, din nefericire, o serie de incompatibilități între cele două limbaje de programare [1]. Cea mai amplă revizie a limbajui C, C99, a creat un număr suplimentar de conflicte. Diferențele fac să fie greu de scris programe și biblioteci care să fie compilate și să ruleze corect în calitate de cod C sau C++, și produce confuzii celor care programează în ambele limbaje. Diferențele fac ca fiecare din cele două limbaje de programare să împrumute din caracteristicile celuilalt limbaj de programare.

Bjarne Stroustrup, creatorul limbajului C++, a sugerat de nenumărate ori [2] să se reducă incompatibilitățile pe cât de mult posibil pentru a maximiza interoperabilitatea dintre cele două limbaje de programare. Unii au argumentat că C și C++ sunt două limbaje de programare distincte, compatibilitatea dintre ele fiind utilă dar nu vitală; potrivit acestei opinii, eforturile de a reduce incompatibilitatea nu trebuie să reducă eforturile de a aduce elemente noi în mod independent celor două limbaje de programare.

Cele mai importante diferențe sunt:

C99 a adoptat unele funcționalități ce au apărut inițial în C++. Printre acestea se enumeră:

Exemplu

[modificare | modificare sursă]

Un program care citește un număr întreg și îl afișează.

Pascal:

program test;
var i:integer;
begin
    writeln('introduceti un nr:');
    read(i);       //citire număr introdus de la tastatură
    writeln(i);    //afișare număr citit
end.

C:

#include <stdio.h>  /* contine declaratiile functiilor de intrare/iesire */
int main()          /* program principal */
{
    int i;
    printf("Introduceti un nr:");
    scanf("%d",&i);   /* citire numar introdus la tastatura */
    printf("%d", i);  /* afișare număr citit */
    return 0;
}

C++:

#include <iostream>  //conține declarațiile funcțiilor de intrare/ieșire
int main()           //program principal
{
    int i;
    std::cout<<"Introduceti un nr:";
    std::cin>>i;  //citire
    std::cout<<i; //afișare
    return 0;
}

Vezi și

[modificare | modificare sursă]

Note

[modificare | modificare sursă]
  1. ^ Kernighan, Brian W.; Ritchie, Dennis M. (februarie 1978). The C Programming Language (ed. 1st). Englewood Cliffs, NJ: Prentice Hall. ISBN 0-13-110163-3.  Regarded by many to be the authoritative reference on C.
  2. ^ Ritchie (1993): "Thompson had made a brief attempt to produce a system coded in an early version of C—before structures—in 1972, but gave up the effort."
  3. ^ Ritchie (1993): "The scheme of type composition adopted by C owes considerable debt to Algol 68, although it did not, perhaps, emerge in a form that Algol's adherents would approve of."
  4. ^ „Verilog HDL (and C)” (PDF). The Research School of Computer Science at the Australian National University. . Accesat în . 1980s: ; Verilog first introduced ; Verilog inspired by the C programming language 
  5. ^ https://www.sitepoint.com/mime-types-complete-list/  Lipsește sau este vid: |title= (ajutor)
  6. ^ en Overview - D Programming Language

Bibliografie

[modificare | modificare sursă]

Legături externe

[modificare | modificare sursă]