Care este starea lui C? Din punct de vedere istoric, această limbă este inseparabilă de sistemul de operare Unix, care se confruntă acum cu cea de-a doua naștere. Anii 60 au reprezentat epoca dezvoltării sistemelor de operare și a limbajelor de programare la nivel înalt. În acel moment, sistemele de operare și compilatoarele au fost dezvoltate independent pentru fiecare tip de calculatoare și adesea chiar și limbile de programare (să ne reamintim, de exemplu, PL / I). În același timp, simplitatea problemelor apărute în acest caz a devenit deja evidentă. Răspunsul la realizarea acestei comunități a fost încercarea de a crea un sistem de operare mobil universal și acest lucru necesită un limbaj de programare la fel de universal și mobil. Această limbă era C, iar Unix a fost primul sistem de operare, aproape complet scris într-un limbaj de nivel înalt.
O conexiune strânsă cu Unix a dat lui C un poligon de rupere, care nu era la acel moment în altă limbă. Sarcini de programare a sistemelor au fost considerate pe bună dreptate la acel moment ca fiind cele mai complexe din industrie. În cea mai mare parte, au fost atât de dependent de mașină încât mulți nu au gândit la soluția lor în mod diferit decât în asamblare. Limbile de nivel înalt au fost destinate programării aplicațiilor și au implementat foarte limitat funcțiile necesare pentru funcționarea sistemului, adesea numai pentru un anumit tip de mașină.
Limba C a fost creată de la început, astfel încât să poată scrie sarcini de sistem pe ea. Creatorii lui C nu au început să dezvolte un model abstract al executorului limbii, ci pur și simplu au realizat în el acele posibilități în care au avut nevoie cel mai mult în practicarea programării sistemului. În primul rând, acestea erau instrumente de lucru direct cu memoria, structuri de control structural și o organizare modulară a programului. Și de fapt nimic altceva nu a fost inclus în limbă. Toate celelalte au fost atribuite bibliotecii runtime. Prin urmare, cei care nu știu să vorbească uneori despre C ca un asamblor structural. Dar indiferent de ce spun ei, abordarea sa dovedit a fi foarte reușită. Mulțumită lui, a fost atins un nou nivel în raportul dintre simplitatea și capacitățile lingvistice.
Există totuși un factor care a determinat succesul limbii. Creatorii foarte des divizați în el proprietățile dependente de mașină și independente. Datorită acestui fapt, majoritatea programelor pot scrie universal - performanța lor nu depinde de arhitectura procesorului și a memoriei. Câteva dintre aceleași componente dependente de hardware ale codului pot fi localizate în module separate. Și folosind un preprocesor, puteți crea astfel de module, care, atunci când sunt compilate pe diferite platforme, vor genera codul corespunzător mașinii dependente.
O mulțime de dispute au fost cauzate de sintaxa limbajului C. Metodele utilizate pentru a scurta înregistrarea atunci când o folosesc incomensurabil pot face programul complet necitit. Dar, așa cum a spus Dijkstra, mijloacele nu sunt de vină pentru faptul că ele sunt folosite analfabeți. De fapt, abrevierile de sintaxă propuse în C corespund celor mai frecvent întâlnite situații stereotipe în practică. Dacă presupunem că abrevierile sunt idiomuri pentru o reprezentare expresivă și compactă a unor astfel de situații, atunci beneficiile lor devin necondiționate și evidente.
Deci, C a apărut ca un limbaj universal al programării sistemului. Dar el nu a rămas în acest cadru. Până la sfârșitul anilor '80 ai limbajului C, Fortran împingând-o poziție de lider, a câștigat popularitate în masă în rândul programatorilor din întreaga lume și a fost folosit în cele mai diverse aplicații. Un rol important aici a fost jucat de răspândirea Unixului (și, prin urmare, C) în mediul universitar, unde a fost instruită o nouă generație de programatori.
Ca toate limbile, C sa îmbunătățit treptat, dar majoritatea îmbunătățirilor nu au fost radicale. Cel mai important dintre ele, probabil, ar trebui să fie luate în considerare introducerea unei stricte tipuri de specificație de funcții care îmbunătățesc în mod semnificativ fiabilitatea interacțiunilor inter-modulare în C. Toate aceste îmbunătățiri au fost în 1989, stabilit în standardul ANSI care determină în continuare limbajul C.
Primele încercări de corectare a acestor neajunsuri au început să se facă la începutul anilor 80. Chiar și atunci, Bjarne Straustrup de la ATT Bell Labs a început să dezvolte extinderea limbajului C sub un nume condițional. Stilul de desfășurare a dezvoltării era în concordanță cu spiritul în care a fost creat limbajul C - a introdus anumite posibilități pentru a face munca mai convenabilă a anumitor persoane și grupuri. Primul traducător comercial al unei noi limbi, numit C ++, a apărut în 1983. A fost un preprocesor care a tradus programul în cod în C. Cu toate acestea, nașterea reală a limbajului poate fi considerată publicarea în 1985 a cărții Straustrupa
Din acest punct C ++ începe să câștige popularitate la nivel mondial.
Principala inovație a C ++ este mecanismul de clasă, care permite definirea și utilizarea noilor tipuri de date. Programatorul descrie reprezentarea internă a obiectului de clasă și un set de metode funcționale pentru accesarea acestei vizualizări. Unul dintre obiectivele costisitoare în crearea C ++ a fost dorința de a crește procentul de reutilizare a codului deja scris. Conceptul de clase a oferit un mecanism de moștenire pentru acest lucru. Moștenirea vă permite să creați clase noi (derivate) cu reprezentare extinsă și metode modificate, fără a afecta codul compilat al clasei sursă (de bază). În același timp, moștenirea oferă unul dintre mecanismele de implementare a polimorfismului, conceptul de bază al programării orientate pe obiecte, conform căruia același cod poate fi utilizat pentru a efectua același tip de procesare a diferitelor tipuri de date. De fapt, polimorfismul este, de asemenea, una dintre metodele de reutilizare a codului.
Introducerea cursurilor nu epuizează toate inovațiile în C ++. Acesta pune în aplicare un mecanism cu drepturi depline pentru Excepție de manipulare structurate, absența în care C este îngreunată în mod semnificativ scris fiabil motor șablon de software - un sofisticat macrogenerations mecanism, adânc înrădăcinată în limba, deschizând un alt mod de cod reutilizabil, și multe altele.
Toate acestea au dus la faptul că mulți dezvoltatori trebuiau să examineze ei înșiși labirintele semanticii limbilor și să găsească în mod independent idiomuri de succes. De exemplu, în prima etapă a dezvoltării limbajului, mulți creatori de biblioteci de clasă au căutat să construiască o singură ierarhie de clase cu un obiect de clasă comună de bază. Această idee a fost împrumutată de la Smalltalk - una dintre cele mai cunoscute limbi orientate spre obiect. Cu toate acestea, a fost complet neviabil în C ++ - ierarhiile gândite cu grijă din bibliotecile claselor s-au dovedit a fi inflexibile, iar lucrarea de cursuri nu a fost evidentă. Pentru a folosi bibliotecile de clasă, acestea trebuiau furnizate în codul sursă.
Apariția claselor templante a denaturat complet această tendință de dezvoltare. Moștenirea a început să fie utilizată numai în acele cazuri în care a fost necesară generarea unei versiuni specializate a unei clase existente. Bibliotecile au fost formate din clase separate și ierarhii mici, fără legătură. Totuși, pe această cale, reutilizarea codului a început să scadă, deoarece în C ++ este imposibil să se folosească polimorfic clase din ierarhii independente. Utilizarea omniprezentă a șabloanelor duce la o creștere inacceptabilă a cantității de cod compilat - să nu uităm că șabloanele sunt implementate utilizând metode de generare a macrocomenzilor.
Unul dintre cele mai grele dezavantaje ale C ++, moștenit de la sintaxa lui C, este disponibilitatea compilatorului pentru a descrie structura internă a tuturor claselor folosite. Ca o consecință, schimbarea structurii interne a reprezentării unor clase de bibliotecă duce la necesitatea de a recompila toate programele în care se folosește această bibliotecă. Acest lucru restrânge foarte mult dezvoltatorii bibliotecilor în ceea ce privește modernizarea lor, la urma urmei, atunci când eliberează o nouă versiune, ei trebuie să păstreze compatibilitatea binară cu cea precedentă. Aceasta este problema care face ca mulți specialiști să considere că C ++ nu este potrivit pentru desfășurarea unor proiecte mari și super-mari.
Și totuși, în ciuda neajunsurilor enumerate și chiar a neplăcului limbajului standard (după cincisprezece ani de utilizare!), C ++ rămâne unul dintre cele mai populare limbi de programare. Puterea sa este în primul rând în compatibilitatea aproape complet cu limbajul C. Această C ++ programatori acces la toate realizările făcute pe C. C ++, chiar și fără utilizarea de clase aduce la seria C este caracteristici suplimentare atât de importante și facilități pe care mulți l utilizați pur și simplu ca un Superior .
În ceea ce privește modelul de obiect C ++, în timp ce programul dvs. nu a devenit foarte mare (sute de mii de linii), este destul de posibil să îl utilizați. Tendința recentă către tranziția la software-ul componentă consolidează poziția C ++. În dezvoltarea componentelor individuale, deficiențele C ++ nu sunt încă evidente, iar conectarea componentelor la sistemul de operare nu se mai face la nivelul limbii, ci la nivelul sistemului de operare.
În lumina tuturor celor de mai sus, perspectivele pentru C ++ nu par a fi sumbre. Deși monopolul de pe piața limbilor de programare nu strălucește. Poate că putem spune cu certitudine că această limbă nu va supraviețui unei alte modernizări-expansiune. Nu fără nici un motiv, când a apărut Java, sa acordat atât de multă atenție. O limbă care este apropiată de sintaxa față de C ++ și, prin urmare, aparent familiară multor programatori, a scăpat de cele mai mari neajunsuri ale C ++ moștenite din anii '70. Cu toate acestea, nu pare că Java se confruntă cu rolul atribuit acestuia.
Pentru a demonstra utilizarea limbilor descrise în practică, am fost ales sarcina, care a fost necesară pentru a intra intrarea standard sau dintr-un număr de dosar de numere întregi, și apoi imprimați doar un ciudat, și în ordine secvențială inversă. Aceasta este una dintre cele mai simple sarcini, care necesită în mod esențial pentru soluția sa de lucru cu matrice, bucle, ramificare, și I / O, și vă permite să demonstreze apelurile subrutină. În același timp, este previzibilă și ușor de perceput.