Search the Community
Showing results for tags 'c++'.
-
Tablouri Un vector (sau șir sau tablou unidimensional) reprezintă o serie de elemente de același tip, memorate în locații de memorie succesive care pot fi referite individual prin adăugarea unui index la un identificator unic. Aceasta înseamnă că, de exemplu, cinci valori de tip int pot fi declarate ca un vector fără a fi necesară declararea a cinci variabile diferite (fiecare cu propriul identificator). Intr-adevăr, folosind un vector, cele cinci valori de tip int sunt stocate în locații de memorie continuă și toate cinci pot fi accesate folosind același identificator, dar cu index-ul potrivit. De exemplu, un vector conținând cinci valori întregi de tip int denumit foo ar putea fi reprezentat astfel: unde fiecare spațiu liber reprezintă un element al șirului. În acest caz, acestea sunt valori de tip int. Aceste elemente sunt numerotate de la 0 la 4, primul fiind pe poziția 0 și 4 indicându-l pe ultimul; în C++, primul element dintr-un vector este totdeauna numerotat cu zero (nu cu unu), indiferent de lungimea vectorului. Ca și o variabilă obișnuită, un vector trebuie declarat înainte de a fi folosit. O declarație tipică pentru un tablou unidimensional în C++ este: tip nume [nr_elemente]; unde tip este un tip de dată valid (precum int, float...), nume este un identificator valid și câmpul nr_elemente (care este întotdeauna închis între paranteze drepte []) precizează lungimea vectorului prin numărul de elemente. De aceea, șirul foo, cu cinci elemente de tip int, poate fi declarat astfel: 1 int foo [5]; ATENȚIE: Câmpul nr_elemente dintre parantezele drepte [], reprezentând numărul de elemente ale vectorului, trebuie să fie o expresie constantă, deoarece vectorii sunt blocuri de memorie statică a căror dimensiune trebuie să fie cunoscută la momentul compilării, înainte ca programul să ruleze. Inițializarea vectorilor În mod implicit, vectorii obișnuiți cu domeniu local (de exemplu, cei declarați în interiorul unei funcții) sunt lăsați neinițializați. Aceasta înseamnă că niciunul dintre elementele sale nu are setată vreo valoare; conținutul lor este nedeterminat în momentul declarării vectorului. Dar elementele dintr-un vector pot fi inițializate explicit cu anumite valori la declarație, punând acele valori între acolade {}. De exemplu: int foo [5] = { 16, 2, 77, 40, 12071 }; Această instrucțiune declară un vector ce poate fi reprezentat astfel: Numărul valorilor incluse între acolade {} nu ar trebui să fie mai mare decât numărul elementelor din vector. De exemplu, mai sus foo a fost declarat ca având 5 elemente (așa cum precizează numărul dintre parantezele drepte []) și acoladele {} conțin exact 5 valori, una pentru fiecare element. Dacă s-ar fi precizat mai puține, elementele rămase ar fi fost setate la valorile lor implicite (care pentru tipurile de date fundamentale înseamnă valori zero). De exemplu: int bar [5] = { 10, 20, 30 }; va crea un vector ca și acesta: Este posibil, chiar, ca inițializarea să nu conțină nicio valoare, doar acolade: int baz [5] = { }; Aceasta crează un vector cu cinci valori de tip int, fiecare dintre ele fiind inițializată cu o valoare zero: Când se furnizează valori de inițializare pentru un vector, C++ ne permite să lăsăm parantezele drepte [] necompletate. În acest caz, compilatorul va dimensiona automat vectorul la numărul de valori incluse între acolade {}: int foo [] = { 16, 2, 77, 40, 12071 }; După această declarație, vectorul foo ar avea lungimea a cinci valori int, deoarece noi am furnizat cinci valori de inițializare. Evoluția limbajului C++ a inclus, până la urmă, la adoptarea inițializării universale și pentru vectori. De aceea, nu mai este obligatoriu să punem semnul egal între declarație și inițializare. Cele două instrucțiuni de mai jos sunt echivalente: int foo[] = { 10, 20, 30 }; int foo[] { 10, 20, 30 }; Vectorii statici și cei declarați direct în spațiile de nume (în afara oricărei funcții) sunt întotdeauna inițializați. Dacă nu se specifică o inițializare explicită, toate elementele sunt inițializate implicit (cu zero, pentru tipurile de date fundamentale). Accesarea valorilor unui vector Valorile elementelor unui vector pot fi accesate ca și valoarea unei variabile obișnuite de același tip. Sintaxa este: nume[index] Urmărind exemplul anterior în care vectorul foo avea 5 elemente și fiecare dintre aceste elemente era de tip int, numele folosit pentru referirea fiecărui element este următorul: De exemplu, instrucțiunea următoare memorează valoarea 75 în al treilea element al lui foo: 1 foo [2] = 75; și, de exemplu, următoarea copiază valoarea celui de-al treilea element al lui foo într-o variabilă numită x: x = foo[2]; De aceea, expresia foo[2] este ea însăși o variabilă de tip int. Să observăm că al treilea element al lui foo este precizat cu foo[2], deoarece primul este foo[0], cel de-al doilea este foo[1] și, de aceea, al treilea este foo[2]. Din același motiv, ultimul său element este foo[4]. De aceea, dacă am scrie foo[5], am putea să accesăm al șaselea element al lui foo, dar, de fapt, s-ar depăși dimensiunea vectorului. În C++, este corect din punct de vedere sintactic să depășim domeniul valid de indici pentru un vector. Aceasta poate crea probleme, căci la accesatea de elemente din afara domeniului nu cauzeaza erori la compilare, ci la momentul execuției programului. Vom vedea motivul pentru care este eprmis așa ceva mai târziu, într-un capitol în care vor fi prezentați pointerii. La acest moment, este important să distingem foarte clar între cele două forme de utilizare a parantezelor drepte [] în legătură cu vectorii. Se execută două sarcini diferite: una ajută la precizarea dimensiunii vctorilor când sunt declarați; cea de-a doua precizează indicii pentru anumite elemente ce trebuie accesate. Să nu confundați aceste două posibilități de folosire a parantezelor drepte [] cu vectori. int foo[5]; // declaratia unui nou vector foo[2] = 75; // accesarea unui element al vectorului Principala diferență constă în faptul că declarația este precedată de tipul elementelor, în timp ce accesarea lor nu este precedată. Alte operații valide cu vectori: foo[0] = a; foo[a] = 75; b = foo [a+2]; foo[foo[a]] = foo[2] + 5; De exemplu: // exemplu cu vectori #include <iostream> using namespace std; int foo [] = {16, 2, 77, 40, 12071}; int n, rezultat=0; int main () { for ( n=0 ; n<5 ; ++n ) { rezultat += foo[n]; } cout << rezultat; return 0; } Tablouri multidimensionale Tablourile multidimensionale pot fi descrise ca "vectori de vectori". De exemplu, un tablou bidimensional poate fi imaginat ca un tabel bidimensional format cu elemente care au același tip de dată. jimmy reprezintă un tablou bidimensional (matrice) de 3 vectori a câte 5 elemente de tip int. The C++ syntax for this is: int jimmy [3][5]; și, de exemplu, modul de a ne referi la al doilea element vertical și al patrulea orizontal ar fi o expresie ca: jimmy[1][3] (să ne amintim că indicii unui vector încep întotdeauna cu zero). Tablourile multidimensionale nu se limitează la doi indici (adică șa două dimensiuni). Ele pot conține atâția indici cât sunt necesari. Totuși, să fim atenți: cantitatea de memorie necesară pentru un tablou crește exponențial cu fiecare dimensiune. De exemplu: char century [100][365][24][60][60]; declară un tablou cu un element de tip char pentru fiecare al doilea dintr-un century. Aceasta ajunge la mai mult de 3 bilioane de char! Astfel incât această declarație ar consuma mai mult de 3 gigabytes de memorie! La sfârșit, tablourile multidimensionale sunt doar o abstractizare pentru programatori, deoarece aceleași rezultate pot fi obținute cu un vector simplu, prin înmulțirea indicilor săi: int jimmy [3][5]; // este echivalent cu int jimmy [15]; // (3 * 5 = 15) cu singura diferență că pentru tablourile multidimensionale compilatorul își reamintește automat adâncimea fiecărei dimensiuni imaginare. Următoarele două secvențe de cod produc exact același rezultat, dar una folosește un tablou bidimensional (matrice) în timp ce cealaltă folosește un tablou simplu (vector): Niciuna dintre variantele de cod de mai sus nu produce nici o ieșire pe ecran, dar ambele atribuie valori blocului de memorie denumit jimmy în felul următor: Să observăm că s-au folosit constante definite pentru lățime și înălțime, în loc de folosirea directă a unor valori numerice. Aceasta dă o mai mare claritate codului și face mai ușoară modificarea programului într-un singur loc. Tablourile ca parametri La un moment dat, vom avea nevoie să transmitem un tablou ca parametru al unei funcții. În C++, nu este posibil să transmitem unei funcții întregul bloc de memorie care conține un tablou direct ca argument. În schimb, putem să transmitem adresa sa. În practică, aceasta are cam același efect, fiind mult mai rapid și mai eficient. Pentru ca o funcție să primească un parametru tablou ca argument, parametrii pot fi declarați ca fiind de tip tablou, dar fără nimic scris între parantezele drepte, adică fără precizarea dimensiunii tabloului. De exemplu: void procedura (int arg[]) Această funcție acceptă un parametru de tip "tablou de int" denumit arg. Pentru a transmite acestei funcții un tablou, el trebuie declarat astfel: int tabloul_meu [40]; ceea ce ar fi suficient pentru a scrie un apel ca: procedura (tabloul_meu); Mai jos avem un exemplu complet: // tablouri ca parametri #include <iostream> using namespace std; void afisare_tablou (int arg[], int lungime) { for (int n=0; n<lungime; ++n) cout << arg[n] << ' '; cout << '\n'; } int main () { int tablou1[] = {5, 10, 15}; int tablou2[] = {2, 4, 6, 8, 10}; afisare_tablou (tablou1,3); afisare_tablou (tablou2,5); } Rezultat: 5 10 15 2 4 6 8 10 În programul se mai sus, primul parametru (int arg[]) acceptă orice tablou ale cărui elemente sunt de tip int, indiferent de lungime. De aceea, am inclus un al doilea parametru care îi precizează funcției lungimea fiecărui tablou ce va fi transmis ca prim parametru. Aceasta face ca repetiția for care afișează tabloul să știe în ce interval să itereze tabloul, fără a-i depăși limitele. Într-o definiție de funcție se pot include și tablouri multidimensionale. Formatul pentru un tablou tridimensional dat ca parametru este: tip_baza[][adancime][adancime] De exemplu, o funcție care are un tablou tridimensional ca parametru ar putea fi: void procedura (int tabloul_meu[][3][4]) Sublinime că prima pereche de paranteze drepte [] nu are nimic completat, în timp ce în următoarele se precizează mărimile pentru respectivele dimensiuni. Acest lucru este necesar, astfel încât compilatorul să poată determina adâncimea pentru fiecare nouă dimensiune. Într-un fel, transmiterea unui tablou ca argument pierde întotdeauna o dimensiune. Motivul, din motive istorice, este acela că tablourile nu pot fi copiate direct, ci se transmit prin intermediul pointerilor. Aceasta este o sursă uzuală de erori pentru programatorii începători. Deși, o înțelegere clară a pointerilor, explicată într-un capitol următor, ar ajuta foarte mult. Biblioteca pentru tablouri Tablourile explicate mai sus sunt implementate direct ca o caracteristică a limbajului, moștenită din limbajul C. Sunt grozave, dar prin restricționarea copierii lor și folosirea pointerilor, se simte o oarecare lipsă de optimizare. Pentru a contracara aceasta modalitate de implementare a tablourilor, C++ furnizează o alternativă la tipul tablou printr-un container standard. Este un tip șablon (un șablon de clasă, de fapt) definit în fișierul antet <array>. Containerele sunt o caracteristică de bibliotecă pe care nu am inclus-o în acest tutorial, motiv pentru care nu vom discuta aici despre această clasă. Este suficient să spunem că funcționează în mod similar cu tablourile predefinite, dar pot fi fi copiate (operație care, în fapt, este foarte costisitoare și ar trebui folosită cu grijă) și se apelează la pointeri numai când se precizează explicit să se facă așa (cu ajutorul membrului data). Doar ca un exemplu, dăm mai jos două versiuni ale aceluiași program, una cu implementarea predefinită descrisă în acest capitol și cealaltă cu containerele din bibliotecă: După cum se poate vedea, ambele tablouri folosesc aceeași sintaxă pentru accesarea elementelor: tabloul_meu. În rest, principala diferență constă în declarația tabloului și includerea suplimentară a unui fișier antet biblioteca array. De asemenea, observați cât este de ușor de accesat dimensiunea tabloului de bibliotecă. Sursa: c++.net
-
- 2
-
-
Tipuri de conversii , C++ ne permite să considerăm o valoare de un anumit tip da fiind de alt tip. Aceasta se numește conversie de tip. În C++ sunt două feluri de conversii de tip: conversia implicită conversia explicită Conversia implicită Conversia implicită intervine de la sine când într-o operație avem operanzi de tipuri diferite. Compilatorul consideră automat ambele date de același tip pentru a putea efectua operația. Conversia implicită se face doar dacă operanzii sunt de tipuri compatibile – vezi mai jos o listă de compatibilități pentru tipurile numerice. Dacă tipurile nu sunt compatibile obținem eroare de sintaxă! Exemple Conversie de la int la double #include <iostream> using namespace std; int main() { int n = 5; double x; /// conversie de la int la double x = n; cout << "n = " << n << endl; cout << "x = " << x << endl; return 0; } n=5 x=5 Conversie de la double la int #include <iostream> using namespace std; int main() { int n; double x = 5.75; /// conversie de la double la int n = x; cout << "n = " << n << endl; cout << "x = " << x << endl; return 0; } n=5 x=5.75 Deoarece o dată de tip int memorează numere întregi, în timpul conversiei zecimalele valorii lui x s-au pierdut. Pierderea de date în timpul conversiei Așa cum am văzut în exemplul anterior, conversia de tip poate duce la pierderea (trunchierea) unor date. Acest lucru nu este neapărat rău, dar trebuie să fim conștienți de această situație. În fapt, conversia este de două feluri: promovare – conversie de la un tip de date inferior la unul superior; nu produce pierdere de date! retrogradare – conversie de la un tip de date superior la unul inferior; poate produce pierdere de date! În primul exemplu de mai sus a avut loc o promovare de la int la double, iar în al doilea exemplu a avut loc o retrogradare de la double la int. Cea de-a doua a condus la pierderea unor date. În situațiile în care este posibil, compilatorul realizează conversiile implicite prin promovare. De exemplu, rezultatul expresiei 2 + 1.5 va fi 3.5, nu 3. Are loc promovarea valorii 2 la tipul double, nu retrogradarea lui 1.5 la int, ceea ce ar fi însemnat pierderi de date! Conversia explicită Conversia explicită a datelor înseamnă modificarea manuală, de către programator, a tipurilor de date folosite într-o expresie. Se mai numește și type casting. Operatorul de conversie explicită Are sintaxa: (TIP) expresie sau TIP(expresie) Observații este un operator unar; are prioritate mare; rezultatul său este rezultatul expresiei, considerat de tipul de date TIP; în varianta a doua TIP trebuie să fie un nume de tip format dintr-un singur cuvânt. Astfel, expresia unsigned int(expresie) este greșită. Exemplu char c='A'; cout << (int) c << endl; // 65 cout << char(97) << endl; // a Notă: Limbajul C++ oferă și următorii operatori de conversie: static_cast, dynamic_cast, const_cast și reinterpret_cast. Câteva reguli privind conversia: dacă se convertește un întreg negativ la un tip fără semn rezultatul va fi complementul în baza 2 a valorii inițiale, datorită modului de reprezentare a valorilor întregi. Astfel, -1 devine cea mai mare valoare a tipului fără semn, -2 devine a doua cea mai mare valoare, etc. la conversia unei valori numerice la tiplul bool rezultatul va fi: true, dacă valoarea inițială este nenulă; false, dacă valoarea inițială este 0; la conversia unei valori de tip float, double la un tip întreg, valoare se va trunchia, pierzându-se partea zecimală. Dacă rezultatul nu se încadrează în limitele tipului întreg, comportamentul programului devine impredictibil. Regulile de mai sus se aplică atât pentru conversia implicită, cât și pentru cea explicită. Exemplu: media aritmetică Să presupunem că dorim să determinăm media aritmetică trei numere întregi. Desigur, răspunsul este suma numerelor împărțită la 3, dar trebuie ținut cont de faptul că împărțirea a doi întregi este câtul împărțirii. Pentru a obține media corectă va trebui să facem anumite conversii. Exemplu 1 – conversie implicită int a , b, c; cin >> a >> b >> c; int S = a + b + c; /// cout << S / 3; // gresit - impartire intreaga cout << S / 3.0; A avut loc conversia implicită a lui S la double (promovare). Exemplu 2 – conversie implicită int a , b, c; cin >> a >> b >> c; int S = a + b + c; cout << 1.0 * S / 3; A avut loc conversia implicită a lui S, apoi a lui 3, la double (promovări). Exemplu 3 – conversie explicită int a , b, c; cin >> a >> b >> c; int S = a + b + c; cout << (double)S / 3; Mai întâi se convertește explicit valoarea lui S la double, apoi are loc conversia implicită la double a lui 3. Evitarea depășirii de tip În numeroase situații avem operații cu date de tip int, dar rezultatul depășește limita maximă (sau minimă) a acestui tip. Astfel se produce depășirea de tip – overflow. Soluția este utilizarea unor conversii prin care operațiile se realizează într-un tip de date mai larg, de exemplu long long. Exemplu: int n = 1000000; cout << n * n << endl; /// posibil -727379968 - overflow cout << 1LL * n * n << endl; /// corect 1000000000000 cout << (long long) n * n << endl; /// corect La realizarea conversiilor trebuie ținut cont de precedența operatorilor. De exemplu, secvența de mai jos nu obține rezultatul corect. int n = 1000000; cout << 1LL * n + n * n << endl; cout << (long long)n + n * n << endl; Articol intreg : https://cplusplus.com/doc/tutorial-ro/typecasting/
-
- 2
-
-
Intrari / Iesiri de baza Programele date ca exemplu în secțiunile anterioare au conținut prea puțină interacțiune cu utilizatorul, dacă nu chiar deloc. Ele pur și simplu afișau valori pe ecran, dar biblioteca standard furnizează multe alte modalități de interacțiune cu utilizatorul prin facilitățile de intrare/ieșire. Această secțiune va prezenta o scurtă introducere în câteva dintre cele mai utile. C++ folosește o noțiune potrivită numită stream-uri pentru a efectua operații secvențiale de intrare/ieșire la/de la monitor, tastatură sau fișiere. Un stream este o entitate în care un program poate insera sau din care poate extrage caractere. Nu este necesar să cunoaștem amănunte despre locațiile asociate acestui stream sau detalii interne ale sale. Tot ceea ce trebuie să știm este faptul că stream-ul reprezintă sursa /destinația caracterelor și faptul că aceste caractere sunt transmise/preluate secvențial (adică unul după altul). Biblioteca standard definește un tip comod de lucru cu obiecte stream care pot fi folosite pentru accesarea a ceea ce se consideră surse și destinații standard de caractere pentru mediul în care rulează programele: Stream // Descriere cin // Stream standard de intrare cout // Stream standard de ieșire cerr // Stream standard de afișare a erorilor clog // Stream standard de afișare a logărilor Noi vom da mai multe detalii numai despre cout și cin (stream-urile standard pentru ieșire, respectiv intrare); cerr și clog reprezintă tot stream-uri de ieșire, deci ele lucrează, în esență,ca și cout, cu singura diferență că identifică stream-uri cu un anumit scop: mesajele de eroare și logările; iar, de cele mai multe ori, în cele mai multe setări de mediu, ele fac exact același lucru: afișează pe ecran, deși se poate face redirecționarea lor. Ieșire standard (cout) În cele mai multe medii de programare, ieșirea standard implicită este ecranul monitorului, iar obiectul stream C++ definit pentru accesarea lui este cout. Pentru operații de ieșire formatată, cout se folosește împreună cu operatorul de inserare, care se scrie cu simbolul << (adică două semne ”mai mic decât”). cout << "Instructiune de iesire"; // afiseaza pe ecran Instructiune de iesire cout << 120; // afiseaza pe ecran numarul 120 cout << x; // afiseaza pe ecran valoarea lui x ]/code] Operatorul << inserează datele care urmează în stream-ul care îl precede. În exemplele de mai sus, inserează string-ul de caractere Instructiune de iesire, numărul 120 și valoarea variabilei x în stream-ul standard de ieșire cout. Să observăm că mesajul din prima instrucțiune este cuprins între ghilimele (") deoarece este un string (șir de caractere), în timp ce în ultima x nu este. Ghilimelele sunt cele care fac diferența între un text (cel care este cuprins între ele) care va fi afișat pe ecran exact așa cum este și identificatorii de variabile (care nu sunt cuprinși între ghilimele) ce se interpretează, afișându-se pe ecran valorile lor. De exemplu, aceste două instrucțiuni au rezultate foarte diferite: [code] cout << "Hello"; // afiseaza pe ecran Hello cout << Hello; // afiseaza pe ecran continutul variabilei Hello Într-o singură instrucțiune pot fi incluse mai multe operații de inserare (<<): cout << "Aceasta " << " este o " << "singura instructiune C++"; Ultima instrucțiune ar trebui să afișeze pe ecran Aceasta este o singura instructiune C++. Înlănțuirea de inserții este foarte utilă în afișarea mixtă de mesaje și variabile cu o singură instrucțiune: cout << "Eu am " << varsta << " ani si codul meu postal este " << cod; Presupunând că variabila varsta conține valoarea 24 și că variabila cod conține 90064, ieșirea instrucțiunii anterioare este: Eu am 24 ani si codul meu postal este 90064 cout nu adaugă automat sfârșit de linie, dacă nu i se precizează să facă asta. De exemplu, să luăm următoarele două instrucțiuni de inserare în cout: cout << "Aceasta este o propozitie."; cout << "Aceasta este o alta propozitie."; Afișarea se face pe o singură linie, fără trecere la rând nou. Cam așa: Aceasta este o propozitie.Aceasta este o alta propozitie. Pentru a insera un rând nou, ar trebui să inserăm caracterul new-line exact în poziția în care ar trebui să apară întreruperea rândului. În C++, un caracter new-line poate fi precizat cu \n (adică un caracter backslash urmat de litera mică n). De exemplu: cout << "Prima propozitie.\n"; cout << "A doua propozitie.\nA treia propozitie."; Acestea produc următoarea ieșire: Prima propozitie. A doua propozitie. A treia propozitie. Alternativ, manipulatorul endl poate fi folosit pentru a întrerupe liniile. De exemplu: cout << "Prima propozitie." << endl; cout << "A doua propozitie." << endl; Aceasta ar afișa: Prima propozitie. A doua propozitie. Manipulatorul endl produce un caracter newline, exact ca și inserarea cu '\n'; dar are, totuși un comportament diferit: buffer-ul de stream (dacă există) este curățat, ceea ce înseamnă că ieșirea necesită scrierea fizică la dispozitiv, dacă nu s-a făcut deja. Aceasta afectează, în principal, stream-urile cu buffer plin și cout nu este (în general) un stream cu buffer plin. Este o idee bună să folosim endl numai când curățarea stream-ului ar fi un lucru pe care nu îl poate face '\n'. Să reținem că operația de curățare aduce o suprasolicitare și unele dispozitive pot fi mai încete, producând întârzieri. Intrare standard (cin) În cele mai multe medii de programare, intrarea standard setată implicit este tastatura, iar obiectul stream C++ definit pentru a o accesa este cin. Pentru operații de intrare cu formatare cin se folosește împreună cu operatorul de extragere, pentru care folosim simbolul >> (adică două semne "mai mare decât"). Acest operator este urmat de variabila în care va fi depusă informația extrasă. De exemplu: int varsta; cin >> varsta; Prima instrucțiune declară o varibilă de tip int denumită varsta, iar a doua extrage din cin o valoare ce va fi memorată în ea. Această operație face ca programul să aștepte o intrare de la cin; în general, aceasta înseamnă că programul va aștepta după utilizator să introducă o secvență de la tastatură. În acest caz, rețineți că toate caracterele tastate sunt transmise programului numai câdn este apăsată tasta ENTER (sau RETURN). Când se ajunge la instrucțiunea cu operația de extragere din cin, programul va aștepta atât cât este necesar până când sunt introduse date. Operația de extragere din cin folosește tipul variabilei de după operatorul >> pentru a determina cum să interpreteze caracterele citite de la intrare; dacă este un întreg, formatul așteptat este o serie de cifre, dacă este un string se așteaptă o secvență de caractere, etc. // exemplu i/o #include <iostream> using namespace std; int main () { int i; cout << "Va rugam, introduceti o valoare intreaga: "; cin >> i; cout << "Valoarea introdusa este " << i; cout << " si dublul sau este " << i*2 << ".\n"; return 0; } Va afisa: Va rugam, introduceti o valoare intreaga: 702 Valoarea introdusa este 702 si dublul sau este 1404. După cum puteți vedea, extragere din cin pare să facă foarte simplă și directă sarcina de extragere a datelor de la intrarea standard. Dar această metodă are și un mare neajuns. Ce se întâmplă în exemplul de mai sus dacă utilizatorul introduce ceva ce nu poate fi interpretat ca număr întreg? Ei bine, în acest caz, operația de extragere eșuează. În mod implicit, aceasta permite prograumului să continue fără atribuirea unei valor varabilei i, producând rezultate nedeterminate dacp valoarea lui i va fi folosită mai târziu. Acesta este un comportament deficitar al prgramului. Cele mai multe programe trebuie să se comporte într-o anume manieră, indeiferent de ceea ce tastează utilizatorul, gestionând în mod adecvat valorile invalide. Numai programele foarte simple ar trebui să se bazeze pe extrageri directe din cin, fără un control mai serios. Puțin mai târziu vom vedea cum poate fi folosis stringstreams pentru a avea un control mai bun asupra intrărilor date de utilizator. Extragerile din cin pot, de asemenea, să fie înlănțuite, atfelt încât să se ceara mai multe informații într-o singură instrucțiune: cin >> a >> b; Aceasta este echivalentă cu: cin >> a; cin >> b; În ambele cazuri, se așteaptă ca utilziatorul să introducă două valori, una pentru variabila a, iar cealaltă pentru variabila b. Se poate folosi orice fel de spațiu pentru a separa două operații consecutive de intrare; poate fi spațiu, tab sau un caracter new-line. cin și string-uri Operatorul de xtragere poate fi folosit cu cin pentru a obține șiruri de caractere la fel ca și cu celelalte tipuri de date fundamentale: string sirul_meu; cin >> sirul_meu; Totuși, extragerea din cin ia în considerare separatorii (caracterele spațiu, tab, new-line...) ca terminatori ale valorii ce trebuie extrase și, de aceea, extragerea unui string înseamnă că se va prelua numai un singur cuvânt, nu o intreagă frază sau propoziție. Pentru a obține o linie întreaga de la cin, există o funcție numită getline, care ia stream-ul (cin) ca prim argument și variabila string ca al doilea argument. De exemplu: // cin cu string-uri #include <iostream> #include <string> using namespace std; int main () { string sirul_meu; cout << "Cum te numesti? "; getline (cin, sirul_meu); cout << "Hello " << sirul_meu << ".\n"; cout << "Care este echipa ta favorita? "; getline (cin, sirul_meu); cout << "Mie imi place " << sirul_meu << ", de asemenea!\n"; return 0; } Va afisa : Cum te numesti? Homer Simpson Hello Homer Simpson. Care este echipa ta favorita? The Isotopes Mie imi place The Isotopes , de asemenea! Să observăm că ambele au apelat funcția getline, am folosit același identificator de string (sirul_meu). În al doilea apel, programul doar a înlocuit conținutul anterior cu cel nou care a fost tastat. Comportamentul standard este ca de fiecare dată când i se cer date utilizatorului, el să le completeze și apoi să apese tasta ENTER (sau RETURN). Aceasta se întâmplă, în general, în programele consolă și se poate realiza folosind getline pentru a obține date de intrare de la utlizator. De aceea, numai dacă aveți un motiv serios să nu o faceți, ar trebui să utilizați getline pentru preluarea datelor de intrare în programele consolă, în loc de extragerea din cin. stringstream Antetul standard <sstream> definește un tip numit stringstream care permite ca un string să fie tratat ca stream și, deci, să fie permise operațiile de extragere și inserare din/în string-uri în același fel ca și pentru cin și cout. Această caracteristică este foarte utilă în convertirea string-urilor la valori numerice și invers. De exemplu, pentru a extrage un întreg dintr-un șir putem scrie: string sir ("1204"); int numar; stringstream(sir) >> numar; Aceasta declară un string cu valoarea inițială "1204" și o variabilă de tip int. Apoi, a treia linie folosește această variabilă pentru a extrage dintr-un stringstream construit din string. Această secvență de cod memorează valoarea numerică 1204 în variabila numar. // stringstreams #include <iostream> #include <string> #include <sstream> using namespace std; int main () { string sir; float pret=0; int cantitate=0; cout << "Introduceti pretul: "; getline (cin,sir); stringstream(sir) >> pret; cout << "Introduceti cantitatea: "; getline (cin,sir); stringstream(sir) >> cantitate; cout << "Pretul total: " << pret*cantitate << endl; return 0; } Va afisa : Introduceti pretul: 22.25 Introduceti cantitatea: 7 Pretul total: 155.75 În acest exemplu, colectăm indirect valori numerice de la intrarea standard indirectly: în loc să extragem valorile numerice direct de la cin, obținem linii într-un obiect string (sir), apoi extragem valorile din string în variabilele pret și cantitate. Deoarece acestea sunt valori numerice, se pot executa operații aritmetice cu ele, precum înmulțirea lor pentru a obține valoarea totală. Cu această abordare, de a obține linii întregi și de a extrage conținutul lor, separăm procesul de preluare a informațiilor de la utilizator de del de intrepretare a lor ca date; astfel, procesul de preluare date este așa cum se așteaptă utilizatorul să fie și, în același timp, câștigăm controlul asupra transformării conținutului în date utile pentru program. Sursa : www.cpluscplus.com
-
Operatori Pentru că am introdus variabilele și constantele, putem începe să operăm cu ele folosind operatori. Ceea ce urmează este o listă completă a operatorilor. În acest moment nu este necesar să îi cunoaștem pe toți, dar i-am prezentat pe toți pentru a ne servi ca referință. Operatorul de atribuire (=) Operatorul de atribuire asignează unei variabile o valoare. x = 5; Această instrucțiune atribuie valoarea întreagă 5 variabilei x. Operația de atribuire are loc întotdeauna de la dreapta la stânga, niciodată în sens invers: x = y; Această instrucțiune atribuie variabilei x valoarea conținută în variabila y. Valoarea lui x la momentul execuției acestei instrucțiuni este pierdută și înlocuită cu valoarea lui y. De asemenea, considerăm că doar atribuim lui x valoarea lui y, la momentul operației de atribuire. De aceea, dacă y se schimbă mai târziu, aceasta nu va afecta valaorea luată de x. De exemplu, să ne uităm puțin la codul următor - am inclus în comentarii evoluția conținutului memorat în variabile: // operatorul de atribuire #include <iostream> using namespace std; int main () { int a, b; // a:?, b:? a = 10; // a:10, b:? b = 4; // a:10, b:4 a = b; // a:4, b:4 b = 7; // a:4, b:7 cout << "a:"; cout << a; cout << " b:"; cout << b; } Acest program afișează pe ecran valorile finale ale lui a și b (4, respectiv 7). Observați că a nu a fost afectat de schimbarea finală a lui b, chiar dacă am avut a = b mai înainte. Operațiile de atribuire sunt expresii care pot fi evaluare. Aceasta înseamnă că atribuirea însăși are o valoare și, pentru tipurile fundamentale, este cea atribuită în operație. De exemplu: y = 2 + (x = 5); În această expresie, lui y i se atribuie rezultatul sumei dintre 2 și valoarea altei expresii de atribuire (care are, la rândul ei, valoarea 5). Este echivalentă cu: x = 5; y = 2 + x; cu rezultatul final 7 atribuit lui y. Următoarea expresie este validă, de asemenea, C++: x = y = z = 5; Ea asignează valoarea 5 tuturor celor trei variabile: x, y și z; întotdeauna de la dreapta la stânga. Operatori aritmetici ( +, -, *, /, % ) Cele cinci operații aritmetice suportate de C++ sunt: Operator // Descriere + // Adunare - // Scădere * // Înmulțire / // Împărțire % // Modular Operațiile de adunare, scădere, înmulțire și împărțire corespund exact operatorilor matematici cunoscuți. Ultimul, operatorul modulo, reprezentat de simbolul procent (%), determină restul împărțirii a două valori. De exemplu: x = 11 % 3; are ca efect faptul că variabila x conține valoarea 2, deoarece împărțind pe 11 la 3 obținem câtul 3 și restul 2. Atribuire compusă (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=) Operatorii pentru atribuire compusă modifică valoarea curentă a variabilei față de ea însăși. Sunt echivalente cu atribuirea rezultatului unei operații chiar primului operand: Expresie // Echivalentă cu... y += x; // y = y + x; x -= 5; // x = x - 5; x /= y; // x = x / y; pret *= cantitate + 1; pret = pret * (cantitate+1); și la fel pentru toți operatorii de atrbuire compusă. De exemplu: // atribuire compusa #include <iostream> using namespace std; int main () { int a, b=3; a = b; a+=2; // echivalent cu a=a+2 cout << a; } Incrementare și decrementare (++, --) Unele expresii pot fi prescurtate chiar mai mult: operatorul de incrementare (++) și operatorul de decrementare (--) crește, respectiv descrește cu o unitate valoarea memorată în variabilă. Ele sunt echivalente cu +=1, respectiv -=1. Deci: 1 2 3 ++x; x+=1; x=x+1; au toate același sens; fiecare dintre ele crește cu 1 valoarea lui x. În primele compilatoare C, cele trei expresii de mai sus ar fi putut produce cod executabil diferit. Acum, însă, acest tip de optimizare a codului este executat automat de către compilator, deci cele trei expresii ar trebui să producă exact același cod executabil. O particularitate a acestui operator este aceea că poate fi folosit atât ca prefix, cât și ca sufix. Aceasta înseamnă că poate fi scris fie înaintea numelui variabile(++x) fie după el (x++). Cu toate că în expresii simple precum x++ sau ++x, au exact același înțeles, în alte expresii în care rezultatul incrementării sau decrementării este evaluat, poate fi o mare diferență între sensurile lor: în cazul prefixării operatorului de incrementare a valorii (++x), expresia se evaluează cu valoarea finală a lui x, adică acea valoare care a fost deja majorată. Pe de altă parte, în cazul postfixării (x++), valoarea este majorată,dar expresia se evaluează cu valaorea pe care o avea x înainte de incrementare. Să observăm diferența: Exemplul 1 x = 3; y = ++x; // x contine 4, y contine 4 Exemplul 2 x = 3; y = x++; // x contine 4, y contine 3 În Exemplul 1, valoarea atribuita lui y este valoarea lui x după ce a fost majorată. În timp ce în Exemplul 2, are valoarea lui x înainte ca ea să fi fost majorată. Operatori de relație și egalitate ( ==, !=, >, <, >=, <= ) Două expresii pot fi comparate folosind operatori de relație și de egalitate: de exemplu, pentru a ști dacă două valori sunt egale sau dacă una este mai mare decât cealaltă. Rezultatul unei asemenea operații este una dintre valorile boolene true (adevărat) sau false (fals). Operatorii relaționali C++ sunt: Operator // Descriere == // Egal cu != // Diferit de < // Mai mic decât > // Mai mare decât <= // Mai mic decât sau egal cu >= // Mai mare decât sau egal cu Să vedem câteva exemple: (7 == 5) // are valoarea false (5 > 4) // are valoarea true (3 != 2) // are valoarea true (6 >= 6) // are valoarea true (5 < 5) // are valoarea false Evident că nu doar valori numerice constante pot fi comparate, ci oricare două valori, inclusiv variabile. Să presupunem că a=2, b=3 și c=6; atunci: (a == 5) // are valoarea false, deoarece a nu este egal cu 5 (a*b >= c) // are valoarea true, deoarece (2*3 >= 6) este true (b+4 > a*c) // are valoarea false, deoarece (3+4 > 2*6) este false ((b=2) == a) // are valoarea true Atenție! Operatorul de atribuire (operatorul =, cu un simbol egal) nu este același cu operatorul de egalitate folosit pentru comparație(operatorul ==, cu două semne egal); primul (=) atribuie valoarea din partea dreaptă variabilei din stânga, în timp ce celălalt (==) compară valorile din cele două părți ale operatorului de egalitate. De aceea, în ultima expresie ((b=2) == a), mai întâi atribuim valoarea 2 lui b și apoi o comparăm cu a (care conține tot valoarea 2), deci avem true. Operatori logici ( !, &&, || ) Operatorul ! este implementarea în C++ a operației boolene NOT. Are doar un operand, la dreapta sa, și îl neagă producând false dacă operandul este true, respectiv true dacă operandul este false. În principiu, el returnează valoarea booleană opusă valorii pe care o are operandul. De exemplu: !(5 == 5) // are valoarea false deoarece expresia din dreapta (5 == 5) este true !(6 <= 4) // are valoarea true deoarece (6 <= 4) este false !true // are valoarea false !false // are valoarea true Operatorii logici && și || se folosesc la evaluarea a două expresii pentru a obține un singur rezultat de relație. Operatorul && corespunde operației logice boolene AND, care va avea rezultatul true dacă ambii operanzi au valoarea true și false în celelalte situații. Următorul tabel ne arată rezultatul operatorului && după evaluarea expresiei a&&b: Operatorul && (și) a | b | a && b true | true | true true | false | false false | true | false false | false | false Operatorul || corespunde operației logice boolene OR, care are valaorea true dacă oricare dintre operanzii săi are valoarea true, deci va fi falsă numai când ambii operanzi sunt falși. Iată posibilele rezultate ale lui a||b: Operatorul || (sau) a b a || b true true true true false true false true true false false false De exemplu: ( (5 == 5) && (3 > 6) ) // are valoarea false ( true && false ) ( (5 == 5) || (3 > 6) ) // are valoarea true ( true || false ) Când folosim operatorii logici, C++ evaluează numai cât este necesar de la stânga spre dreapta pentru a afla rezultatul operației, ignorând restul. De aceea, în ultimul exemplu ((5==5)||(3>6)), C++ evaluează mai întâi dacă egalitatea 5==5 este true și , în caz afirmativ, nu va mai verifica dacă și inegalitatea 3>6 este true sau nu. Acest mecanism este cunoscut ca evaluare scurt-circuit și lucrează, pentru acești operatori ca mai jos: Operator // Scurt-circuit && // dacă expresia din partea stângă este false, rezultatul combinat este false (expresia din partea dreaptă nu va mai fi evaluată). || // dacă expresia din partea stângă este true, rezultatul expresiei combinate este true (expresia din partea dreaptă nu va mai fi evaluată). Cel mai important este când expresia din partea dreaptă ar putea avea efecte, ca de exemplu să altereze valorile: if ( (i<10) && (++i<n) ) { /*...*/ } // atentie la expresia care il incrementeaza pe i Aici, expresia condițională combinată l-ar putea crește pe i cu o unitate, dar numai în cazul în care condiția din stânga semnului && are valaorea true, deoarece altfel condiția din partea dreaptă (++i<n) nu va fi evaluată (deci incrementarea nu are loc). Operatorul condițional ternar ( ? ) Operatorul condițional evaluează o expresie, returnând o valoare dacă expresia are valoarea true, respectiv o altă valoare atunci când expresia are valoarea de adevăr false. Sintaxa ei este: conditie ? rezultat_1 : rezultat_2 În cazul în care conditie are valoarea true, întreaga expresie se evaluează cu rezultat_1, iar altfel se evaluează cu rezultat_2. 7==5 ? 4 : 3 // are valoarea 3, deoarece 7 nu este egal cu 5. 7==5+2 ? 4 : 3 // are valoarea 4, deoarece 7 este egal cu 5+2. 5>3 ? a : b // are valoarea lui a, deoarece 5 este mai mare decat 3. a>b ? a : b // are acea valoare care este mai mare, a sau b. De exemplu: // operatorul conditional #include <iostream> using namespace std; int main () { int a,b,c; a=2; b=7; c = (a>b) ? a : b; cout << c << '\n'; } În acest exemplu, a este 2, b este 7, așa încât expresia care trebuie evaluată (a>b) nu are valoarea true, deci prima valoare precizată după semnul de întrebare este ignorată în favoarea celei de-a doua valori (cea de după două puncte) adică b (care este 7). Operatorul virgulă ( , ) Operatorul virgulă (,) este folosit pentru a separa două sau mai multe expresii succesive. Când setul de expresii trebuie evaluat la o valoare, numai expresia cea mai din dreapta se va lua în considerare. De exemplu, codul următor: a = (b=3, b+2); asignează mai întâi valoarea 3 lui b, apoi asignează b+2 variabilei a. Așa încât, la sfârșit, variabila a ar putea conține valoarea 5 în timp ce variabila b ar conține valoarea 3. Operatori pe biți ( &, |, ^, ~, <<, >> ) Operatorii pe biți modifică variabilele considerând șablonul de biți al valorilor pe care le conțin variabilele. Operatorul de conversie explicită Operatorii de conversie de tip permit conversia unei valori dintr-un anumit tip de dată la un al tip. Sunt câteva modalități de a face aceasta în C++. Cea mai simplă, care a fost moștenită din limbajul C, este cea prin care expresia de convertit este precedată de noul tip cuprins între paranteze (()): int i; float f = 3.14; i = (int) f; Codul anterior convertește numărul real zecimal 3.14 la o valoare întreagă (3); restul se pierde. Aici, operatorul de conversie este (int). Altă modalitate de a face exact același lucru în C++ este folosirea notației funcționale: după cuvântul cheie corespunzător noului tip, urmează expresia de convertit cuprinsă între paranteze: i = int (f); Ambele modalități de conversie de tip sunt valide în C++. sizeof Acest operator acceptă un parametru, care poate fi un tip de dată sau o variabilă, și returnează dimensiunea în bytes a acelui tip sau obiect: x = sizeof (char); Aici, lui x i se asignează valoarea 1, deoarece tipul de dată char are dimensiunea de un byte. Valoarea returnată de sizeof este determinată în timpul compilării, deci ea este determinată întotdeauna înainte de execuția programului. Alți operatori Mai târziu, în aceste lectii vom vedea mai mulți operatori, precum cei referitori la pointeri sau cei specifici programării orientate pe obiecte. Precedența operatorilor O singură expresie poate conține mai mulți operatori. De exemplu: x = 5 + 7 % 2; În C++, expresia de mai sus atribuie valoarea 6 lui x, deoarece operatorul % are o precedență mai mare față de operatorul + și este evaluat întotdeauna înainte. Uneori părți ale unor expresii pot fi cuprinse între paranteze pentru a modifica ordinea dată de precedență sau pentru a face mai explicit efectul dorit. Să observăm diferența: x = 5 + (7 % 2); // x = 6 (la fel si fara paranteze) x = (5 + 7) % 2; // x = 0 De la prioritatea cea mai mare la cea mai mică, operatorii C++ sunt evaluați în ordinea următoare: Când o expresie are doi operatori cu același grad de precedență, gruparea determină care dintre ei este evaluat primul: fie de la stânga la dreapta fie de la dreapta la stânga. Includerea tuturor subexpresiilor în paranteze (chiar și acolo unde nu este necesar datorită precedenței) poate îmbunătăți claritatea sursei. Sursa: www.cpluscplus.com
-
- 2
-
-
-
Constante Constante sunt expresii cu valoarea fixă. Valori precizate Valorile precizate sunt cel mai clar exemplu de constante. Ele sunt folosite pentru a exprima anumite valori în sursa unui program. Deja am folosit unele dintre ele în capitolele anterioare pentru a atribui anumite valori unor variabile sau pentru a transmite mesaje pe care dorim ca programul nostru să le afișeze. Am scris: a = 5; Valoarea 5 reprezintă o valoare precizată în această secvență de cod. Constantele precizate prin valori sunt clasificate în: întregi, reale, caractere, string-uri, boolean, pointeri și valori precizate definite de utilizator. Numere întregi 1776 707 - Acestea sunt constante precizate care identifică valori de tip întreg. Să remarcăm că ele nu sunt cuprinse între ghilimele sau între alte caractere speciale; sunt pur și simplu succesiuni de cifre reprezentând un număr în baza 10; de exemplu, 1776 reprezintă întotdeauna valoarea o mie șapte sute șapte zeci și șase. În plus față de numerele zecimale (cele cu care lucrăm uzual), C++ permite precizarea de constante în formatul numerelor octale (în baza și hexazecimale (în baza 16). Pentru octali, cifrele sunt precedate de un caracter 0 (zero). Pentru hexazecimale, vor fi precedate de combinația 0x (zero, x). De exemplu, următoarele constante precizate sunt echivalente una cu cealaltă: 75 // zecimal 0113 // octal 0x4b // hexazecimal Toate reprezinta același număr: 75 (șaptezeci și cinci), exprimat în baza 10, respectiv bazele opt și 16. Aceste constante precizate au câte un tip, la fel ca și variabilele. În mod implicit, valorile întregi sunt de tipul int. Totuși, putem adăuga anumite sufixe la o constantă pentru a preciza un alt tip întreg: Unsigned poate fi combinat cu oricare dintre ceilalți doi, în orice ordine, pentru a forma unsigned long sau unsigned long long. De exemplu: 75 // int 75u // unsigned int 75l // long 75ul // unsigned long 75lu // unsigned long În toate cazurile de mai sus, sufixul poate fi precizat folosind litere mari sau mici. Numere reale Exprimă valori reale, cu zecimale și/sau exponenți. Ele pot conține punct zecimal (virgula) sau un caracter e (care înseamnă "zece la puterea X", unde X este o valoare întreagă ce urmează după caracterul e), sau atât punct zecimal cât și un caracter e: 3.14159 // 3.14159 6.02e23 // 6.02 x 10^23 1.6e-19 // 1.6 x 10^-19 3.0 // 3.0 Acestea sunt patru numere zecimale valide expimate în C++. Primul număr este PI, al doilea este numărul lui Avogadro, al treilea este încărcarea electrică a unui electron the electric charge of an electron (un număr extrem de mic) - toate aproximate -, iar ultimul este numărul trei exprimat ca valoare reală precizată. Tipul implicit pentru valorile reale precizate este double. Numerele reale de tipul float sau long double pot fi precizate adăugând următoarele sufixe: Sufix Tip f or F float l or L long double De exemplu: 3.14159L // long double 6.02e23f // float Oricare dintre literele care fac parte dintr-o constantă reală (e, f, l) pot fi scrise fie cu literă mare, fie cu literă mică, fără a avea imortanță deosebită. Caractere și valori string Caracterele și constantele de tip string sunt cuprinse între ghilimele: 'z' 'p' "Salutare, lume!" "Ce mai faci?" Primele două expresii reprezintă câte o constantă caracter iar următoarele două reprezintă câte o constantă string compuse din mai multe caractere. Observați că pentru a reprezenta un singur caracter obișnuim să îl cuprindem între apostrofuri ('), iar pentru a exprima un string (care, în general, este un șir format mai mai mult de un caracter), îl includem între ghilimele ("). Atât constantele caractere, cât și constantele string necesită apostrofuri, respectiv ghilimele, pentru a le deosebi de eventuali identificatori de variabile sau de cuvinte rezervate. Observați diferentța dintre aceste doua expresii: x 'x' Aici, x simplu s-ar putea referi la un identificator, cum ar fi numele unei variavile sau un tip de dată compus, în timp ce 'x' (cuprins între apostrofuri) s-ar putea referi la constanta caracter 'x' (caracterul care reprezintă litera mică x). Constantele caracter si string pot reprezenta, de asemenea, caratere speciale care altefe sunt dificil sau chiar imposibil de reprezentat în sursa unui program, de exemplu newline (\n) sau tab (\t). Totae aceste caractere sunt precedate de un caracter backslash (\). Aici aveți o listă cu codurile caracterelor escape: De exemplu: '\n' '\t' "Stanga \t Dreapta" "unu\ndoi\ntrei" Calculatoarele reprezintă intern carecterele prin niște coduri numerice: cel mai adesea, ele folosesc una dintre extensiile sistemului de codificare ASCII (pentru mai multe informații, vedeți ASCII code). Caracterele pot fi reprezentate ca și constante folosind codul lor numeric în octal sau hexazecimal, precedat de un caracter (\). În baza opt, caracterul backslash este urmat imediat de cifre, în timp ce pentru hexazecimal se inserează un caracter x între backslash și cifrele hexazecimale (de exemplu: \x20 sau \x4A). Mai multe constante string pot fi concatenate petnru a forma o singură constanta string doar prin separarea lor de unul sau mai multe spații, prin includerea de caractere speciale (blank) precum tab, newline. De exemplu: "Acestea formeaza" "un singur" " string " "de caractere" Mai sus este o constantă string echivalentă cu: "Acestea formează un singur string de caractere" Observați că spațiile dintre ghilimele fac parte din constantă, în timp ce spațiile din afară sunt eliminate. De asemenea, unii programatori folosesc un truc pentru a extinde constante string pe mai multe rânduri: în C++, un backslash (\) la sfârșitul liniei este considerat un caracter de continuare a liniei, care unește ceea ce este scris pe linia respectivă și pe următoarea într-o singură linie. De aceea, codul următor: x = "string exprimat pe \ doua linii" este echivalent cu: x = "string exprimat pe doua linii" Toate constantele caracter și string descrise mai sus sunt formate din caractere de tip char. Un alt tip de caracter poate fi specificat folosind unul dintre următoarele prefixe: Prefix // Tip caracter u // char16_t U // char32_t L // wchar_t Observați că, spre deosebire de sufixele pentru numere întregi, aceste prefixe sunt case sensitive: litere mici pentru char16_t și litere mari pentru char32_t și wchar_t. Pentru constante string, în afară de cele de mai sus u, U și L, există încă două prefixe: Prefix // Descriere u8 // Constanta string este codificată folosind UTF-8 R // Constanta string este un rând string În string-urile rând, caracterele backslash, ghilimele si apostrof sunt toate caractere valide; conținutul constantei este delimitat de o expresie inițială R"secventa( și una finală )secventa", unde secventa este orice secventa de caractere (inclusiv o secvență vidă). Conținutul string-ului este cuprins între paranteze, ignorându-se delimitarea secvenței. De exemplu: R"(string cu \backslash)" R"&%$(string cu \backslash)&%$" Cele două string-uri de mai sus sunt echivalente cu "string cu \\backslash". Prefixul R poate fi combinat cu orice alte prefixe, precum u, L sau u8. Alte constante precizate În C++ mai există alte trei cuvinte cheie pentru precizarea de valori: true, false și nullptr: true și false sunt două valori posibile pentru variabilele de tip bool. nullptr este valoarea pointer nul. bool foo = true; bool bar = false; int* p = nullptr; Expresii de tip constant Uneori, este mult mai convenabil să dăm un nume unei valori constante: const double pi = 3.1415926; const char tab = '\t'; Vom putea apoi să folosim numele în loc să precizăm valoarea cu care a fost definit: #include <iostream> using namespace std; const double pi = 3.14159; const char newline = '\n'; int main () { double r=5.0; // raza double cerc; cerc = 2 * pi * r; cout << cerc; cout << newline; } Rezultatul afisat va fi : 31.4159 Definiții preprocesor (#define) Alt mecanism pentru a denumi o valoare constantă folosește definițiile preprocesor. Ele au următoarea formă: #define identificator valoare După această directivă, orice apariție în cod a lui identificator este interpretată ca valoare, unde valoare este orice secvență de caractere (până la sfârșitul liniei). Această înlocuire este realizată de către preprocesor și se realizează înainte ca programul să fie compilat, deci este un fel de înlocuire ”oarbă”: validitatea tipurilor sau sintaxa implicată nu sunt verificate în niciun fel. De exemplu: #include <iostream> using namespace std; #define PI 3.14159 #define NEWLINE '\n' int main () { double r=5.0; // raza double cerc; cerc = 2 * PI * r; cout << cerc; cout << NEWLINE; } Rezultatul va fi acelasi . Observați că liniile #define sunt directive preprocesor și, deși ocupă o singură linie, spre deosebire de instrucțiunile C++, ele nu se termină cu punct și virgulă (;). Directivele se extind automat până la sfârșitul liniei. Dacă se include caracterul punct și virgulă pe acea linie, atunci el este parte din valoarea cu care se va înlocui apariția expresiei (deci va fi inclus în toate aparițiile expresiei înlocuite). Sursa: cpluscplus.com
-
- 1
-
-
Structura unui program in c++ Cel mai bun mod de a învăța un limbaj de programare este scrierea de programe. De obicei, primul program scris de începători este programul numit "Hello World", care pur și simplu printeaza "Hello World" pentru ecranul computerului. Deși este foarte simplu, el conține toate componentele fundamentale ale programelor C ++: 1.// primul meu program in C++ 2.#include <iostream> 3. 4.int main() 5.{ 6. std::cout << "Salutare, lume!"; 7. 8.} Programul va afisa : Salutare , lume! Să examinăm acest program linie cu linie: Linia 1: // primul meu program in C++ Doua semne slash indică faptul că restul liniei este un comentariu introdus de către programator, dar care nu are nici un efect asupra comportamentului programului. Programatorii le folosesc pentru a include explicații scurte sau observații cu privire la cod sau program. În acest caz, este vorba de o scurtă descriere introductivă a programului. Linia 2: #include <iostream> Liniile care încep cu un diez (#) sunt directivele de citit și interpretat de ceea ce este cunoscut sub numele de preprocesor. Acestea sunt linii speciale interpretate înainte de începerea programului în sine. În acest caz, directiva #include <iostream>, instruiește preprocesorul să includă o secțiune de cod C ++, cunoscuta ca antet-ul iostream care permite efectuarea de operațiuni de intrare și de ieșire standard, cum ar fi scrierea pe ecran a mesajului (Salutare lume). Linia 3: O linie goală. Liniile goale nu au niciun efect asupra unui program. Ele îmbunătățesc pur și simplu lizibilitatea codului. Linia 4: int main () Această linie inițiază declararea unei funcții. În esență, o funcție este un grup de instructiuni de cod caruia ii este dat un nume: în acest caz, avem numele de "principal" pentru gruparea de instructiuni care urmează. Funcțiile vor fi discutate în detaliu într-un capitol ulterior, dar, în esență, definirea acestora este introdusa ca o succesiune de tip (int), un nume(main) și o pereche de paranteze (()), care opțional poate include si parametri. Funcția numita main este o funcție specială în toate programele C ++; aceasta este funcția apelata atunci când programul este rulat. Executarea tuturor programelor C ++ începe cu funcția main, indiferent de locul în care funcția este de fapt localizata în cod. Liniile 5 si 7: { si } Acolada deschisa ({) la linia 5, indică începutul definiției funcției main, iar acolada de închidere (}) de la linia 7, indică sfârșitul ei. Tot ce este între aceste acolade formeaza corpul functiei care definește ceea ce se întâmplă atunci când se apeleaza functia principala main. Toate funcțiile folosesc acolade pentru a indica începutul și sfârșitul definițiilor lor. Linia 6: std::cout << "Salutare, lume!"; Această linie este o instrucțiune C ++. O instrucțiune este o expresie care poate produce un efect. Este partea esențială a unui program, precizând comportamentul efectiv al acestuia. Instrucțiunile sunt executate în aceeași ordine în care apar în corpul unei funcții. Această instrucțiune are trei părți: în primul rând, std::cout, care identifică dispozitivul standard de afișare (iesire = output) a caracterelor (de obicei, acest lucru este ecranul calculatorului). În al doilea rând, operatorul de inserare (<<), care indică faptul că ceea ce urmează este introdus în std::cout. În cele din urmă, o propoziție între ghilimele ("Salutare, lume!"), este ceea ce se trimite la ieșirea standard. Observați că declarația se termină cu punct și virgulă (;). Acest caracter marchează sfârșitul instrucțiunii, la fel cum punctul încheie o propoziție în limba engleză. Toate instrucțiunile C ++ trebuie să se termine cu un caracter punct și virgulă. Una dintre cele mai comune erori de sintaxă în C ++ este cand se uita terminarea unei instrucțiuni cu punct și virgulă. Poate că ați observat că nu toate liniile acestui program efectuează acțiuni atunci când se execută codul. Există o linie care conține un comentariu (începând cu //). Există o linie cu o directivă pentru preprocesor (începând cu #). Există o linie care definește o funcție (în acest caz, funcția principală main). Și, în cele din urmă, o linie cu instructiuni se termină cu punct și virgulă (folosirea lui cout), care a fost în cadrul blocului delimitat de acolade ( { } ) din funcția main. Programul a fost structurat pe diferite linii și indentate în mod corespunzător, în scopul de a-l face mai ușor de înțeles pentru oamenii care il citesc. Dar C ++ nu are reguli stricte cu privire la indentare sau cu privire la modul de împărțire a instrucțiunilor în linii diferite. De exemplu, în loc de 1.#include<iostream> 2.int main () 3.{ 4. std::cout << " Salutare, lume!"; 5.} puteam scrie : #include<iostream> int main () { std::cout << "Salutare, lume!"; } toate într-o singură linie, iar acest lucru ar fi avut exact același înțeles (pentru compilator) ca și codul precedent. În C ++, separarea dintre instrucțiuni se marcheaza cu ajutorul simbolului punct și virgulă (;) care se pune la sfarsit de instructiune, iar separarea pe diferite linii nu are nici o importanta în acest sens. Mai multe instrucțiuni pot fi scrise pe o singură linie, sau fiecare instrucțiune poate fi scrisa pe propria linie. Impartirea codului pe linii diferite servește doar pentru a-l face mai lizibil și pentru a-l schematiza pentru oamenii care il pot citi, dar nu are nici un efect asupra comportamentului real al programului. Acum, haideți să adăugăm o instrucțiune suplimentară pentru primul nostru program: // al doilea program al meu in C++ #include <iostream> int main () { std::cout << "Salutare, lume! "; std::cout << "Eu sunt un program C++."; } Programul va afisa : Salutare, lume! Eu sunt un program C++. În acest caz, programul efectuează două inserții în std::cout în două instrucțiuni diferite. Încă o dată, separarea pe diferite linii de cod, pur și simplu dă o mai mare vizibilitate la program, deoarece main ar fi putut fi perfect valabil definită si în acest fel: #include<iostream> int main () { std::cout << " Salutare, lume! "; std::cout << " Eu sunt un program C++. "; } Codul sursă ar fi putut fi, de asemenea, împărțit în mai multe linii de cod: #include<iostream> int main () { std::cout << "Salutare, lume!"; std::cout << "Eu sunt un program C++."; } iar rezultatul ar fi fost din nou exact la fel ca în exemplele precedente. Directivele preproces (cele care încep cu #) fac exceptie de la această regulă generală, deoarece acestea nu sunt instructiuni. Acestea sunt linii citite și prelucrate de către preprocesor inainte de a incepe compilarea corespunzătoare. Directivele preprocesorului trebuie să fie specificate în linia lor și, pentru că ele nu sunt instructiuni, nu trebuie să se termine cu punct și virgulă (;). Articol intreg : https://cplusplus.com/
-
- 2
-
-
//se citesc datele intr un vector . Sa se tipareasca sortat vectorul... #include <iostream> using namespace std; void citesc(int vt[10], int n) { int i; for(i=1; i<=n; i++) {cout<<"v["<<i<<"]= "; cin>>vt[i];} } void sortez(int vt[10], int n) { int i,gasit,aux; do { gasit=0; for(i=1; i<=n-1; i++) if (vt[i]>vt[i+1]) { aux=vt[i];vt[i]=vt[i+1];vt[i+1]=aux; gasit=1; } }while(gasit); // {cout<<"v["<<i<<"]= "; cin>>vt[i];} } void scriu(int vt[10], int n) { int i; for(i=1; i<=n; i++) cout<<vt[i]<<endl; } int main(void) { int n, v[30]; cout<<"Dati dimensiunile vectorului \n"; cout<<"n = ";cin>>n; citesc (v,n); sortez(v,n); scriu(v,n); }
-
#include<iostream.h> long long ack(long m, long n) { if (!m) return n+1; else if (!n) return ack(m-1,1); else return ack(m-1, ack(m,n-1)); } int main() { long long m,n; cout<<"Introduceti prima cifra: "; cin>>m; cout<<"Introduceti al doilea numar: "; cin>>n; cout<<ack(m,n); return 0; }
-
- c++
- tehnologie
-
(and 1 more)
Tagged with:
-
#include <iostream> using namespace std; int main() { int n,i,j,a[10][10],b[10][10],c[10][10]; cout<<"Introduceti gradul matricei:"; cin>>n; for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ cout<<"A["<<i<<"]["<<j<<"]="; cin>>a[i][j]; }} for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ cout<<"B["<<i<<"]["<<j<<"]="; cin>>b[i][j]; }} for(i=1;i<=n;i++){ for(j=1;j<=n;j++){ c[i][j]=a[i][j]+b[i][j]; }} for(i=1;i<=n;i++){ for(j=1;j<=n;j++) cout<<c[i][j]<<" "; cout<<endl; } return 0; }
-
- 1
-
-
- c++
- tehnologie
-
(and 1 more)
Tagged with:
-
/Sortarea prin interschimbare // se parcurge vectorul inversand continuturile elementelor alaturate care nu sunt crescatoare #include <iostream> using namespace std; int a[100], n, i,j ,k ,man, gasit ; int main() { cout<<"Dati dimensiunea tabloului n = "; cin>>n; for(i=0; i<n; i++) { cout<<"a["<<i<<"] = "; cin>>a[i]; } do { gasit=0; for(i=0; i<n-1; i++) if (a[i]>a[i+1]) { man=a[i]; a[i]=a[i+1]; a[i+1]=man; gasit=1; } } while (gasit); { cout<<"Tabloul ordonat crescator \n"; for(i=0; i<n; i++) cout<<a[i]<<" "; } }
-
- c++
- tehnologie
-
(and 2 more)
Tagged with:
-
//(metoda bulelor) Se parcurge vectorul atât timp cât mai există o pereche (a,a[i+1]) cu a > a[i+1] (adică o pereche de numere astfel încât primul să fie mai mare ca cel de-al doilea). #include<iostream> using namespace std; int a[100],n,i; void bubble_sort(int a[100], int n) // a - tabloul de numere intregi care se va ordona crescator // n - numarul de elemente al tabloului { int i,aux,inv; // variabila inv este 0 atunci cand s-a facut o interschimbare do{ inv=1; for(i=1; i<=n-1; i++) if( a[i] > a[i+1] ) { aux = a[i]; a[i] = a[i+1]; a[i+1] = aux; inv = 0; } }while( !inv ); return; } int main(void) { cout<<"Dati dimensiunea vectorului n = "; cin>>n; cout<<"Dati elementele vectorului \n"; for(i=1; i<=n; i++) { cout<<"a["<<i<<"]= "; cin>>a[i]; } bubble_sort(a,n); cout<<"Tabloul ordonat crescator \n"; for(i=1; i<=n; i++) cout<<a[i]<<" "; }
-
- 3
-
-
- tehnologie
- c++
-
(and 1 more)
Tagged with:
-
Salut, in urmatoarele randuri am sa va prezint cum se face suma cifrelor unui numar (n): #include <iostream.h> int n,s,c; void main() { cout<<„n=”; cin>>n; while(n!=0) { c=n%10; // extrag ultima cifra s=s+c; n=n/10; // tai ultima cifra } cout<<„Suma cifrelor=”<<s; }
-
- 3
-
-
- tehnologie
- stiri
-
(and 3 more)
Tagged with:
-
Salutare, #include<iostream> #include<math.h> #include<conio.h> using namespace std; int main () { float MediaAritmetica; int x, nr, suma; suma=0; nr=1; cout<<"Dati numarul x= "; cin>>x; while(x!=0) { suma=suma+x; nr++; cout<<"Dati numarul x= "; cin>>x; } nr--; MediaAritmetica=suma/nr; cout<<"Media aritmetica este egal cu:"<<MediaAritmetica; return 0; _getch(); }
-
- 2
-
-
- c++
- tehnologie
-
(and 2 more)
Tagged with: