Colegiul National

21
Colegiul national ,,Ion Luca Caragiale” Bucuresti Atestat la informatica Clasament campionat fotbal

description

as

Transcript of Colegiul National

Page 1: Colegiul National

Colegiul national ,,Ion Luca Caragiale”

Bucuresti

Atestat la informatica

Clasament campionat fotbal

Page 2: Colegiul National

Indrumator: Autor:prof. Iuliana Dumitrescu elev Constantin Alexandru

2014

CUPRINS :

Introducere…………………………………

Prezentarea aplicatiei……………………

Utilizarea aplicatiei………………………..

Page 3: Colegiul National

Cod sursa…………………………………….

IntroducereClasament campionat de fotbal este un program in C++ care poate fi utilizat pentru a clasifica echipele care participa intr-un campionat de fotbal, in urma rezultatelor pe care le inregistreaza pe parcursul unui sezon. Motivul pentru care am ales aceasta tema a fost pentru a fi folosit de fanii echipelor care doresc sa tina evidenta echipelor lor favorite, dar si de institutiile care organizeaza competitii de fotbal. Utilizatorii vor putea inscrise victoriile, egalurile si infrangerile echipelor ce activeaza in acel campionat si astfel pot determina clasarea tuturor echipelor sau a unei singure echipe favorite. Acest program pune in evidenta o clasificare a participantelor unei competitii de fotbal, oferind posibilitatea de a stoca, sterge si vizualiza date despre acele echipe.

Page 4: Colegiul National

Programul Clasament campionat de fotbal este realizat cu ajutorul mediului de programare Code::Blocks.

Code::Blocks este o sursa deschisa si gratuita, o platforma IDE care suporta multiple compilatoare GCC si Visual C++. Este dezvoltat in C++ folosind wxWidgets ca toolkit GUI. Folosind o interfata de plugin capacitatile si caracteristicile sale sunt definite de pluginurile oferite. In present, Code::Blocks este orientat catre C, C++ si Fortran. De asemenea, poate fi folosit si pentru a crea ARM, AVR, D, DirectX, FLTK, GLFW, GLUT, GTK+, Irrlicht, Lighfeather, MATLAB, OGRE, OpenGL, Qt, SDL, SFML, STL, SmartWin si programe wx si aplicatii, chiar daca in unele cazuri instalarea unor SDKs-uri third-party sau a unor cadre de lucru ( framework ) este necesara.

Code::Blocks este dezvoltat pentru Windows, Linux, Mac OS X si a fost adaptat pentru FReeBSD, OpenBSD si Solaris.

Cea mai recenta versiune stabila din decembrie 2013 este de Code:: Blocks 13.12, care a fost lansata pe 27 decembrie 2013.

Page 5: Colegiul National

 Introducere in C/C++

 

In anul 1970, doi programatori, Brian Kerninghan si Dennis Ritchie, au creat limbajul C. Principalul scop pentru care a fost realizat acest limbaj este rescrierea sistemului de operare UNIX, pentru a-l face portabil pe toate platformele existente. Marele avantaj al limbajului C este acela de a fi extrem de flexibil si de a permite atat programarea la nivel inalt cat si la nivel scazut. C-ul este un limbaj procedural, asadar un program scris in C incepe de obicei cu definirea structurilor de date, apoi definirea functiilor pentru lucrul cu aceste structuri.

Cresterea complexitatii programelor a dus la necesitatea elaborarii unor alte tipuri de limbaje. Astfel, destinate inteligentei artificiale, au aparut limbajele care au la baza notiunea de 'cadru' si cele care pleaca de la ideea de 'actor'. Primele implementeaza operatii asupra unor modele de entitati; celelalte presupun faptul ca obiectele nu sunt simple elemente pasive asupra carora se fac anumite prelucrari, ci, dimpotriva, ca menirea acestor obiecte consta in a realiza prelucrarile asupra lor insile.

De aici a pornit ideea de a grupa structurile de date cu operatiile care prelucreaza respectivele date. Astfel s-a nascut notiunea de obiect sau clasa. Proiectarea de programe utilizand clase se numeste programare orientata pe obiecte (OOP).

Primele limbaje orientate pe obiecte au fost SIMULA (1965) si SIMULA-2 (1967). In anii '70 a aparut si celebrul limbaj SMALLTALK. Cel mai mare dezavantaj al lor a fost faptul ca au aparut ca limbaje de sine statatoare, avand o raspandire relativ redusa. Din acest motiv, putin programatori erau dispusi in acea vreme sa renunte la limbajele consacrate doar pentru a lucra obiectual.

In anul 1980, Bjarne Stroustrup a conceput limbajul 'C with Classes'. Acest limbaj a dus la imbunatatirea C-ului prin adaugarea unor noi facilitati, printre care si lucrul cu clase. In vara 1983, C-with-classes a patruns si in lumea academica si a institutiilor de cercetare. Astfel, acest limbaj a putut

Page 6: Colegiul National

sa evolueze datorita experientei acumulate de catre utilizatorii sai. Denumirea finala a acestui limbaj a fost C++.

Succesul extraordinar pe care il are limbajul C++ a fost asigurat de faptul ca a extins cel mai popular limbaj al momentului, C. Programele scrise in C functioneaza si in C++, si ele pot fi transformate in C++ cu eforturi minime.

 

II.1 Instructiuni conditionale

II.1.1 Conditii

In limbajul C++ intalnim doua instructiuni conditionale (if si switch), precum si o varianta “imediata” a instructiunii if. Le vom descrie pe rand insistand asupra modalitatii de folosire si a greselilor frecvent intalnite. Insa, inainte de aceasta vom detalia notiunea de “conditie” in acceptiunea limbajului C++ si vom prezenta operatorii logici acceptati.

In limbajul C++ nu exista un tip logic de sine statator cum exista in Pascal tipul boolean. Pentru un plus de flexibilitate si o mai mare putere de exprimare s-a convenit ca orice tip de variabila/expresie ce

poate fi evaluata la un tip diferit de tipul “void” sa poata fi considerata o expresie logica. Conventia este ca orice expresie/variabila/constanta care este evaluata la o valoare nenula (diferita de 0) sa fie considerata ca avand valoarea de adevar “adevarat” si orice expresie /variabila /constanta care este nula sa fie considerate ca avand valoare de adevar “fals”. Pentru a clarifica acest concept vom prezenta cateva exemple de conditii. La inceput vom declara cateva variabile:

int x = 3;

char ch = ‘A’;

char chn = 0x0;

float r = 0.0;

unsigned long ul = 0;

Acum sa vedem cateva expresii logice formate cu variabilele de mai sus si valoarea lor de adevar:

x - este o expresie care fiind diferita de 0 (3 != 0), se va evalua la adevarat

chn - este o expresie care fiind 0 (caracterul avand codul ASCII 0) este

considerata falsa

x + ul - este o expresie a carei valoare este 3 + 0 = 3, adica adevarata

ch * 0 - este o expresie a carei valoare este 0 (‘A’ are codul ASCII 65, iar 65 * 0= 0), deci falsa

x / ch - este o expresie a carei valoare este 0 (3 / 65 in numere intregi are valoarea 0), deci falsa

Page 7: Colegiul National

sqrt(x) - este o expresie a carei valoare este nenula, radical din 3 este aprox. 1.732

De obicei nu vom testa pur si simplu o variabila, sau o expresie simpla, ci vom folosi operatori pentru a defini o conditie. Deoarece in acceptiunea C++ nu exista un tip logic ci orice expresie poate fi o conditie, se pot folosi absolut toti operatorii in cadrul expresiei (aritmetici, relationali, logici, pe biti, de egalitate, etc). Operatorii logici (a nu se confunda cu operatorii aritmetici, relationali, de egalitate sau pe biti care pot fi folositi in expresiile care se evalueaza pentru conditie) suportati de C++ sunt:

&& -“si” logic. Returneaza adevarat daca ambele expresii se evalueaza la valori nenule, altfel returneaza fals. Daca prima expresie este evaluata la 0 (fals), a doua expresie nu se mai evalueaza. Acest lucru poate cauza erori de programare greu de detectat in cazul in care cea de a doua expresie contine un apel de functie. Apelul va avea loc numai daca prima conditie se evalueaza la adevarat (valoare nenula).

Atentie: un singur simbol & inseamna si pe biti si este diferit de &&.

|| -“sau” logic. Returneaza adevarat daca cel putin una din expresii se evalueaza la o valoare nenula. In cazul in care prima expresie este adevarata, cea de a doua nu se mai evalueaza. Remarca este absolut similara cu cea de la si logic.

Atentie: un singur simbol | insemna SAU pe biti si este diferit de ||.

! -negatie logica; Returneaza adevarat daca expresia este nula, fals in caz contrar. (!E) este echivalent cu (E == 0).

Alti operatori mult folositi in conditii sunt operatorii de egalitatate:

== -egal. Returneaza adevarat (valoare nenula) daca cele doua expresii sunt egale, fals (0) daca cele doua expresii sunt diferite. Din punct de vedere logic (E1 == E2) este echivalent cu (!(E1 - E2))

!= -diferit. Semnificatia este opusa operatorului ==. In consecinta, din punct de vedere logic (E1!= E2) si (E1 - E2) sunt echivalente.

Ultimii operatori amintiti sunt cei relationali:

< -mai mic. Returneaza adevarat daca valoarea expresiei din stanga este mai mica decat a celei din dreapta. Normal ca ambele expresii trebuie sa fie de tip scalar/numeric (integer/real/caracter/etc) pentru ca sa se poate face comparatia.

<= -mai mic sau egal. Returneaza adevarat daca valoarea expresiei din stanga este mai mica sau egala cu cea din dreapta.

> -mai mare. Returneaza adevarat daca valoarea expresiei din stanga este mai mare ca si cea din dreapta.

>= -mai mare sau egal. Returneaza adevarat daca valoarea expresiei din stanga este mai mare sau egala cu cea din dreapta.

Acum, dupa ce am prezentat cele mai importante lucruri despre ceea ce inseamna o conditie si care sunt operatorii care pot fi folositi in definirea conditiilor, vom trece in revista instructiunile conditionale.

II.1.2   - if

Sintaxa instructiunii este:

Page 8: Colegiul National

if ( <conditie> ) <instructiune1>;

Sau in varianta cu executie alternativa (executie pentru cazul in care conditia este falsa)

if ( <conditie> ) <instructiune1>;

else <instructiune2>;

In ambele cazuri prin instructiune se intelege fie o instructiune simpla, fie una compusa (grup de instructiuni incadrat de ). Conditia poate sa contina dupa cum am mentionat mai sus orice expresie. Este bine insa sa nu se exagereze la folosirea expresiilor complexe deoarece aceasta afecteaza claritatea codului.

Un exemplu in care se poate vedea aceasta este urmatorul:

int x = 3;

int y = 4;

if(x = y)

else

printf(“Conditie falsa”);

In mod oarecum surprinzator pentru un neinitiat in C++ bucata de program la executie va tipari “Conditie adevarata”. Aceasta deoarece conditia este x = y, adica o atribuire si nu o comparatie (comparatia ar fi fost x == y), iar atribuirea primeste ca valoare, valoarea atribuita (4 in cazul nostru).

Recomandam o folosire mai putin tipica C++, dar mult mai usor de inteles:

int x = 3;

int y = 4;

x = y;

if(x != 0) //mai normal pentru C++ ar fi fost sintaxa echivalenta if(x)

Mai facem doua remarci pentru instructiunea if. Este obligatoriu simbolul de terminare instructiune “;” inainte de else. In cazul in care avem mai multe instructiuni if/else imbricate se recomanda folosirea parantezelor acoladice pentru a ne asigura ca ramura de else se va interpreta pentru ramura de if la care ne asteptam. De exemplu:

if(conditie_a)

else

II.1.3 - operatorul conditional (if imediat)   “? :”

In multe cazuri avem de atribuit o anumita valoare unei variabile in functie de o anumita conditie. Sa presupunem urmatorul scenariu. Daca “conditia_a” este adevarata atunci vrem sa

