• Like 1
  • Ador 1
Sari la conținut

NOT a MERCEDES

Members
  • Număr conținut

    81
  • Înregistrat

  • Ultima Vizită

  • Country

    Romania

Orice postat de NOT a MERCEDES

  1. ** INTRODUCERE IN VARIABILE STATICE ** Variabilele Statice sunt variabile locale care isi mentin valoarea si daca ies din context . Practic , valorile statice isi pot pastra valoarea la fiecare iteratie a unei bucle sau la apelul unei functii . Ele se initializeaza astfel : static <tip_date> <numele_variabilei>; // Daca nu sunt initializate , sunt atribuite implicit cu valoarea 0 ! Exemplu de efect al variabilelor statice : for (int index = 0; index < 10; index++) { static int i; // Declaram o variabila statica int j = 0; // Declaram o variabila normala cout << "i : " << i << " | " << "j : " << j << endl; // Post Incrementam ambele variabile cu += 1 i++; j++; } Vom avea ca rezultat : i : 0 | j : 0 i : 1 | j : 0 i : 2 | j : 0 i : 3 | j : 0 i : 4 | j : 0 i : 5 | j : 0 i : 6 | j : 0 i : 7 | j : 0 i : 8 | j : 0 i : 9 | j : 0 REZUMAT ** : Variabila "i" (statica) isi PASTREAZA valoarea la fiecare iteratie (sau la iesirea din context) spre deosebire de variabila j (normala) . De asemenea , pot exista functii statice : static int getStaticValue() { static int i; return i++; } int getNonStaticValue() { int j = 0; return j++; } int main() { for (int index = 0; index < 10; index++) { cout << "i : " << getStaticValue() << " | " << "j : " << getNonStaticValue() << endl; } return 0; } /* rezultat : i : 0 | j : 0 i : 1 | j : 0 i : 2 | j : 0 i : 3 | j : 0 i : 4 | j : 0 i : 5 | j : 0 i : 6 | j : 0 i : 7 | j : 0 i : 8 | j : 0 i : 9 | j : 0 */ ** Integrare Membrii Statici in Paradigma Orientata Pe Obiecte ** Pe scurt , membrii statici isi pastreaza valoarea intre instante . Practic , ele au aceeasi valoare indiferent de instanta !! class Demo { private: // Declaram doua variabile int j; static inline int i; // inline e valabil pentru C++ 17 in sus public: Demo(int index) { j = index; i = index; } // Setam niste getteri static inline const int getI() { return i; } int const getJ() { return j; } // NOTA ** : Membrii Statici necesita "o dubla initializare" . Din acest motiv , folosim "inline" !! VALABIL DOAR PENTRU C17++ IN SUS !! }; int main() { // Instantiem O Colectie de Pointeri Demo** arrOfDemo = new Demo * [10]; for (int i = 0; i < 10; i++) { arrOfDemo[i] = new Demo(i); // Instantiem 10 obiecte de tip Demo cu i diferit } // Printam Obiectele for (int i = 0; i < 10; i++) { // Accesam i si j de la fiecare instanta cout << "Obiectul " << i << " : i = " << arrOfDemo[i]->getI() << " | " << "j : " << arrOfDemo[i]->getJ() << endl; } // Eliberam memoria ocupata de instante for (int i = 0; i < 10; i++) { delete arrOfDemo[i]; // Eliberam fiecare Instanta in parte } // Eliberam colectia si o punem pe null !! delete[] arrOfDemo; arrOfDemo = nullptr; return 0; } /* Rezultatul : Obiectul 0 : i = 9 | j : 0 Obiectul 1 : i = 9 | j : 1 Obiectul 2 : i = 9 | j : 2 Obiectul 3 : i = 9 | j : 3 Obiectul 4 : i = 9 | j : 4 Obiectul 5 : i = 9 | j : 5 Obiectul 6 : i = 9 | j : 6 Obiectul 7 : i = 9 | j : 7 Obiectul 8 : i = 9 | j : 8 Obiectul 9 : i = 9 | j : 9 // Diferenta se remarca prin faptul ca valoarea statica (i) isi pastreaza aceeasi valoare la fiecare instanta spre deosebire de cea non - statica (j) care e dependenta de obiect !! */ NOTA ** : Vom discuta in tutorialele ce urmeaza , mai in detaliu despre acesti membrii !!!
  2. ** Ce reprezinta si importanta procedeului de sortare ** Sortarea , a unei colectii , reprezinta procedeul prin care accesam si modificam POZITIA elementelor asociate acesteia , pe baza unui criteriu . De exemplu , putem ordona de la mic la mare (intr-o colectie de numere), de la A la Z (intr-o colectie de siruri de caractere) etc. Sortarea se poate efectua sub mai multe procedee , unul mai optim decat altu din punct de vedere , a timpului de executie si a resurselor alocate . Nota ** : Definim colectie orice entitate care contine o multime de elemente (array,lista,arbore etc.) ; ** In ce Consta Sortarea Prin Selectie ** Sortarea Prin Selectie se bazeaza pe doua bucle , una care acceseaza toate elementele colectiei iar cealalta , in interiorul acesteia , care compara repetitiv un element cu restul . Daca in comparatie, se gaseste un element mai mic acesta , se va efectua o interschimbare intre acestia. ** Exemplu Selectie prin Sortare ** Sa presupunem ca avem 6 numere naturale intr o colectie [44 , 22, 67, 23 , 21, 11] --> NUMERE NATURALE [0 , 1 , 2 , 3 , 4 , 5 ] --> INDECSI EFECTUAM O SORTARE A COLECTIEI DE LA MARE LA MIC : Prima Iteratie : i = 0 ; 1. 44 > 22 --> 44 mai mare decat 22 --> nu efectuam nimc --> continuam ; 2. 44 < 67 --> 44 mai mic decat 67 --> efectuam interschimbarea --> [67 , 22 , 44 , 23 , 21 , 11] ; 3. 67 > 23 --> 67 mai mare decat 23 --> nu efectuam nimc --> continuam ; 4. 67 > 21 --> 67 mai mare decat 21 --> nu efectuam nimic --> continuam ; 5. 67 > 11 --> 67 mai mare decat 11 --> nu efectuam nimic --> continuam . A doua iteratie : i = 1 ; 1. 22 < 44 --> 22 mai mic decat 44 --> efectuam interschimbarea --> [67 , 44 , 22 , 23 , 21 , 11] ; 2. 44 > 23 --> 44 mai mare decat 23 --> nu efectuam nimc --> continuam ; 3. 44 > 21 --> 44 mai mare decat 21 --> nu efectuam nimc --> continuam ; 4. 44 > 11 --> 44 mai mare decat 11 --> nu efectuam nimc --> continuam . A treia iteratie : i = 2 ; 1. 22 < 23 --> 22 mai mic decat 23 --> efectuam interschimbarea --> [67, 44 , 23 , 22 , 21 , 11] ; 2. 23 > 21 --> 23 mai mare decat 21 --> nu efectuam nimc --> continuam ; 3. 23 > 11 --> 23 mai mare decat 11 --> nu efectuam nimc --> continuam . A patra iteratie : i = 3 ; 1. 22 > 21 --> 23 mai mare decat 21 --> nu efectuam nimc --> continuam ; 2. 22 > 11 --> 22 mai mare decat 11 --> nu efectuam nimic --> continuam . A cincea iteratie : i = 4 ; 1. 21 > 11 --> 21 mai mare decat 11 --> nu efectuam nimic --> continuam . FINAL ALGORITM Algoritmul sortat de la mare la mic : [67, 44 , 23 , 22 , 21 , 11] NOTA ** : Pentru la mic la mare , doar inversam comparatia !!! Procedeul e acelasi !! ** Algoritm in C ** #include <stdio.h> #include <stdlib.h> // Pentru malloc & free void selectionSorting(int** arr , int arrayBuffer) { for (int i = 0; i < arrayBuffer - 1; i++) // Traversam toata colectia mai putin ultinmul element { for (int j = i + 1; j < arrayBuffer; j++) { if ((*arr)[i] < (*arr)[j]) // "<" PENTRU NUMERE DESCRESCATOARE IAR ">" PENTRU NUMERE CRESCATOARE { // Efectuam Algoritmul de Inteschimbare int temp = (*arr)[i]; (*arr)[i] = (*arr)[j]; (*arr)[j] = temp; } // Daca nu , continuam } } } int main() { int arrayBuffer; printf("Cate numere doresti sa aiba colectia : "); scanf_s("%d", &arrayBuffer); int* a = (int*)malloc(arrayBuffer * sizeof(int)); // ALOCAM UN ARRAY IN FUNCTIE DE CATE NUMERE VREA UTILIZATORUL SA INTRODUCA printf("Insereaza %d numere la intamplare : \n",arrayBuffer); for (int i = 0; i < arrayBuffer; i++) { printf("colectie[%d] = ", i); scanf_s("%d", &a[i]); // Inseram numerele de la tastatura } selectionSorting(&a,arrayBuffer); // Transferam colectia prin adresa /// Printam Colectia printf("Printam colectia ordonata : \n"); for (int i = 0; i < arrayBuffer; i++) { printf("v[%d]=%d\n", i, a[i]); } // Eliberam Memoria Ocupata de Array (Sa prevenim Memory Leak) free(a); // Eliberam Colectia in sine a = NULL; // Setam NULL Pointer return 0; } NOTA 1 ** : E USOR DE IMPLENTAT SI INTELES , IDEAL UNDE SE LUCREAZA CU LISTE MICI SI SIMPLITATEA E NECESARA !! NOTA 2 ** : CU CAT LISTA ESTE MAI MARE , CU ATAT VOM AVEA O COMPLEXITATE TIMP MAI MARE (MAI INEFICIENT) !!
  3. ** Algoritm de Cautare Binar ** Este un algoritm de cautare utilizat intr-o colectie SORTATA , ne ofera posibilitatea de a miscora timpul de executie (Complexitate Timp mai optim) prin divizarea repetata a intervalelor la jumatate . ** Explicatie ** Sa presupunem ca avem o colectie de 10 numere (SORTATA) : [11 , 22 , 34 , 56 , 65 , 76 , 78 , 84 , 96 , 98] Si dorim sa aflam daca exista numar 78 in colectie si la ce index : APLICAM ALGORITMUL :: --> AFLAM INDEX-UL CARE-I CORESPUNDE NUMARULUI DIN MIJLOCUL INTERVALULUI : (9+0)/2 = 4.5 ==> 5 ==> Verificam daca a[5] = 76 este echivalent cu 78 ==> DIFERIT CONTINUAM ALGORITMUL ; --> CUNOASTEM FAPTUL CA 78 > 76 ASA CA VOM STII CA NUMARUL CAUTAT SE AFLA IN INTERVALUL DIN DREAPTA [76 , 78 , 84 , 96 , 98 ] --> AFLAM INDEXUL CAREI CORESPUNDE NUMARUL DIN MIJLOCUL INTERVALULUI : (5+9)/2 = 14/2 = 7 (indexul din mijloc) ==> Verificam daca a[7] = 84 este echivalent cu 78 ==> DIFERIT CONTINUAM ALGORITMUL ; --> CUNOASTEM FAPTUL CA 84 > 78 ASA CA VOM STII CA NUMARUL CAUTAT SE AFLA IN INTERVALUL DIN STANGA [ 76 , 78 , 84 ] --> AFLAM INDEXUL CAREI CORESPUNDE NUMARUL DIN MIJLOCUL INTERVALULUI : (5+7)/2 = 6 (Indexul din mijloc) ==> verficam daca [a6] = 78 = este echivalent cu 78 ==> AM GASIT ELEMENTU , INTRERUPEM ALGORITMUL CU SUCCES !! ** Interpretare in Cod C ** : #include <stdio.h> #include <stdlib.h> // Pentru malloc & free int main() { int arrayBuffer; printf("Cate numere doresti sa aiba colectia : "); scanf_s("%d", &arrayBuffer); int* a = (int*)malloc(arrayBuffer * sizeof(int)); // ALOCAM UN ARRAY IN FUNCTIE DE CATE NUMERE VREA UTILIZATORUL SA INTRODUCA printf("Insereaza %d numere in sir crescator : \n",arrayBuffer); for (int i = 0; i < arrayBuffer; i++) { printf("colectie[%d] = ",i); scanf_s("%d", &a[i]); // Inseram numerele de la tastatura } int numberToSearch, found = 0, index; do { printf("Insereaza numarul pe care vrei sa l cauti in colectie : "); scanf_s("%d", &numberToSearch); int leftIndex = 0, RightIndex = arrayBuffer - 1; // Aflam Primul Si Ultimul Index // LE AM INITIALIZAT IN AFARA LOOPULUI PENTRU A SI PASTRA VALOAREA LA FIECARE ITERARE !!! do { int mid = (leftIndex + RightIndex) / 2; // Aflam Indexul Din Mijlocul Intervalului if (a[mid] == numberToSearch) // Comparam Cu Mijlocul { // Daca Am gasit numarul index = mid; // Preluam Indexul found = 1; break; } else if(a[mid] < numberToSearch) { // DACA NUMARUL CAUTAT ESTE MAI MARE DECAT MIJLOCUL leftIndex = mid; // Vom Cauta in Continuare de la Mijloc Spre Dreapta } else { // DACA NUMARUL CAUTAT ESTE MAI MIC DECAT MIJLOCUL RightIndex = mid; } } while (leftIndex <= RightIndex); printf("\n"); } while (found == 0); printf("Am gasit elementul %d la pozitia %d", numberToSearch, index); // Eliberam Memoria Ocupata de Array (Sa prevenim Memory Leak) free(a); // Eliberam Colectia in sine a = NULL; // Setam NULL Pointer return 0; } NOTA 1 ** : ALGORITM INEFICIENT IN CAZUL COLECTIILOR DEZORDONATE (NESORTATE) !!! Explicatie : Sa presupunem ca avem o colectie de 10 numere (NESORTAT) : [98 , 33 , 22 , 11 , 65 , 55 , 44 , 78 , 45 , 99] Si dorim sa aflam daca exista numarul 44 in colectie si la ce index : Aplicam Algoritmul : 1. mid = (0+9)/2 = 4.5 a[5] = 55 diferit de 44 ==> 55 > 44 ==> CAUTAM IN INTERVALUL DIN STANGA [98 , 33 , 22 , 11 , 65 , 55] NU L GASIM PE 44 IN ACEST INTERVAL !! ==> ALGORITMUL ESUEAZA NOTA 2 ** : FOARTE BUN DACA AVEM O COLECTIE MARE DE DATE , SCUTINDU NE DE A CAUTAT FIECARE ELEMENT !! (CU CONDITIA DE A FI ORDONAT)
  4. ** Analiza Algoritmilor ** Algoritmii sunt modalitati de identificare si rezolvare a unei sau mai multe probleme . In rezolvarea unei probleme , pot exista mai multe solutii dar unele pot fi mai eficiente sau nu . Eficacitatea unui algoritm este masurata in TIMP SI SPATIU . * TIMPUL CONSTA IN PERIOADA DE EXECUTIE A ALGORITMULUI . CU CAT TINDE SPRE 0 , cu atat este mult mai eficient din acest aspect !! * SPATIUL CONSTA IN RESURSELE ALOCATE IN EXECUTAREA ALGORITMULUI . CU CAT SPATIUL ESTE MAI MIC , CU ATAT ALGORITMUL ESTE MAI EFICIENT !! ** Introducere in Algoritmii de Cautare ** Algoritmii de cautare reprezinta modalitati diferite de rezolvare a problemei privind cautarea unui element sau mai multe , intr-o colectie (array,liste,arbori etc.) . Importanta algoritmilor de cautare : Ne ajuta la cautarea unui produs sau persoana , dupa preferintele noastre , de pe un site de e-commerce sau social media (persoana) ; Ne ajuta in diferite sisteme de recunoastere vocala , faciala etc. ; Ne ajuta sa cautam relevant intr o baza de date ; Ne ajuta la aflarea rutei optime dintr - o retea etc. ** Algoritmul de Cautare Liniar ** Cautarea Liniara reprezinta cea mai usoara modalitate de a descoperi un termen dintr- o colectie . Ea consta in verificarea fiecarui element in parte , de la un cap la celalalt . Explicatie : Definim o colectie de 10 numere . Sa cautam termenul 30 in colectie : [40 , 50 , 35 , 60 , 70 , 78 , 30 , 10 , 5 , 12] Navigam prin colectie si luam la comparatie fiecare numar (de la cifra 40 pana la 30) 40 diferit de 30 ==> mergem la urmatorul 50 diferit de 30 ==> mergem la urmatorul 35 diferit de 30 ==> mergem la urmatorul 60 diferit de 30 ==> mergem la urmatorul 70 diferit de 30 ==> mergem la urmatorul 78 diferit de 30 ==> mergem la urmatorul 30 egal cu 30 ==> TERMEN GASIT , OPRIM ALGORITMUL !!! Interpretare algoritm in C : #include <stdio.h> int main() { int a[10]; printf("Insereaza 10 numere : \n"); for (int i = 0; i < 10; i++) { printf("colectie[%d] = ",i); scanf_s("%d", &a[i]); // Inseram numerele de la tastatura } int numberToSearch, found = 0, index; do { printf("Insereaza numarul pe care vrei sa l cauti in colectie : "); scanf_s("%d", &numberToSearch); for (int i = 0; i < 10; i++) // Navigam prin colectie { if (numberToSearch == a[i]) // Cautam secvential prin toata colectia si comparam cu fiecare individ { // DACA S -A IMPLINIT CONDITIA DE MAI SUS found = 1; // Am gasit elementul index = i; // Salvam indexul break; // Intrerupem bucla !! } } printf("\n"); } while (found == 0); printf("Am gasit elementul %d la pozitia %d", numberToSearch, index); return 0; } NOTA 1 ** : Algoritmul devine mai ineficient cu cat elementul cautat este mai aproape de capat (TIMPUL DE EXECUTIE DEVINE DIN CE IN CE MAI MARE !!) NOTA 2 ** : NU SE RECOMANDA ACEST ALGORITM DE CAUTARE CAND AVEM DE A FACE CU COLECTII DE MARI DIMENSIUNI SAU ORDONATE !!!
  5. ** Constructor cu Argumente (Parametrii) ** Constructorul sau Constructorii cu parametrii sunt metode care ne permit sa avem instante (obiecte) unice in functie de parametrii luati . De asemenea , pot exista si impreuna cu constructorul implicit . Reconstruim clasa de la tutorialul trecut (cu constructorul implicit) + functia de alocare a sirurilor de caractere : void atribuireSirCaractere(char** target, const char* source) { size_t bufferString = strlen(source) + 1; *target = new char [bufferString]; strcpy_s(*target, bufferString, source); } class Utilizator { public : // Punem enumul pe public deoarece trebuie sa l accesam din exterior enum class type { // Tip de Utilizator MEMBER, PREMIUM, MODERATOR, ADMIN }; private: // Sector Privat (Membrii aflati la acest nivel de acces NU pot fi accesati unsigned id; // Numar Natural char* username; // String char* email; // String char* password; // String unsigned nrPosts; // Numar Natural bool isForbidden; // Banat sau NU type userType; // Tip Utilizator public: // Sector Public (Membrii aflati la acest nivel de acces POT FI ACCESATI) Utilizator() { /// Definitie Constructor fara parametrii (argumente) //// Definim Stringurile pe care le dorim sa le atribuim campurilor // Initializam campurile statice id = 0; nrPosts = 0; isForbidden = false; userType = type::MEMBER; // Member by Default // Atribuire Nume de Utilizator atribuireSirCaractere(&username, "Vasile"); // Atribuire Nume atribuireSirCaractere(&email, "vasile79@gmail.com"); // Atribuire Email atribuireSirCaractere(&password, "vasileParola"); } // Definim Getteri const unsigned _getIdUser() { return id; } const char* const _getUsername() { return username; } const char* const _getEmail() { return email; } const char* const _getPassword() { return password; } const unsigned _getNrPosts() { return nrPosts; } const bool _isForbidden() { return isForbidden; } const type _getType() { return userType; } }; NOTA ** : Am adaugat trei campuri noi ("isForbidden","NrPosts" si "TypeUser") sa devina mai interesant ; Acum in clasa respectiva , vom adauga 4 constructori cu paramatrii : Utilizator(unsigned _id,type _userType) { // Constructor care preia ca argument ID-ul si tipul de user ; id = _id; // Atribuim id-ul din argumentul preluat userType = _userType; // Atribuim tipul din argumentul preluat // Restu e implicit isForbidden = false; nrPosts = 0; atribuireSirCaractere(&username, "Vasile"); // Atribuire Nume atribuireSirCaractere(&email, "vasile79@gmail.com"); // Atribuire Email atribuireSirCaractere(&password, "vasileParola"); } Utilizator(unsigned _id, const char* _username,type _userType) // Al doilea Constructor cu id si nume preluat { // Atribuire cu argumente preluate id = _id; atribuireSirCaractere(&username, _username); userType = _userType; // Restu Implicit isForbidden = false; nrPosts = 0; atribuireSirCaractere(&email, "vasile79@gmail.com"); // Atribuire Email atribuireSirCaractere(&password, "vasileParola"); // Atribuire Parola A } Utilizator(unsigned _id, const char* _username , const char* _email , const unsigned _nrPosts) // Al treilea Constructor cu id , nume , email preluat si numar posturi { // Atribuire cu argumente preluate id = _id; atribuireSirCaractere(&username, _username); atribuireSirCaractere(&email, _email); // Atribuire Email nrPosts = _nrPosts; // Atribuire cu argumente default atribuireSirCaractere(&password, "vasileParola"); // Atribuire Parola A userType = type::MEMBER; // Atribuire Tip Utilizator isForbidden = false; } /// Constructor care preia toate argumentele Utilizator(unsigned _id, const char* _username, const char* _email, const char* _password,const unsigned _nrPosts,const bool _isForbidden,type _userType) { // Atribuire cu argumente preluate id = _id; nrPosts = _nrPosts; isForbidden = _isForbidden; userType = _userType; atribuireSirCaractere(&username, _username); // Atribuire Nume Utilizator atribuireSirCaractere(&email, _email); // Atribuire Email atribuireSirCaractere(&password, _password); // Atribuire Parola } NOTA ** : PUTEM FACE CATI CONSTRUCTORI CU PARAMETRII DORIM NOI !! (TOTUSI E RECOMANDAT DOAR CE E STRICT NECESAR) Pentru a putea afisa un enum ca sir de caractere , avem nevoie de un adaptor in interiorul clasei : static const char* typeUser(type userType) // O Folosim la nivel static { switch (userType) { case type::ADMIN: return "Administrator"; break; case type::MODERATOR: return "Moderator"; break; case type::PREMIUM: return "Utilizator Premium"; break; default: return "Utilizator Simplu"; break; } } NOTA ** : L am notat cu "static" deoarece functia nu depinde de campurile instantei !! Vom discuta in tutorialele ce urmeaza despre membrii statici , in detaliu !! Totodata , construim o alta functie in interiorul clasei care sa ne afiseze datele (Cu scopul de a nu repeta cod aiurea ): void toString(){ // Interfata de afisare a fiecarui obiect cout << _getIdUser() << " | " << _getUsername() << " | " << _getEmail() << " | " << _getPassword() << " | " << _isForbidden() << " | " << _getNrPosts() << " | " << typeUser(_getType()) << endl; } Acum , trecem in functia main si instantiem 5 obiecte (1 cu constructor default si 4 cu parametrii ) : int main() { Utilizator vasileEntitate1; // Instantiat cu Constructorul Default (Implicit) // Afisam Campurile : ID | USERNAME | EMAIL | PASSWORD vasileEntitate1.toString(); Utilizator vasileEntitate2(1,Utilizator::type::MEMBER); // Instantiere Prim Constructor vasileEntitate2.toString(); Utilizator ionEntitate(2, "Ion", Utilizator::type::PREMIUM); // Instantiere Al Doilea Constructor ionEntitate.toString(); Utilizator alinEntitate(3, "Alin", "alin21332@gmail.com" ,50); // Instantiere Al Treilea Constructor alinEntitate.toString(); Utilizator georgeEntitate(4, "George", "george21332@gmail.com", "georgeParola" , 80 , false,Utilizator::type::ADMIN); // Instantiere Al Treilea Constructor georgeEntitate.toString(); return 0; } Si primim ca rezultat : 0 | Vasile | vasile79@gmail.com | vasileParola | 0 | 0 | Utilizator Simplu 1 | Vasile | vasile79@gmail.com | vasileParola | 0 | 0 | Utilizator Simplu 2 | Ion | vasile79@gmail.com | vasileParola | 0 | 0 | Utilizator Premium 3 | Alin | alin21332@gmail.com | vasileParola | 0 | 50 | Utilizator Simplu 4 | George | george21332@gmail.com | georgeParola | 0 | 80 | Administrator
  6. ** Importanta Constructori ** Constructorii sunt metode care NU returneaza un tip de date , pot detine parametrii sau nu, si sunt utilizati pentru initializarea si alocarea dinamica a campurilor unei clase . Asemenea , ei poarta numele clasei si se declanseaza la instantierea clasei !!! ** Constructor fara Parametrii ** Constructorul fara Parametrii sau Implicit (Default) este un constructor fara argumente , el se declanseaza daca nu oferim parametrii la instantiere . Construim o functie in afara clasei care ne permite alocarea si atribuirea pentru fiecare sir de caractere : void atribuireSirCaractere(char** target, const char* source) // Luam ca argument sirul de caracter pe care dorim sa l initializam dar si valoarea pe care dorim sa o atribuim // Nota ** : char** pentru ca dorim sa efectuam o modificare a argumentului { size_t bufferString = strlen(source) + 1; // Aflam numarul de caractere pe care l are sursa + 1 bit (pentru caracterul terminal) *target = new char [bufferString]; // Alocam Targetul in functie de "bufferstring" strcpy_s(*target, bufferString, source); /// Atribuim targetul cu sursa } Construim clasa "Utilizator" cu campurile "id , username , emal , password " : class Utilizator { private: // Sector Privat (Membrii aflati la acest nivel de acces NU pot fi accesati) unsigned id; // Numar Natural char* username; // String char* email; // String char* password; // String }; Definim un costructor fara parametrii cu rolul de a atribui acele campuri private : class Utilizator { public: // Sector Public (Membrii aflati la acest nivel de acces POT FI ACCESATI) Utilizator() { /// Definitie Constructor fara parametrii (argumente) // Initializam campurile id = 0; // O initializam cu o valoare default // Atribuire Stringuri de Caractere (Accesam functia de mai sus) /* Astfel ca : username , email , password --> sunt targeturi (transferate prin adresa, continutul acestor pointeri se poate schimba la apelul functiei) Celalalte valori (al doilea parametru al functiei) sunt siruri de caractere constante (transferate prin valoare deoarece ne intereseaza sa atribuim targetul cu aceste valori) !! */ atribuireSirCaractere(&username, "Vasile"); // Atribuire Nume atribuireSirCaractere(&email, "vasile79@gmail.com"); // Atribuire Email atribuireSirCaractere(&password, "vasileParola"); // Atribuire Parola } }; Definim getteri pentru accesa campurile in functia main : // Definim Getteri // Functii Constante deoarece ne intereseaza doar sa citim valorile !!! const unsigned _getIdUser() { return id; } const char* const _getUsername() { return username; } const char* const _getEmail() { return email; } const char* const _getPassword() { return password; } Construim doua entitati de utilizator ("vasileEntitate1" , respectiv "vasileEntitate2") si afisam continutul acestora : int main() { Utilizator vasileEntitate1; // Instantiez + Declansam constructorul fara parametrii // Afisam Campurile : ID | USERNAME | EMAIL | PASSWORD cout << vasileEntitate1._getIdUser() << " | " << vasileEntitate1._getUsername() << " | " << vasileEntitate1._getEmail() << " | " << vasileEntitate1._getPassword() << endl; Utilizator vasileEntitate2; // Instantiem alt obiect dar Declansam acelasi constructor cout << endl; /// VOM AVEA ACELASI REZULTAT cout << vasileEntitate2._getIdUser() << " | " << vasileEntitate2._getUsername() << " | " << vasileEntitate2._getEmail() << " | " << vasileEntitate2._getPassword() << endl; return 0; } NOTA ** : VOM OBSERVA CA AMBELE ENTITATI LA APELUL CONSTRUCTORULUI IMPLICIT , NE FURNIZEAZA ACELEASI DETALII !!
  7. Corect , e o abordare buna atunci cand NU cunoastem dimensiunea acelui array . Practic , impartim numarul total de biti alocat pentru array la numarul alocat pentru fiecare unitate individuala (prima unitate are acelasi spatiu alocat ca al doilea , al treilea etc. Multumesc pentru completare !
  8. ** Tablouri de Dimensiune ** Tablouri de Dimensiune sau "Arrays" sunt tipuri de date compuse care au abilitatea de a stoca una sau mai multe valori . Asemenea putem stoca mai multe tipuri de date . (int , float ,char , pointeri chiar etc.) De exemplu : #include <stdio.h> int main() { int a[3] = { 0,1,2}; // Initializare Array cu 3 elemente for (int i = 0; i < 3; i++) { printf("%d | ", a[i]); // AFISARE CELE TREI ELEMENTE : a[0] , a[1] , a[2] } return 0; } NOTA 1 ** : Indexul primul element din array va fi intotdeauna 0 , cel putin in limbajele comune C/C++ , C# , Java etc. Astfel daca : int a[3] = {1 , 2 , 3} ; printf("%d" , a[1]); // Vom AFISA VALOAREA 2 , NICIDECUM 1 . PENTRU CA CEREM SA ACCESAM AL DOILEA ELEMENT /* a[n] --> n oricare numar natural o fi {1 , 2 , 3 , 4 , 5 , 6 , .... , n } ---> Valori [0 , 1 , 2 , 3 , 4 , 5 , .... , n-1] ---> Index (Incepe de la 0 si se termina la (n-1) ) Defapt Index e un sir de crescator de numere naturale */ NOTA 2 ** : ATENTIE , putem, din neatentie , sa accesam zone de memorie invalide . Astfel ca : #include <stdio.h> int main() { int a[3] = { 0,1,2}; // Initializare Array cu 3 elemente for (int i = 0; i <= 3; i++) { printf("%d | ", a[i]); // VOM AVEA O EROARE LA ACCESAREA LUI a[n] } /* {0 , 1 , 2 } -> valorile lui a [a[0] ,a[1] , a[2]] -> indexurile lui a iar noi incercam prin loop sa accesam a[3] care nu exista !!! */ return 0; } De asemenea , putem modifica valorile corespondete tabloului #include <stdio.h> int main() { int a[3] = { 0,1,2}; // Initializare Array cu 3 elemente for (int i = 0; i < 3; i++) { printf("%d | ", a[i]); // 0 , 1 , 2 } printf("\n"); /// Modificam valorile tabloului for (int j = 5 , i = 0 ; i < 3; (j += 2) , (i++)) // i = 0 , 1 , 2 ; j = 5 , 7 , 9 { a[i] = j; // a[0] = 5 ; a[1] = 7 ; a[2] = 9 } // Printam noul array for (int i = 0; i < 3; i++) { printf("%d | ", a[i]); // 5 , 7 , 9 } return 0; }
  9. ** POINTERI NULI SAU INVALIZI ** * In programare , vor exista situatii cand declaram dinamic o variabila , o folosim iar dupa va trebui sa o eliberam din memorie . In acest context (dupa eliberare) , pointerul respectiv devine INVALID si poate produce o eroare de tip runtime (In timpul rularii programului) daca acesta este accesat accidental . #include <stdio.h> #include <stdlib.h> // Pentru alocare dinamica int main() { int* pointer; pointer = (int*)malloc(sizeof(int)); // Alocam in memorie o variabila de tip intreg // VOM DISCUTA ULTERIOR DESPRE ALOCARE DINAMICA IN DETALIU *pointer = 30; // Atribuim numarul 30 ; printf("%i\n", *pointer); // Afisam 30 OK free(pointer); // Eliberam memoria ==> *pointer devine invalid printf("%i", *pointer); // EROARE ==>> *Pointer DEVINE DAGGLING return 0; } * In astfel de situatii , apelam la pointer nuli . Practic atribuim valoarea "null" acelui pointer !! pointer = NULL; // DUPA ELIBERAREA MEMORIEI SE RECOMANDA sa fie atrebuit cu NULL // SAU CHIAR LA INITIALIZARE NOTA ** : SE RECOMANDA CA POINTERI CARE NU POINTEAZA UN OBIECT VALID LA INCEPUT , SA FIE NOTATI CU NULL !! ** Pointeri Constanti ** * Pointeri constanti sunt pointeri a carora adresa nu se poate modifica dupa initializare . Pot pointa atat valori modificabile (atat variabile cat si constante) . #include <stdio.h> int main() { int a = 100; // Variabila int b = 50; // Constanta (NU SE POATE MODIFICA VALOAREA) int* const c = &a; // Pointer Constant pointeaza o variabila const int* const d = &b; // Pointer Constant pointeaza o constanta // EROARE DACA INCERCAM SA FACEM "c = &b" sau "d = &a" pentru ca nu putem schimba adresa de memorie // A DOUA SITUATIE *c = 30; // E OK (PUTEM SCHIMBA TOTUSI VALOAREA PENTRU CA POINTEAZA O VARIABILA) // *d = 30; /// EROARE NU PUTEM MODIFICA VALOAREA DEOARECE POINTAM O CONSTANTA printf("%d || %d ", *c , *d); // Afisam 30 | 50 return 0; } * Pointeri care pointeaza valori constante NU SI POT MODIFICA VALOARE DAR SPRE DEOSEBIRE DE POINTERI CONSTANTI ISI POT MODIFICA ADRESA DE MEMORIE #include <stdio.h> #include <stdlib.h> // Pentru alocare dinamica int main() { const int a = 50; const int* ptr = &a; printf("%d \n", *ptr); // Afisam 50 (CONSTANTA A) /// *ptr = 100; // NU PUTEM MODIFICA VALOAREA POINTERULUI CARE POINTEAZA O VALOARE CONSTANTA // Totusi spre deosebire de pointeri constanti putem schimba adresa de memorie !!!! // astfel ca const int b = 100; ptr = &b; // E OK , PUTEM SCHIMBA ADRESA DE MEMORIE printf("%d", *ptr); // AFISAM CONSTANTA B (100) return 0; }
  10. ** Introducere in Pointeri ** * Pointeri reprezinta variabile compuse care retin adresa altor variabile . * Ei sunt folositi pentru alocarea dinamica a variabilelor dar si pentru transferul parametrilor (functii) prin referinta . (Daca dorim sa modificam parametrii in subprogram) ; * Este un concept solid gasit doar in C/C++ (si partial in C#) deoarece pot duce la situatii complexe si erori , daca nu sunt gestionati cum trebuie ; ** Operatorul "&" ** * Operatorul '&' , insotit de oricare variabila , ne furnizeaza locatia de memorie a acesteia . * Spre exemplu : #include <stdio.h> int main() { int variabila; // Declaram o variabila de tip intreg printf("%p", &variabila); // Afisam adresa de memorie a acestei variabile return 0; } * Primim ca output locatia de memorie : * NOTA : Prin acest operator , pointerul poate obtine adresa de memorie a variabilei pe care o pointeaza . ** Operatorul '*' ** * Operatorul '*' , insotit de numele variabilei si tipul de date , ne indica o variabila de tip pointer ; int* pointer; // Declaratie variabila de tip pointer (Poate stoca adresa de memorie a altei variabile de tip int ) * Operatorul '*' poate fi interpretat si ca operatorul de referentiere astfel ca putem obtine valoarea adresei pe care o pointeaza : #include <stdio.h> int main() { int variabila = 100 , *variabilePointer; // Declaram o variabila de tip intreg si un pointer de tip intreg variabilePointer = &variabila; // Obtinem adresa de memorie a variabilei (Pointam "variabila") printf("%d", *variabilePointer); // Afisam valoarea variabilei return 0; } * Si obtinem in output valoarea variabilei : * Daca efectuam modificari pe valoarea stocata de variabila Pointeri se va modifica asemenea si valoarea variabilei simple !!! #include <stdio.h> int main() { int variabila = 100 , *variabilePointer; // Declaram o variabila de tip intreg si un pointer de tip intreg variabilePointer = &variabila; // Obtinem adresa de memorie a variabilei *variabilePointer = 50; // Modificam valoarea variabilei POINTER printf("%d", variabila); // Obtinem 50 deoarece pointerul stocheaza adresa de memoriei a variabilei automat se va modifica si valoarea !!! return 0; } ** Dimensiunea in memorie a pointerilor ** * Indiferent de tipul de date pe care l poate stoca , pointerul ocupa in memorie 4 biti (arhitectura x86 - 32 biti) sau 8 biti (arhitectura x64 - 64 biti) #include <stdio.h> int main() { int* ptr1; double* ptr2; char* ptr3; float* ptr4; printf("%zu | %zu | %zu | %zu", sizeof(ptr1), sizeof(ptr2), sizeof(ptr3), sizeof(ptr4)); // Vom Obtine 8 | 8 | 8 | 8 (Arhitectura x64) indiferent de tipul de date pe care l stocheaza return 0; }
  11. ** Introducere in Incapsulare ** Incapsularea reprezinta un alt concept crucial in paradigma orientata pe obiecte care ne permite capacitatea de a restrictiona accesul campurilor unei clase de catre exterior . De exemplu , utilizatorului NU i se permite modificarea sau citirea parolei de catre persoane NEAUTORIZATE (DOAR DE CATRE ADMINISTRATOR SAU UTILIZATORUL RESPECTIV) . ** Nivele de Acces ** In limbajul C++ , exista 3 nivele de acces : "private" --> nu se permite accesul (modificare/citire) din exterior (doar in interiorul clasei) ; "public" --> se permite accesul (modificare/citire) din exterior . "protected" --> similar cu "private" doar ca se permite accesul de catre alte clase derivate . (VOM DISCUTA LA MOMENTU POTRIVIT) De exemplu : #include <iostream> using namespace std; class Utilizator { private: // Sector Privat (Membrii aflati la acest nivel de acces NU pot fi accesati) char username[50]; // Declar Privat public : // Sector Public (Membrii aflati la acest nivel de acces POT FI ACCESATI) char email[50]; // Declar Public protected : // Sector Protejat (Membrii aflati la acest nivel de acces NU POT FII ACCESATI DIN EXTERIOR CU EXCEPTIA MEMBRIILOR CARE APARTIN DE CLASE DERIVATE DIN ACEASTA) char password[50]; // Declar Protected }; int main() { Utilizator vasileEntitate; // Instantiez /// Atribuim valori catre instanta strcpy_s(vasileEntitate.email, "vasileemai@gmail.com"); // OK strcpy_s(vasileEntitate.username, "vasile"); // EROARE MEMBRU INACCESIBIL --> MEMBRU PRIVAT strcpy_s(vasileEntitate.password, "vasileParola"); // EROARE MEMBRU INACCESIBIL --> MEMBRU PROTECTED return 0; } NOTA ** : SE RECOMANDA CA VARIABILELE SA FIE STOCATE PE SECTOR PRIVAT IAR FUNCTIILE (METODELE) PE PUBLIC !!! ** Getteri && Setteri ** Pentru citirea si modificarea campurilor private din exterior , exista conceptul de getteri (pentru citire) & setteri (pentru modificari) . Practic , putem modifica campurile private prin intermediul unor metode publice . De exemplu : #include <iostream> using namespace std; class Utilizator { private: // Sector Privat (Membrii aflati la acest nivel de acces NU pot fi accesati) char username[50]; // Declar Privat char email[50]; // Declar Privat char password[50]; // Declar Privat public : // Sector Public (Membrii aflati la acest nivel de acces POT FI ACCESATI) // Getteri ( Getteri Trebuie sa returneze tipul de date al campului) const char* getUsername() { return username; } const char* getEmailAddress() { return email; } const char* getPassword() { return password; } // Setteri (Setteri NU returneaza nimic doar modifica) void setUsername(const char* _username) { strcpy_s(username, _username); } void setEmail(const char* _email) { strcpy_s(email , _email); } void setPassword (const char* _password) { strcpy_s(password, _password); } }; int main() { Utilizator vasileEntitate; // Instantiez /// Atribuim valori catre instanta prin Setteri vasileEntitate.setUsername("Vasile"); vasileEntitate.setEmail("vasileEmail@gmail.com"); vasileEntitate.setPassword("vasileParola"); // Afisam valorile prin getteri cout << vasileEntitate.getUsername() << endl; cout << vasileEntitate.getEmailAddress() << endl; cout << vasileEntitate.getPassword() << endl; return 0; } Rezultat output : TUTORIAL CONSTRUIT DE CATRE MINE PENTRU UTILIZATORI LEAGUECS !!! PENTRU SUGESTII , RECLAMATII , OBIECTII , va astept cu PM sau jos , in comentarii !!!
  12. Obiective : * Introducere Clase ; * Introducere Obiecte (Instante) ; * Implementare Clasa si Obiect in C++ . ** Clasele ** Clasele reprezinta un concept crucial in paradigma orientata pe obiecte definind atat caracteristicile cat si comportamentele unei entitate . Spre exemplu , o clasa poate fi reprezentat de utilizator la care se descriu informatii precum varsta , nume , email , parola etc. Practic , reprezinta modelul pentru fiecare obiect instantiat in clasa respectiva . O clasa poate avea membrii de tip : --> Variabile (Simple , Pointeri,Tablouri de dimensiune etc.) ; --> Structuri , Clase sau Enumeratii ("Imbracate") ; --> Metode (Functii) ce descriu comportamentele obiectelor ; --> Constructori & Destructori (Pentru atribuire/alocare membrii cu valori si pentru eliminarea valorilor reziduale ) ** De constructori si destructori vom discuta in subiectele ce urmeaza !! Exemplu de Implementare Clasa in C++ : class Utilizator { public: // Recunoscut in afara Clasei // Variabile Simple int id; // Id Utilizator char username[50]; // Nume Utilizator char email[50]; // Email Utilizator char password[50]; // Parola Utilizator // Functii (Metode) const char* afisarenume() { return username; // Afisam numele utilizatorului } const char* afisareemail() // Afisam Email Utilizator { return email; } const int afisareid() // Afisam Id utilizator { return id; } const char* afisareParola() // Afisam Parola Utilizator { return password; } }; ** Obiectele sau Instantele ** Instantele reprezinta exemplarele sau entitatile autonome facute pe baza clasei instantate . De exemplu , clasa utilizatori poate instantia una sau mai multi elevi . Practic , putem avea elevi cu nume sau adresa de mail diferite , cu altfel de comportamente etc. O clasa se poate instantia pe cale statica sau dinamica : int main() { // Alocare Statica Utilizator vasileEntitate; // Initializare Proprietati vasileEntitate.id = 1; strcpy_s(vasileEntitate.username, "Vasile"); strcpy_s(vasileEntitate.email, "vasile323@gmail.com"); strcpy_s(vasileEntitate.password, "VasileParola"); cout << vasileEntitate.afisareid() << endl; cout << vasileEntitate.afisarenume() << endl; cout << vasileEntitate.afisareemail() << endl; cout << vasileEntitate.afisareParola() << endl; /// Alocare Dinamica (Stocata in memorie) Utilizator* ionEntitate = new Utilizator(); // Initializare cu valori ionEntitate->id = 2; strcpy_s(ionEntitate->username, "Ion"); strcpy_s(ionEntitate->email, "ion323@gmail.com"); strcpy_s(ionEntitate->password, "IonParola"); // Afisare Valori pentru ion cout << ionEntitate->afisareid() << endl; cout << ionEntitate->afisarenume() << endl; cout << ionEntitate->afisareemail() << endl; cout << ionEntitate->afisareParola() << endl; // Intotdeauna la Alocarea Dinamica Stergem valorile Reziduale delete ionEntitate; // Stergem Valoare Reziduala ionEntitate = nullptr; // Si o transformam in null pointer !! return 0; } Rezultatul in consola : NOTA** : VOM DISCUTA IN TUTORIALELE CE URMEAZA MAI IN DETALIU DESPRE ALOCAREA DINAMICA A INSTANTELOR !! **MULTUMESC FRUMOS PENTRU ATENTIE , TUTORIAL CONSTRUIT INTEGRAL DE CATRE MINE PENTRU UTILIZATORI LEAGUECS !! **PENTRU NELAMURIRI , SUGESTII , RECLAMATII VA PUTETI ADRESA JOS (IN COMENTARII) SAU PM !!!
      • 1
      • Fortzaaaa
  13. Nume actual: Deja Vu Numele pe care il doriti: ^^King Of Underground^^ Motivul pentru care doriti sa il schimbati: Nu mi mai place Link de la ultima cerere: Link PS : Daca nu sunt acceptate caractere speciale , cer sa ramana fara ele , Multumesc !
  14. Ce reprezinta Motorul ? Motorul reprezinta componenta esentiala a unui autovehicol care face posibila , generarea unui LUCRU MECANIC , prin intermediul unei forme de energie . De exemplu , pentru o bicicleta simpla (fara motor) va trebui sa pedalam (forta mecanica) pentru a pune in miscare aceea bicicleta , in schimb , cele electrice folosesc curentul pentru a ne scuti din a pedala . Pe scurt , ele genereaza energie cinetica prin procesarea combustibilului . Unde regasim Motorul ? Motorul il regasim de la orice scula de gospodarie (motosapa,pompa,ciocan rotopercutor) pana la autoturisme , avioane sau nave . Tipuri de Motoare in functie de combustie Din aceasta perspectiva (a formei de energie) , se desting doua tipuri de motoare : --> Motoarele termice (cu ardere interne sau externa) ce folosesc un tip de combustibil fosil (benzina,motorina etc.) . --> Motoarele electrice ce folosesc curent electric pentru a pune in miscare motorul . MOTOR TERMIC (PE BENZINA) Motor ELECTRIC
×
×
  • Creează nouă...

Informații Importante

Termeni de Utilizare & Politică Intimitate