Am apucat sa vorbim despre o parte din problemele legate de functii.
Deja am utilizat in intalnirile anterioare functii existente in BGT precum exit(), alert(), wait() sau random(). Aceste functii fac un anumit lucru: efectueaza o actiune sau returneaza o valoare. De exemplu alert() face o actiune, afiseaza o fereastra cu buton Ok, exit() scoate tot ceea ce tine de BGT din memorie etc, pe cand functia random() returneaza o valoare, un numar aleatoriu.
In BGT exista cateva sute de functii built-in, acestea fiind gasibile cu documentatie si exemple in manualul care devine disponibil in urma instalarii kitului de la Blastbay Studios.
Explicand cat mai simplu posibil, o functie este un nume care se refera la un bloc de cod care face ceva:
- ori o actiune fara returnarea unei valori,
- ori o actiune cu returnarea unei valori,
- ori doar returneaza o valoare fara o actiune perceputa de noi.
De exemplu functia random() care returneaza o valoare are si un bloc de cod care face ca numarul aleatoriu sa fie returnat, dar fiind o functie nativa / built-in, noi nu putem vedea acest cod care sta la baza.
Am observat ca atunci cand apelam o functie in cadrul unui script, numele acesteia este urmat de paranteze rotunde, deschisa si inchisa. Intre aceste paranteze pot fi sau nu parametri.
Parametrii pot fi oricati, inclusiv niciunul, intre ei punandu-se "," (virgula).
Acesti parametri sunt practic niste valori de care are nevoie o functie, dupa caz, pentru a se achita de sarcina asa cum vrem noi. De exemplu functia random() are nevoie de doi parametri, numarul minim si numarul maxim intre care sa fie generat numarul aleatoriu de returnat. Functia alert() are nevoie de doi parametri de tip string, unul reprezentand titlul, al doilea reprezentand corpul ferestrei cu buton Ok. Functia wait() are nevoie doar de un parametru de tip int (numar intreg) care sa specifice numarul de milisecunde pentru care rularea scriptului sa fie intrerupta. Functia exit() nu are nevoie de parametri, insa parantezele nu lipsesc.
BGT / C++ fiind un limbaj static typed, este foarte important tipul valorii returnate.
Avem functii care returneaza un numar intreg, aceasta inseamna ca functia este definita de tip int, avem functii care returneaza un string, deci functie definita string, la fel double sau bool, dar avem si functii care nu returneaza nimic, acestea fiind definite ca void.
De exemplu functia random() este de tip int pentru ca returneaza un numar intreg, numarul aleatoriu generat intre parametri dati. Inseamna ca putem atribui valoarea returnata de random() doar unei variabile de tip numar; asadar putem considera corect urmatorul cod:
Cod: Selectaţi tot
void main()
{
int numar_aleatoriu = random(1, 6);
alert(“Salut!”, “Un numar aleatoriu este ”+numar_aleatoriu+”.”);
exit();
}
Cod: Selectaţi tot
void main()
{
string numar_aleatoriu = random(1, 6);
alert(“Salut!”, “Un numar aleatoriu este ”+numar_aleatoriu+”.”);
exit();
}
Un exemplu de functie care returneaza string ar fi string_reverse(). Aceasta functie returneaza un text inversat, scris de la coada la cap. Are nevoie de un parametru, string-ul de inversat:
Cod: Selectaţi tot
void main()
{
// Cream o variabila cu numele textul si ii dam o valoare:
string textul = “Manu”;
// Atribuim variabilei textul valoarea pe care o avea, dar inversata:
textul = string_reverse(textul);
alert(“Salut!”, textul);
/*
In corpul ferestrei alert va aparea string-ul “unaM”, de remarcat ca litera “M” ramane majuscula, chiar daca ajunge sa fie la capat de string.
*/
exit();
}
int text = string_reverse(textul);
nu am fi putut atribui valoarea string returnata de string_reverse unei variabile de tip int cum ar fi fost int text.
Functia exit() este de tip void, aceasta nu returneaza nici o valoare. Inseamna ca nu putem scrie o instructiune de tipul:
int x = exit();
Putem defini si noi functii pentru diferite actiuni, calcule. Avand functii definite pentru anumite sarcini, ne vom putea folosi in viitor de ele apelandu-le oriunde in cadrul scriptului nostru.
Avem sa zicem nevoie de o functie care sa adune doua numere si sa returneze rezultatul sub forma de int (numar intreg). Putem crea pentru aceasta o functie numita adunare(), functie pe care o vom putea utiliza apoi oriunde.
Pentru a defini o functie, sablonul este urmatorul:
Cod: Selectaţi tot
tip nume_functie(parametri)
{
// Aici un cod oarecare.
// Urmatorul rand doar daca tip nu este egal cu void:
return valoare;
}
Primul rand este:
tip nume_functie(parametri)
tip poate fi egal cu string, int, float, double sau bool, depinde ce tip de valoare vrem sa returneze in final functia. Daca nu vrem sa returneze vreo valoare ci doar sa faca o actiune, vom scrie void.
nume_functie poate fi orice text, important e ca nu poate incepe cu o cifra si poate contine doar litere, cifre sau semnul “_” (underline). E bine sa denumim cat mai sugestiv functiile, astfel incat sa ne amintim usor de ele; de exemplu daca cream o functie care sa faca o adunare, aceasta se poate numi… cum altfel decat “adunare”.
Intre parantezele rotunde vor aparea parametrii daca e cazul. Acestia vor fi definiti precum niste variabile. Daca avem de exemplu nevoie de doi parametri de tip int, am putea scrie intre paranteze (int nr1, int nr2).
Urmeaza blocul de cod la care se refera numele functiei pe care o cream, desigur acesta fiind intre acolade.
In acest bloc de cod pot fi oricate instructiuni, oricate alte functii built-in sau definite de noi, important e ca in final, daca functia nu a fost de tip void, sa apara instructiunea pentru returnarea valorii.
Pentru a returna valoarea scriem:
return val;
val poate fi ori continutul unei variabile, ori un calcul facut pe acelasi rand, ori un text scris intre ghilimele in cazul unei functii de tip string etc.
Sa presupunem ca am fi creat noi functia random(), incercam sa modificam sablonul cu date mai concrete.
Stim ca este o functie care returneaza int si stim ca are doi parametri de tip int, atunci sablonul va arata astfel:
Cod: Selectaţi tot
int random(int numar_minim, int numar_maxim)
{
/*
In locul acestui comentariu, ar putea fi codul pentru generarea numarului aleatoriu.
Variabilele care vor prelua parametrii au fost denumite la intamplare, nu conteaza numele pe care le dam.
In cadrul blocului de cod al acestei functii, cand vrem sa ne referim la valoarea primului parametru vom folosi numar_minim ca pe o variabila normala, la fel si cu al doilea parametru, numar_maxim.
Aici se termina comentariul.
*/
// Presupunand ca mai sus am generat numarul aleatoriu atribuindu-l unei variabile numite x, scriem mai jos:
return x;
}
Vrem asadar sa adunam doua numere de tip int (numar intreg) si apoi sa fie returnat rezultatul sub forma tot de int.
Avem nevoie de doi parametri, cele doua numere de adunat:
Cod: Selectaţi tot
int adunare(int nr1, int nr2)
{
// cream o variabila locala numita temp:
int temp;
// Atribuim acestei variabile rezultatul adunarii:
temp = nr1+nr2;
// Returnam valoarea variabilei temp:
return temp;
}
Cod: Selectaţi tot
void main()
{
int rezultat;
rezultat = adunare(1, 5);
alert(“Salut!”, “Rezultatul este ”+rezultat+“.”);
// ar trebui sa apara 6.
exit();
}
Mai cream o ultima functie de tip void in doua exemplare.
Sa zicem ca avem nevoie in unele locuri in script de o functie care sa inchida programul. O prima idee va fi: putem folosi exit() oricand, o functie deja existenta in BGT. Dupa o analiza mai atenta, vom vedea ca o inchidere brusca a unui joc nu este atat de placuta, poate vrem sa fie afisat si un mesaj de ramas bun.
Asadar, am avea nevoie de doua randuri de cod, una cu alert-ul care sa afiseze mesajul si unul cu functia exit() care sa inchida totul.
Am putea scrie cele doua randuri direct in cod fara sa cream o functie pentru aceasta, dar, poate in viitor dorim sa mai adaugam o instructiune, sa se auda si un sunet. Ar insemna sa cautam toate locurile din program / joc unde este posibila inchiderea si sa adaugam randul pentru sunet. Avand insa functia definita de noi pentru inchidere, aceasta este apelata peste tot unde este necesar, dar instructiunile care ii alcatuiesc blocul de cod sunt scrise doar intr-un loc, in locul definirii, fapt care va face sa ne fie foarte usor sa modificam cum si cand vrem actiunile care sa se intample la inchiderea programului.
O prima intrebare care ar putea aparea in aceasta faza la un incepator ar fi: “Cum adica sa fie in mai multe locuri nevoie de inchiderea programului? Nu se inchide la apasarea Alt + F4?”.
Raspunsul este: inchiderea programului poate surveni in nenumarate situatii: a fost apasata combinatia Alt + F4 daca aceasta este definita, s-a terminat jocul, a expirat timpul de testare intr-o versiune demo, a aparut o eroare etc. Peste tot in aceste cazuri noi am folosi functia creata si s-ar intampla acelasi lucru.
O prima varianta foarte simpla ar fi:
Cod: Selectaţi tot
void inchidere_program()
{
alert(“La revedere!”, “Te mai asteptam si altadata!”);
exit();
}
Presupunand totusi ca avem nevoie de mesaje diferite in functie de situatia in care trebuie sa se inchida programul, putem crea functia cu un parametru pentru mesaj:
Cod: Selectaţi tot
void inchidere_program(string mesajul)
{
alert(“La revedere!”, mesajul);
exit();
}
Pentru ca sa aiba acelasi efect ca prima varianta, atunci cand apelam functia inchidere_program() in cea de-a doua varianta scriem:
inchidere_program(“Te mai asteptam si altadata!”);
In final ar mai fi de mentionat cate ceva pentru a nu exista confuzii:
- Parametrii pot fi oricati, inclusiv niciunul.
- Tipul parametrilor nu au legatura cu tipul functiei. O functie care returneaza int poate avea ca parametri stringuri.
- Parametrii pot fi de toate felurile la aceeasi functie, de exemplu definirea unei functii amestec_litere() ar fi corecta si in felul urmator:
string amestec_litere(string tx, int nr)
desigur ca randul de mai sus este doar un exemplu pentru o functie ipotetica in care string tx ar fi textul de amestecat, iar acel int nr ar putea specifica de cate ori sa fie amestecat inainte de returnare.
- De-a lungul acestui rezumat nu am folosit cele mai scurte posibilitati cand am creat functii, intentionat am definit uneori variabile fara a le atribui pe acelasi rand o valoare sau invers, intentionat am creat variabile temporare desi nu era cazul si altele, acestea pentru a se putea observa toate modurile de exprimare.
Referitor la scrierea celui mai scurt cod posibil, redefinesc acum functia adunare():
Cod: Selectaţi tot
int adunare(int nr1, int nr2)
{
return nr1+nr2;
}
Cam atat ar fi de inteles in prima faza despre functii, data viitoare vom continua cu alte probleme legate de acelasi subiect.
Ca tema de casa as cere:
Sa se creeze o functie cu numele int_to_string().
Aceasta sa aiba un parametru de tip int si sa returneze acel int sub forma de string.
Dupa ce este creata functia, urmatorul cod copiat in acelasi document ar trebui sa nu dea eroare:
Cod: Selectaţi tot
void main()
{
int x=29;
string z=int_to_string(x);
alert(“Salut!”, z+“ este egal cu 31 minus 2. Asa-i?”);
exit();
}
O tema rezolvata corect este considerata cea care va contine atat functia definita, cat si codul de mai sus, astfel incat tot scriptul sa fie functional.
Imprimarea acestei intalniri este la link-ul urmator:
Download Fisier MP3 04._Curs_BGT_-_Functiile_Partea1.mp3 (55,5 MB)