Page 9: Colegiul National

atribuim variabilei x valoarea 1, daca nu valoarea 3. Evident acest lucru se poate scrie folosind instructiunea if:

if(conditia_a)

x = 1;

else

x = 3;

O alta posibilitate mult mai compacta si mai usor de scris este folosind operatorul if imediat:

x = (conditia_a) ? 1 : 3;

II.1.4 –   switch

Formatul instructiunii este:

switch ( <variabila> )

Este o instructiune folosita cand se doreste ca in functie de valoarea unei anumite expresii (<variabila>) numerice sa se execute un grup de instructiuni. De obicei se foloseste in cazul in care avem mai mult de trei variante (pentru 2 variante este mai comoda varianta cu if). Ca si interpretare in cazul in care break este prezent pe toate ramurile de case, este echivalenta cu:

if(<variabila> == <constanta1>) <instructiune1>;

else if(<variabila> == <constanta2>) <instructiune2>;

else <instructiune_def>;

In cazul in care break nu este prezent pe una din ramuri se va executa in continuare instructiunea de pe ramura urmatoare. O greseala comuna este uitarea instructiunii break in totalitate, in acest caz se vor executa toate instructiunile situate mai jos de ramura de case pe care este selectata executia.

ex.

unsigned int uTest = 3; //evident in acest caz se va intra doar pe ramura pentru //valoarea 3,

//daca aceasta exista, altfel pe ramura default daca exista

unsigned uVal = 0;

switch(uTest)

Daca nu ar fi existat instructiunile break s-ar fi executat uVal = 78 si apoi uVal = 0, deoarece neexistand instructiunea break de iesire din switch executia se continua liniar ignorand selectiile din

Page 10: Colegiul National

case. Desi aceasta pare un deficit, in fond este un avantaj, permitand un cod mai compact in cazul in care

conditiile din case sunt cumulative (adica pentru prima ramura se executa si codul de pe cea de a doua ramura, etc.).

 

II.2 Instructiuni de ciclare

In C++ instructiunile care pot fi folosite pentru a cicla (executa un grup de mai multe

instructiuni -numit si bucla de ciclare- in mod repetat) sunt:

- for

- while

- do while

Toate aceste instructiuni folosesc conditii pentru a iesi din bucla de ciclare. Reamintim ca in C o conditie este formata din orice expresie, nu exista un tip specific 'logic' pentru conditii ca si in alte limbaje de programare. Expresia care formeaza conditia este analizata si daca este diferita de zero se considera valoare 'adevarat', iar daca este egala cu zero se considera 'fals'.

Vom analiza pe rand instructiunile de ciclare si vom specifica pentru fiecare cateva modalitati tipice de folosire. Inainte insa vom reaminti cateva notiuni despre sirurile de caractere, deoarece o utilizare tipica a tuturor instructiunilor de ciclare este parcurgerea sirurilor de caractere si executarea unor anumite operatiuni pe acestea. Cele mai multe din exemple vor lucra cu siruri de caractere sau de intregi. Sirurile de caractere in C/C++ sunt stocate ca si secvente de caractere in memorie terminate prin caracterul 0. Nu este stocata lungimea in mod explicit. De exemplu cuvantul “ABC” este stocat in memorie ca un sir de caractere ‘A’ ‘B’ ‘C’ 0x0. Numeric in memorie se vor gasi codurile ASCII: 65 66 67 0, sau in hexazecimal 0x41 0x42 0x43 0x0. Sirurile sunt referite in general de pointeri la caracter. Deoarece in C++ un nume de matrice/vector este un pointer constant la sirul -primul element din sir de fapt, dar acesta este urmat in memorie de restul elementelor din sir- de caractere/elemente din matrice/vector, acesta se poate folosi pentru a cicla peste vectorul respectiv. De exemplu urmatorul cod declara o variabila de tip sir de caractere, apoi copiaza in sirul respectiv un alt sir, iar in final tipareste sirul..

unsigned char strBuffer[256];

