După citirea caracterului curent de la intrarea standard se atribuie variabilei c codul ASCII al caracterului citit sau EOF la întâlnirea sfârşitului de fişier.
Exemple:
{ putchar(getchar() – ‘A’ + ‘a’); // citeste o litera mare si o rescrie ca litera mica }
void main (void)
{ intc c;
putchar(((c = getchar() )>= ‘A’ && c<= ‘Z’) ? c-‘A’+’a’ :c);
}
4.5. Funcţiile standard getche şi getch
Funcţia getche citeşte de la intrarea standard caracterul curent şi returnează codul ASCII al caracterului citit. Această funcţie are acces direct la caracter după ce a fost tastat şi are forma:
getche();
Funcţia getch este similară cu getche cu singura condiţie că citirea se face fără ecou (deci caracterul tastat nu se reafişează pe terminal). De fapt prezenţa/absenţa sufixului e precizează că funcţia e sau nu cu ecou. Cele două funcţii fac citiri fără intermedierea zonei tampon.
5. Instrucţiuni
5.1. Scurt istoric al metodelor de programare
Vom prezenta în continuare câteva metode de programare dar nu exhaustiv, nefiind aici cadrul adecvat (eventual într-un curs de Software Engineering). O clasificare cronologică a ceea ce vrem să prezentăm ar fi următoarea:
-
programarea artizanală;
-
programarea procedurală;
-
programarea modulară;
-
programarea structurată;
-
programarea prin abstractizarea datelor;
-
programarea orientată spre obiecte.
5.1.1. Programare artizanală
Această metodă de fapt nu este o metodă propriu-zisă ci este prima modalitate de programare odată cu apariţia calculatoarelor. Intuiţia şi experienţa programatorului joacă un rol important. Fiecare programator îşi are propriile reguli de programare. Programele sunt monolitice (un singur corp de instrucţiuni), lungi şi greu de înţeles de alt programator. Însuşi cel ce a elaborat un astfel de program întâmpină dificultăţi de înţelegere a propriului program după un timp oarecare.
5.1.2. Programare procedurală
Odată cu apariţia primelor limbaje de înalt nivel se utilizează programarea procedurală. Necesitatea ca anumite secvenţe de program să fie folosite de mai multe ori duce la organizarea acestora în unităţi distincte de program numite în diverse limbaje subprograme, subrutine, proceduri, etc. De multe ori procedurile trebuie să fie generale deci procesarea să facă abstractizare de valorile datelor. De exemplu o procedură de calcul al radicalului de ordinul 2 trebuie să calculeze acest lucru din orice număr real pozitiv iar pentru cele negative să semnaleze eroare. Procedurile trebuie deci parametrizate cu anumite variabile numite parametri formali. Valorile de la apel ale parametrilor formali se numesc parametri efectivi. Programarea procedurală are la bază deci utilizarea procedurilor, iar acestea realizează o abstractizare prin parametri. La apelare o procedură funcţionează după principiul cutiei negre (black box): se cunosc intrările şi ieşirile rezultate din acestea dar nu şi modul de transformare care nu e important în acest moment.
În majoritatea limbajelor procedurale de programare se consideră 2 categorii de proceduri:
-
proceduri care definesc o valoare de revenire (denumite şi funcţii);
-
proceduri care nu definesc o valoare de revenire.
În limbajele C şi C++ procedurile de ambele categorii se numesc funcţii.
5.1.3. Programare modulară
Pe măsură ce complexitatea aplicaţiilor a crescut, a apărut ideea de a descompune problemele în subprobleme mai simple care la rândul lor pot fi descompuse în altele mai simple şi aşa mai departe. În felul acesta se ajunge la o descompunere arborescentă a problemei date în subprobleme mai simple. Programarea subproblemelor devine o problemă mai simplă şi fiecare subproblemă are o anumită independenţă faţă de celelalte subprobleme. De asemenea, interfaţa ei cu celelalte subprobleme este limitată şi bine precizată prin procesul de descompunere a problemei iniţiale. De obicei, programarea unei subprobleme, componentă a descompunerii arborescente a problemei iniţiale, conduce la realizarea unui număr relativ mic de proceduri (funcţii). Aceste funcţii pot prelucra în comun anumite date. Unele dintre ele sunt independente de funcţiile realizate pentru alte subprobleme componente ale descompunerii arborescente. Altele realizează chiar interfaţa cu subproblemele învecinate.
Despre funcţiile obţinute în urma programării unei subprobleme se obişnuieşte să se spună că sunt înrudite. De obicei, aceste funcţii, împreună cu datele pe care le prelucrează, se păstrează într-un fişier şi se compilează independent.
O colecţie de funcţii înrudite, împreună cu datele pe care le prelucrează în comun formează un modul. În felul acesta, problema iniţială se realizează printr-un program alcătuit din module.
Programarea modulară are la bază elaborarea programelor pe module.
O parte din datele utilizate în comun de funcţiile modulului, sau chiar toate datele modulului, nu sunt necesare şi în alte module. Aceste date pot fi protejate sau cum se mai spune, ascunse în modul.
Limbajul C şi C++, permite ascunderea datelor în modul folosind date care au clasa de memorie static. Mai mult, pot fi declarate şi funcţiile ca statice şi atunci ele vor fi ascunse în modul (nu pot fi apelate din afara modului). Ascunderea funcţiilor în modul se face pentru acele funcţii care nu se utilizează la realizarea interfeţei modulului cu celelalte module. Ascunderea datelor şi funcţiilor în module permite protejarea datelor şi preîntâmpină utilizarea eronată a funcţiilor.
5.1.4. Programare structurată
Descompunerea unei probleme în subprobleme mai simple se poate face succesiv în mai multe etape, până când subproblemele sunt direct programabile sub forma unor proceduri sau module. Această descompunere succesivă se mai numeşte rafinare pas cu pas (stepwise refinement).. Evident că se obţine o descompunere arborescentă. Procedurile se pot organiza sau nu în module. În cadrul procedurilor se folosesc anumite structuri de control a execuţiei. Aceasta impune o anumită disciplină a programării. Structurile de control de sunt:
-
secvenţa;
-
iteraţia (pretestată, posttestată, cu număr prestabilit de ciclări);
-
alternativa (simplă, completă, generalizată).
Instrucţiunea de bază (primitivă) în cadrul acestor structuri de control este instrucţiunea de atribuire.
Această abordare a programării s-a născut din necesitatea eliminării instrucţiunii de control GO TO care face saltul necondiţionat la o instrucţiune precizată, alta decât instrucţiunea următoare ei. Profesorul Dijsktra de la Universitatea din Eindhoven spunea, prin anul 1965, “calitatea unui programator este invers proporţională cu numărul de instrucţiuni GO TO folosite” şi a impus D-structurile de control:
-
secvenţa;
-
iteraţia pretestată;
-
alternativa simplă.
D-structurile se regăsesc în toate limbajele procedurale. Corespondenţa ar fi:
-
secvenţa este echivalentă cu execuţia instrucţiunilor în ordinea scrierii lor în programul sursă;
b) iteraţia pretestată echivalentă cu WHILE ... DO;
c) alternativa simplă echivalentă cu IF ... THEN.
O ilustrare grafică a celor trei D-structuri se dă în continuare.
da
S1 C
nu da
S2 S C
S nu
.
Sn
S-a demonstrat ulterior (Bohm şi Jacopini) că orice algoritm se poate descrie doar cu D-structurile dar pentru o mai bună lizibilitate şi înţelegere a programelor sursă s-au adăugat şi iteraţia postestată (REPEAT ... UNTIL), iteraţia cu număr prestabilit de ciclări (FOR ... DO), alternativa completă (IF ... THEN ... ELSE) şi alternativa generalizată (CASE ... OF).
În unele limbaje se folosesc şi alte structuri pe lângă cele de mai sus pentru o cât mai fidelă reflectare a algoritmului.
5.1.5. Programare prin abstractizarea datelor
În toate aceste tehnologii anterioare se urmăreşte mai mult organizarea programului şi mai puţin rezolvarea cât mai naturală a problemei. Programarea prin abstractizarea datelor şi programarea orientată spre obiecte propun metodologii în care conceptele deduse din analiza problemei să poată fi reflectate cât mai fidel în program şi să se poată manevra cu instanţieri ale acestor concepte cât mai natural. Se realizează o mai mare fidelitate a programului faţă de problemă. De exemplu dacă într-o problemă în care se procesează numere complexe e nevoie să se lucreze într-o formă cât mai apropiată cu forma matematică se poate introduce tipul COMPLEX (tip care nu există în limbajele de programare) şi apoi se pot declara variabile de acest tip. Mai mult ar trebui să se poată face toate operaţiile matematice asupra datelor de tip COMPLEX. În general un TAD (Tip Abstract de Date) are două componente fundamentale:
- datele membru (reflectă reprezentarea tipului);
- funcţiile membru (reflectă comportamentul tipului).
5.1.6. Programarea orientată spre obiecte
Un neajuns al programării prin abstractizarea datelor este faptul că nu permite exprimarea legăturilor dintre diferite concepte (TAD-uri). Singura legătură dintre concepte care se poate exprima, este aceea că datele membru ale unei clase pot fi obiecte ale unei alte clase. Acest lucru nu este suficient în cazul în care conceptele sunt strâns dependente între ele formând structuri ierarhice. Exprimarea ierarhiilor conduce la atribute suplimentare cum sunt cele de moştenire. Aceste atribute conduc la un nou model de programare pe care îl numim programare orientată obiect.
În vârful unei ierarhii se află fenomenul sau forma de existenţă care are trăsături comune pentru toate celelalte componente ale ierarhiei respective. Pe nivelul următor al ierarhiei se află componentele care pe lângă trăsăturile comune de pe nivelul superior, mai au şi trăsături suplimentare, specifice. O ierarhie, de obicei, are mai multe nivele, iar situarea unui element pe un nivel sau altul al ierarhiei este uneori o problemă deosebit de complexă. Dăm în exemplul următor o ierarhie arborescentă pentru conceptele de paralelogram, dreptunghi, romb şi pătrat.
Paralelogram
Dreptunghi Romb
Pătrat
Dacă paralelogramul se află în vârful ierarhiei atunci pe nivelul imediat inferior se aşează dreptunghiul (paralelogramul cu un unghi drept) dar şi rombul (paralelgramul cu 2 laturi alăturate congruente). Apoi pătratul se poate defini fie ca un dreptunghi cu laturile congruente fie ca un romb cu un unghi drept. Conceptul de pe fiecare nivel se observă că moşteneşte proprietăţile conceptului imediat superior din care este derivat.
La ora actuală, toate ramurile cunoaşterii ştiinţfice sunt pline de ierarhii rezultate în urma clasificării cunoştinţelor acumulate în perioada lungă de observare a fenomenelor şi formelor de existenţă a lumii materiale şi spirituale. Clasificările ierarhice ale cunoştinţelor pot fi întâlnite atât în domeniile care pleacă de la cele mai concrete forme ale lumii materiale, cum sunt botanica, zoologia, biologia, etc cât şi în domenii care studiază concepte dintre cele mai abstracte, cum ar fi matematica sau filozofia.
Aceste ierarhii sunt rezultatul definirii conceptelor după regula includerii “genul proxim şi diferenţa specifică”.
Limbajul C dispune de un set bogat de instrucţiuni care permit scrierea de:
-
programe structurate,
-
programe flexibile,
-
programe compacte.
Totodată limbajul C permite aplicarea metodelor de programare procedurală, programare modulară şi programare structurată. Pe lângă aceste metodologii limbajul C++ permite şi programarea prin abstractizarea datelor şi programarea orientată spre obiecte.
Vom descrie în continuare instrucţiunile limbajului C. Ca o caracteristică sintactică toate instrucţiunile limbajului se termină prin caracterul “;”, excepţie făcând instrucţiunile care se termină cu acolada închisă.
Dostları ilə paylaş: