Cum introduci si cum scoti date dintr-un program C
Programele de calculator sunt de diverse “forme” și “culori”, așa că pot fi clasificate în diverse moduri. În articolul ăsta vreau să îți fac distincția între programele “bibelou” și programele “vii”.
Pentru a înțelege această clasificare, hai să vedem ce e, de fapt, un program.
OK, e clar că un program e o succesiune de instrucțiuni pe care calculatorul știe să le execute. Dar hai să ne îndepărtăm un pic de aceste detalii și să vedem treaba asta mai de la distanță.
Cam ce distanță? Cam atâta cât e nevoie pentru ca instrucțiunile să nu mai fie vizibile, ci întreg programul să ajungă un dreptunghi mic.
Iată cum ar arăta un program de calculator privit de la distanța asta:
Ar arăta, deci, ca “ceva” care primește “din afară” niște date (de intrare) și scoate “în afară” niște date (de ieșire).
Deci programul e ca o mașinuță de telecomandă. Când apeși pe butoanele telecomenzii îi dai date de intrare, iar datele de ieșire produse sunt noile poziții ale mașinuței.
Acuma putem să revenim la ce e un program “bibelou” și ce e un program “viu”. Eu numesc program “bibelou” un program care nu primește date de intrare.
Asta nu înseamnă că e “mort” ca o statuie. (Ba poate chiar să “licăre” sau să “danseze”.) Ci înseamnă că datele sale de ieșire vor fi mereu la fel indiferent când este rulat programul respectiv.
Ca un fel de mașinuță, dar fără telecomandă. Ci doar cu o “coregrafie” pe care știe s-o urmeze indiferent de “muzica” ce se aude.
Un program “viu”, în schimb, răspunde la stimulii exteriori. Adică în calculul datelor sale de ieșire ține cont de datele de intrare introduse de utilizatorul programului.
Din experiența ta de utilizator de programe cred că ți-e clar că “date de intrare” poate să însemne mai multe lucruri, cum ar fi:
– click-uri cu mouse-ul în diverse locuri
– trageri de obiecte cu mouse-ul
– apăsări de taste
– atingeri de ecran (ca pe telefon)
– sau chiar conținutul vreunui fișier.
Varianta cel mai la îndemână (și cel mai la “îndeochi”) pentru a da unui program date de intrare și a-i vizualiza datele de ieșire o constituie terminalul de comenzi.
Terminalul de comenzi? Da, chestia aia care îți permite să introduci text scriind din taste pe un fundal în general negru și să arăți ca un hacker în timp ce faci asta. 🙂
Programele ce rulează în terminal (sau în “consolă”, cum i se mai zice) sunt cel mai ușor de făcut — pentru că nu au nevoie de o interfață grafică (cu ferestre, meniuri și butoane), ci toate interacționarea cu ele se realizează în mod text (ca într-un fel de Notepad interactiv, capabil să și “înteleagă” unele din lucrurile pe care i le scrii acolo și să îți afișeze răspunsuri la comenzile cunoscute).
Programele pe care le-ai făcut până acum în lecțiile anterioare de C au fost programe de acest gen. (Îți amintești că în Code::Blocks selectai la un moment dat ca tip al aplicației “Console application”, da?)
Hai să revenim la subiect.
Cum scoți date dintr-un program C (ce rulează în terminal)?
Deja ai văzut cum. (În lecțiile trecute.) Cu funcția printf(…).
Ca să o folosești trebuie ca la începutul programului tău să pui instrucțiunea (de preprocesare) #include <stdio.h>. (Apropo, ăsta nu e hashtag. Exista cu mult înainte să se inventeze hashtag-uirea.)
De ce? Fiindcă acolo — în fișierul antet stdio.h este descrisă funcția printf. Altfel, programul tău n-ar ști de ea și ți-ar da eroare când ai încerca să-l compilezi.
(“Boss, ce e aia « printf »? compila-ți-aș programul tău…” ți-ar zice compilatorul dacă nu l-ai “hashtag-ui” pe “stdio”.)
Hai să tragem un pic cu ochiul în fișierul “stdio.h” și să vedem cum e prezentat acolo antetul funcției “printf”:
int printf(const char* format, …);
Mai ții minte ce e un antet de funcție în C, da? (Ai văzut într-o lecție anterioară.)
În fața numelui funcției e trecut tipul de dată pe care apelul ei îl va returna. (Adică dacă ai funcția f : A —› B (“ef definită pe a cu valori în be”), tipul returnat de ea, adică tipul valorilor de gen “f(x)” e tipul elementelor mulțimii B.)
Deci printf returnează o valoare de tip număr întreg (posibil cu semn)…
Wow! Neașteptat, nu? Mai ales că până acum ai văzut-o mereu apelată ca pe o instrucțiune de sine stătătoare, și nu ca pe o funcție ce returnează o valoare. (Ea valoare a returnat și așa, doar că acea valoare nu a fost folosită în niciun calcul și nici nu a fost stocată undeva (în vreo variabilă, adică — normal!).)
Care o fi rostul valorii ăsteia returnate?…
Aici doar documentația ne poate ajuta. Și scrie acolo că: valoarea returnată de funcția printf reprezintă numarul total de caractere ce au fost scrise (iar dacă a fost vreo eroare, se va returna un număr negativ).
OK, și ce parametri are funcția printf?
Așa cum ai văzut, are un parametru (numit acolo format) de tip const char *.
Ooo, stai așa! Ce tip de dată mai e și ăsta?!
“char *” înseamnă “pointer către o bucată de memorie de tip char”, iar “const”-ul din față înseamnă că datele respective din memorie nu vor putea fi modificate în interiorul funcției.
Dar vom vorbi altă dată despre toate astea. Acuma reține doar că parametrul pe care i-l dai funcției printf este un șir de caractere pe care îl scrii între ghilimele.
Și că în mod normal tot conținutul acelui șir de caractere (adică tot ce se găsește între ghilimele) va fi afișat pe ecran.
Adică efectul instrucțiunii
printf(“Bla-bla!”);
va fi că textul “Bla-bla!” (fără ghilimele) va fi afișat pe ecran. (În terminalul de comenzi, adică.)
Dar dacă voiai să afișezi ghilimele? Uite aici:
printf(“Uite \”ghilimele\”!”);
Pe lângă șirul de caractere denumit “format”, ai văzut că funcția printf mai poate primi un parametru — marcat acolo cu “…”.
Ce înseamnă aceste trei puncte succesive din lista de parametri a lui printf? Înseamnă o listă de parametri de dimensiune variabilă. Adică poate să nu fie acolo niciun parametru, poate să fie unul, pot să fie doi sau mai mulți.
Hai să vedem când și cum folosește funcția printf lista aceea de parametri opționali.
Ai văzut deja că o secvență de program de genul:
int a = 3;
printf(“Valoarea variabilei a este %d”, a);
are ca efect afișarea pe ecran a textului:
Valoarea variabilei a este 3
Acest lucru se întâmplă pentru că șirul de caractere “%d” este interpretat de printf ca însemnând “o valoarea de tip număr întreg (posibil cu semn)”. Și de unde va lua această valoare? Din lista de parametri.
Subșirul “%d” poartă numele de specificator de format.
Pentru a afișa o valoare de tip număr real (cu virgulă), specificatorul de format este “%f”. Iar dacă vreau ca după virgulă să fie afișate două zecimale, voi folosi ca specificator de format “%.2f”.
Ca să vezi diferența, uite aici o secvență de program pe care îți recomand s-o testezi:
float pi = 3.14159;
printf(“PI = %f; PI cu două zecimale = %.2f”, pi, pi);
Dacă te uiți în documentație o să vezi că mai sunt și alți specificatori de format și că toți aceștia pot fi parametrizați în multe feluri. E foarte puternică funcția asta, printf.
Nu o să intru aici în detalii. Te las să te documentezi, să descoperi și să experimentezi.
Vreau să-ți mai spun doar cum poți să faci ca afișarea ta să treacă pe o nouă linie. Secretul e caracterul “linie nouă”, reprezentat prin șirul “\n”. Când acest subșir e întâlnit în șirul format, efectul nu va fi afișarea lui pe ecran, ci coborârea cursorului virtual cu o linie mai jos și mutarea lui la începutul noii linii (adică la marginea din stânga).
Deci comanda
printf(“Linia 1.\nLinia 2.”);
va afișa pe ecran
Linia 1.
Linia 2.
Așa, deci…
Știi acum cum poți afișa în terminal valoarea oricărei variabile din programul tău.
Dar cum faci să citești valori de la tastatură?
Cum faci, adică, să îi dai utilizatorului programului tău posibilitatea să scrie valori în variabilele tale?
(Cum îi dai, altfel spus, posibilitatea să dea date de intrare programului tău?)
Răspunsul îl găsești la funcția scanf (‹— tot din stdio.h):
int scanf(const char * format, …);
Explicațiile sunt foarte similare cu cele de la printf, așa că nu le repet. Ce diferă e faptul că șirul de caractere format va conține doar specificatori de format, iar în lista variabilă de parametri se vor găsi adresele variabilelor în care dorești să scrii valorile citite de la tastatură. (Adresa unei variabile numite a o obțin scriind &a.)
Hai să vedem un exemplu. Uite un program care te întreabă câți ani ai și îți spune câți ani mai ai până când vei împlini 100.
#include <stdio.h>
int main()
{
int varsta;
printf(“Cati ani ai?”);
scanf(“%d”, &varsta);
printf(“Pana la 100 mai ai %d ani.”, 100 – varsta);
return 0;
}
Simpatic, nu? 🙂 (Și ce e chiar fain la programul ăsta e că îl poți rula de multe ori și de fiecare dată e posibil să îți dea alt rezultat — în funcție de răspunsul pe care îl scrii la întrebare.)
Te las acum să experimentezi. Iar dacă ai nevoie de o temă de gândire, te invit să faci un program în care utilizatorului să i se ceară 3 numere, iar programul tău să îi afișeze pe ecran suma lor.
Sau un program în care utilizatorul să scrie un număr, iar programul să afișeze pe ecran ultima cifră a acelui număr.
Sau ce zici de un program care îți cere vârsta ta și vârsta mamei tale, iar programul să îți spună peste câți ani mama ta va avea dublul vârstei tale?…
[Indicație pentru ultima: M + x = 2 (F + x), adica M + x = 2 F + 2 x, ceea ce înseamnă că M – 2 F = 2x – x, de unde rezultă că x = M – 2 F. Te-ai prins că M e vârsta mamei, F e vârsta ta, iar x e numărul de ani pe care trebuie să îl afișezi, da?]
Alatura-te celor peste 7000 de oameni din armata noastra de creiere cu muschi si vei primi testul care iti va spune daca ai sau nu minte de programator.
In plus, vei fi mereu la curent cu tot ce pun la cale.
Cu drag,