strcpy(strBuffer, “Un alt sir”);

printf(strBuffer);

II.2.1 –   for

Sintaxa instructiunii este prezentata mai jos.

for ( [<instructiuni_initializare>] ; [<conditie_ciclare>] ; [<instructiuni_incrementare>] )

<instructiune_bucla>;

Page 11: Colegiul National

Este probabil cea mai folosita instructiune de ciclare, prin ea se pot emula toate celelalte instructiuni.

In pozitia “instructiuni_initializare” se pot include mai multe instructiuni separate prin virgula “,”. Acestea pot fi declaratii de variabile, initializari, etc. Se vor executa la inceputul buclei, inainte de orice instructiune din bucla. In cadrul “instructiuni_incrementare” se respecta aceleasi reguli, doar ca aceste instructiuni se vor executa la fiecare ciclare. In mod normal aici se vor afla instructiuni care modifica contoarele folosite in ciclu si in baza carora se va testa iesirea din bucla. Testul se va face in “conditie_ciclare”. Conditia se testeaza pentru fiecare executie a buclei, inclusiv prima executie. sa vedem de exemplu cum putem parcurge un sir de caractere, modificand caracterele la majuscule (in engleza UpCase):

unsigned char strSir[256];

sscanf(“Introduceti un sir de caractere (cuvant/propozitie): %s”, strSir); //citim

for(int iIndex = 0; (strSir[iIndex]) && (iIndex < 256); iIndex++)

strSir[iIndex] = UpCase(strSir[iIndex]);

printf(“nSirul convertit la majuscule: %sn“, strSir);

Ne vom concentra asupra instructiunii for. La initializare pornim un contor care va creste de la 0 pana la valoarea pe care se afla pozitia ultima in sir (caracterul 0). Variabila declarata in cadrul instructiunilor de initializare este local buclei for si nu poate fi folosita in afara ei. In conditie testam doua lucruri: caracterul din sir de pe pozitia indicata de “iIndex” sa fie diferit de 0 si sa nu depasim dimensiunea sirului. De obicei al doilea test nu se mai face, in cazul in care sirul este folosit corect, nu se va ajunge niciodata sa se depaseasca dimensiunea maxima. Daca in schimb se incerca a se copia in spatiul destinat unui sir un sir care este mai mare decat spatiul respectiv se poate ajunge in situatia in care nu mai exista caracterul 0 de terminare si atunci se va depasi zona de date alocata sirului, algoritmul mergand in continuare pana intalneste primul 0 in memoria de dupa sir (aceasta generand un “memory overwrite” si o comportare aleatoare a programului).

Sa vedem de exemplu un mic program care determina lungimea unui sir de caractere (echivalent cu strlen):

#include <stdio.h>

void main(void)

Ca si in cazul instructiunii switch este posibil sa folosim break pentru a intrerupe in mod fortat bucla. O alta instructiune de control al executiei in cadrul buclei este continue care trece controlul la inceputul buclei. De exemplu daca vrem sa parcurgem un sir de 20 de elemente si in loc de fiecare element sa setam inversul acestuia (1/x, evident doar daca acesta este nenul).

float array[20];

void main ()

}

II.2.2 -   while

Sintaxa instructiunii este urmatoarea:

Page 12: Colegiul National

while ( <conditie> ) <instructiune>;

Este folosita pentru ciclurile in care conditia nu depinde de un contor. De exemplu unul din cazurile cele mai folosite sunt la citirea dintr-un fisier. Exemplul de mai jos prezinta un ciclu in care se citesc dintr-un fisier (c:test.txt) blocuri de 1MB si se afiseaza de fiecare data nr. de bytes (octeti) cititi (cu unele modificari s-ar putea folosi ca si un program de cautare in fisiere a unui text, sau de copiere).

const int BufferSize = 1024L * 1024L;

int *Buffer = (int *)malloc(BufferSize); //1Mb = 1024 * 1024 bytes

int fin = open(“c:test.txt”, O_RDONLY | O_BINARY);

int iBytesRead;

while((fin != -1) && (!eof(fin)))

close(fin);

Se remarca folosirea unor altor instructiuni de lucrul cu fisiere fata de articolul trecut. In mod normal acestea sunt preferate -mai noi si mai eficiente-, desi in cele mai multe cazuri pentru convenienta data de fprintf si fscanf se folosesc instructiunile mai vechi fopen,fclose.

Echivalentul in Pascal al instructiunii este “while do”. Mentionam aceasta pentru a se evita confuzia dintre while si do while -ambele instructiuni C++. Prima testeaza conditia la inceput de bucla, a doua executa bucla si abia apoi testeaza conditia (la sfarsit de bucla). In cazul while se poate intampla ca sa nu se execute bucla nici macar o data daca la evaluarea conditiei de ciclare aceasta este mereu falsa. Ca si in cazul instructiunii for se pot folosi break si continue pentru a intrerupe executia sau a relua executia de la inceputul buclei (cu reevaluarea conditiei).

II.2.3 -   do while

In cazurile in care este necesara cel putin o parcurgere a buclei inainte de testare se foloseste instrucsiunea dowhile. Sintaxa ei este redata mai jos:

do <instructiune> while ( <conditie> );

Echivalentul ei in Pascal este repeat until. Ca si la while se folosesc instructiunile break si continue pentru a controla executia in interiorul buclei. Diferenta vine din faptul ca se executa in mod sigur cel putin o data bucla, pe cand la while bucla poate sa nu se execute deloc daca se evalueaza la fals conditta in momentul atingerii instructiunii while. Mai jos dam un exemplu de program care foloseste bucla do while pentru a testa introducerea unei parole:

#include <stdio.h>

#include <string.h>

int main ()

while (strcmp(pass, control));

return 0;

Page 13: Colegiul National

}

In cazul in care parola se va potrivi cu cea stocata in variabila checkword, functia strcmp (compara doua stringuri) va intoarce 0 si conditia de iesire din bucla se va evalua la fals, parasindu-se bucla.

In cazul instructiunii do while la intanirea instructiunii continue nu se testeaza conditia (normal daca ne gandim ca executia se reia de la inceputul buclei si conditia se testeaza la sfarsitul buclei).

Page 14: Colegiul National

PREZENTAREA APLICATIEI

Page 15: Colegiul National

CODUL SURSA

#include<iostream>#include<string>#include<windows.h>using namespace std;

struct echipe{   char club[30];   unsigned w,l,e;   unsigned long pt;

Page 16: Colegiul National

};echipe v[100],aux;int n,i;void citire(){  SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),10);   cout<<"Numarul de echipe din Liga I:"; cin>>n; cout<<endl<<endl<<endl;   for(i=1;i<=n;i++)   {      SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),7);      cout<<"    *** Date echipa no. "<<i<<" ***"<<endl<<endl;      SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),4);      cout<<"[Echipa "<<i<<"] Nume: ";           cin>>v[i].club;      cout<<"[Echipa "<<i<<"] Meciuri castigate: "; cin>>v[i].w;      cout<<"[Echipa "<<i<<"] Meciuri egale: ";     cin>>v[i].e;      cout<<"[Echipa "<<i<<"] Meciuri pierdute: ";   cin>>v[i].l; cout<<endl;   }}

Page 17: Colegiul National

void puncte(){   for(i=1;i<=n;i++)   {      v[i].pt=v[i].w*3+v[i].e*1+v[i].l*0;      SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),11);   }}

void clasament(){   puncte();   int ok;   do   {      ok=0;      for(i=1; i<n; i++)        {         if(v[i].pt<v[i+1].pt)         {            aux=v[i];            v[i]=v[i+1];            v[i+1]=aux;            ok=1;         }      }   }   while(ok==1);

Page 18: Colegiul National

}

int main(){   citire();   clasament();   system("cls");   for(i=1; i<=n; i++)      cout<<i<<". Echipa: "<<v[i].club<<"   Victorii: "<<v[i].w<<"   Infrangeri: "<<v[i].l<<"   Egaluri: "<<v[i].e<<"   Puncte: "<<v[i].pt<<endl;   return 0;}