azpiprogramak etiketadun mezuak erakusten. Erakutsi mezu guztiak
azpiprogramak etiketadun mezuak erakusten. Erakutsi mezu guztiak

2023(e)ko martxoaren 29(a), asteazkena

Datu-motak eta azpiprogramak


















Azpiprograma batek zer datu-motako emaitza itzul dezake? Galderari erantzuna emateko ondoko iruditik abiatu eta adibideak jarriko dira:










Integer, Real, Boolean, Char, String, Array eta Record datu-motako aldagaiak sarrerakoak izan daitezke azpiprogrametan, bai funtzioetan eta bai prozeduretan. File datu-mota ezin daiteke izan parametro, ez sarrerakoa ez irteerakoa.


Baina...



... Integer, Real, Boolean, Char, String, Array eta Record datu-motako aldagaiak irteerakoak izan behar direnean, zer erabiliko dugu prozedura ala funtzio?





Hona hemen, datu-mota bakoitzeko, erantzuna eta adibideak.








  • INTEGER/REAL:


    • prozedura adibidea: teklatuaren bitartez irakurritako 10 zenbakien artean maximoa zehaztu. Prozedurak bi balio itzuliko ditu: maximoa zenbatgarren zenbakia izan den eta maximoaren balioa. Algoritmo aldetik, FOR-TO-DO bat erabiliko dugu; lehen zenbakia FOR kanpoan irakurri readln bitartez eta aurreneko erreferentzitzat hartu, gero FOR barnean 9 aldiz (for k:=2 to 10 do) ondokoa errepikatu: readln eginez beste zenbaki bat irakurri eta konparaketa eginez handiena gordetzen joan eta dagokion k ere

    • funtzio adibidea: teklatuaren bitartez irakurritako 10 zenbakien metatua kalkulatu. Algoritmo aldetik, FOR-TO-DO bat erabiliko dugu









  • BOOLEAN:


    • prozedura adibidea: urte bat adierazten duen zenbaki oso bat teklatuaren bitartez irakurri eta zenbaki hori prozedura bati pasatu, prozedurak emaitza bikoitza itzuliko dio programa nagusiari: urte horretan Olinpiadarik dagoen ala ez, eta Olinpiaden lekua. Prozedurak hiru parametro izango ditu, bat sarrerakoa eta beste biak irteerakoak. Adibidez:


      • iUrtea: sarrerako parametroa, teklatuz irakurritako zenbaki osoa

      • boOlinpiarJokoak: irteerako emaitza boolearra (bere balio posibleak TRUE edo FALSE)

      • sNon: irteerako karaktere-katea


    • funtzio adibidea: urte bat adierazten duen zenbaki oso bat teklatuaren bitartez irakurri eta funtzio boolear bati pasatu honek erabakiko baitu urtea bisiestoa den ala ez. Funtzioak urtea aztertuko du eta bisisestoa bada TRUE itzuliko du, baina urtea bisiestoa ez bada FALSE itzuliko du 









  • CHAR:


    • prozedura adibidea: teklatuaren bitartez karaktere bat irakurri eta karaktere hori prozedura bati pasatu, prozedurak sarrerako karaktereari dagozkion bi karaktere itzuliko ditu: bere aurrekoa eta bere atzekoa

    • funtzio adibidea: teklatuaren bitartez karaktere bat irakurri eta karaktere hori funtzio bati pasatu, karaktereari dagokion letra minuskula itzuliko du funtzioak. Izan ere, funtzio hori ez dugu zertan programatu behar lowercase funtzio estandarrak lan hori betetzen duelako









  • STRING:


    • prozedura adibidea: teklatuaren bitartez karaktere-kate bat irakurri eta string hori prozedura bati pasatu. Prozedurak bi kate itzuliko ditu batean sarrerako katearen kontsonanteak eta bestean sarrerako katearen bokalak

    • funtzio adibidea: teklatuaren bitartez karaktere-kate bat irakurri eta string hori funtzio bati pasatu. Funtzioak katearen karaktere guztiak hitz larrietan jartzen ditu eta kate berria itzuliko du. Dena den, funtzio hori ez dugu zertan programatu behar upcase funtzio estandarrak lan hori betetzen duelako (bai karaktereekin eta bai kateekin)









  • ARRAY:


    • prozedura adibidea: zenbakiak biltzen dituen array bat prozedura barruan irakurri eta programa nagusiari itzuli

    • funtzio adibidea:









  • RECORD:


    • prozedura adibidea: erregistro baten eremu guztien edukia pantailaratu

    • funtzio adibidea:









  • FILE:


    • prozedura adibidea:

    • funtzio adibidea:





 

2023(e)ko martxoaren 15(a), asteazkena

8. astea | menu bat azpiprogramekin



Programa bakar batek eginkizun desberdinak bildu behar dituenean menu bat erabil daiteke. Adibide honetan hiru aukerako menu bat erakusten da, non hirugarren aukerari esker programa bukaraziko da.


{
Menuaren aukerak hautatzeko funtzio bat.
Aukera bakoitzaren eginkizuna burutzeko prozedura bana.
}
program MenuaAzpiprogramaz;
uses
crt;

{ Menuaren aukera erakutsi eta hautapena aukeratu }
function fncMenua: char;
var
cHautapena: char;
begin
writeln('===============MENUA================');
writeln(' A) alfabeto zatia diagonalean');
writeln(' B) biderkatzeko taula pantailaratu');
writeln;
writeln(' I) irten');
writeln('====================================');
repeat
write(' Zure aukera: ');
cHautapena := readkey;
writeln(cHautapena);
cHautapena := upcase(cHautapena);
until (cHautapena = 'A') or (cHautapena = 'B') or (cHautapena = 'I');

fncMenua := cHautapena;
end;

{ A-tik hasita alfabetoa diagonalki pantailaratu }
procedure DiagonalaPantailanIdatzi(cLetra: char);
var
cKont: char;
iNon: integer;
begin
writeln;
iNon := 5;
for cKont:='A' to cLetra do
begin
writeln(cKont:iNon);
iNon := iNon + 2;
end;
end;

procedure TaulaPantailaratu(iZbk: integer);
var
k: integer;
begin
writeln(iZbk,' zenbakiaren biderkatzeko taula:');
for k:=1 to 10 do
begin
writeln(k:10, ' x ', iZbk:2, ' = ', k*iZbk:3);
end;
writeln;
end;


{ ----------------------PROGRAMA NAGUSIA---------------------- }
var
cAukera, cLetra, cItxoin: char;
iZbk: integer;
begin
repeat
clrscr;

cAukera := fncMenua;
writeln;

case cAukera of
'A': begin
repeat
write('Azken letra eman: ');
cLetra := readkey;
writeln(cLetra);
cLetra := upcase(cLetra);
until (cLetra >= 'A') and (cLetra <= 'Z');
DiagonalaPantailanIdatzi(cLetra);
end;
'B': begin
repeat
write('1 eta 10 arteko zenbaki osoa eman: ');
readln(iZbk);
until (iZbk >= 1) and (iZbk <= 10);
TaulaPantailaratu(iZbk);
end;
'I': begin
writeln('Programa amaitzera doa.');
end ;
end; (* case-rena *)

writeln;
write('Edozein tekla sakatu aurrera egiteko...');
cItxoin := readkey; (* emaitzak ikusi ahal izateko itxaron *)
writeln(cItxoin); (* konpilazio abisua kentzeko *)
until cAukera='I';
end.



 

2023(e)ko martxoaren 3(a), ostirala

7. astea | Taylor azpiprogramaz (edozein angelurako)




7. astea | Taylor (angelu txikiekin) blog-artikuluan ikusi dugu Taylor metodoa nola aplikatzen zaion 0 eta Π/2 artean dagoen sarrerako x angelu bati. Baina eta edozein angelu sartuko bagenu? Ikusitako programak ondo ibiliko lirateke? Kalkulu ahulena zein izan daiteke?




7. astea | Taylor (angelu txikiekin) artikuluko programa aldatzen baduzu sarrerako datua 0.0 gradu eta 360.0 gradu artekoa izan dadin; ikusiko duzu nola 160 graduko angelu batekin ondo dabilela, baina 160.9 graduko angeluarekin programa ez dabilela. Arazoa faktorialaren kalkulu honetan dago:


function fnliFaktoriala(iZbk:integer): longint;
var
j: integer;
liMetatua: longint;
begin
liMetatua := 1;
for j:=1 to iZbk do
begin
liMetatua := liMetatua*j;
//writeln('j=', j, ' ---faktoriala-> ', liMetatua); (* agindu hau indarrean jarri programa ulertzeko *)
end;
fnliFaktoriala := liMetatua;
end;


Faktorialaren kalkulua ondo dago. Baina iZbk datua handia bada, gerta daiteke liMetatua handiegia izatea longint datu-motarako eta orduan funtzioaren emaitza desegokia izango litzateke.



Izan ere, goiko funtzio horretan, faktoriala lortzean emaitza longint datu-motako aldagai batean gordetzen da, eta angelu handiekin faktorialaren balioak longint datu-motak duen muga gainditzen du. Horregatik, 0.0 gradu eta 360.0 gradu arteko angeluekin lan egin ahal izateko, faktorialaren funtzioa aldatuko dugu bere emaitza real datu-motakoa izan dadin.


function fnrFaktoriala(iZbk:integer): real;
var
j: integer;
rMetatua: real;
begin
rMetatua := 1.0;
for j:=1 to iZbk do
begin
rMetatua := rMetatua*j;
//writeln('j=', j, ' ---faktoriala--> ', rMetatua:0:10); (* agindu hau indarrean jarri programa ulertzeko *)
end;
fnrFaktoriala := rMetatua;
end;




Sarrerako angelua oso handia bada, esate baterako 98765.9 graduko angelua sartuko bagenu, hurrengo moldaketa aplikatuko genioke:

Datua den 98765.9 gradu zati 360 egin ondoren, 98765.9/360 eta zatiketaren hondarrarekin geratuko ginateke bere kosinua kalkulatzeko. Zatiketa horren zatidurak adierazten du 98765.9 graduko angeluak zirkuluari zenbat bira ematen dizkion eta kosinuaren kalkulurako garrantzirik ez du. Ez-osoa den zenbaki baten atalak nola lortzen diren gogoratu 2. astea | zenbaki erreal baten atalak artikulua birpasatuz.












 

7. astea | Taylor azpiprogramaz (angelu txikiekin)



Brook Taylor












Brook Taylor britainiar matematikaria 1685ean jaio eta 1731ean hil zen. Zientziaren arazo asko aztertu zituen eta 1715. urtean idatzi zuen Methodus incrementorum directa et inversa, bere lan garrantzitsuena, non kalkulu diferentziala eta funtzio deribatua definitu zituen. Liburu berean agertu ziren Taylorren seriea, diferentzia finituen bidezko kalkulua, ekuazio diferentzialen soluzio bereziak, zatikako integrazio-metodoa, etab.






Taylor serie bidezko hurbilpena


Taylor seriea funtzio batek x puntuaren inguruan hartzen duen
baliora hurbiltzeko erabil daiteke, seriearen batugai zenbait bakarrik
erabiltzen direnean; era honetan, errore bat sortzen da, funtzioaren
balioarekin bat datorren seriea ez baita modu osotuan garatzen:



(a=0 balioa denean, serieari MacLaurin serie deritzo)






Funtzio esponentzialaren eta logaritmikoaren serieak











Funtzio trigonometrikoen serieak











Non Bs Bernouilliren zenbakiak diren.







Ariketa hau egiteko, ikusitako hauek gogoratu Azp-1 (zero bertsioa), Azp-2 (zero bertsioa) eta Azp-3 (zero bertsioa). Klikatu irudi honen gainean eta grafikoki ikusiko duzu Taylor polinomioa kosinu funtzioarentzat:











Lehen bertsioa





Angelu baten kosinua Taylor-ren arabera honela kalkula daiteke:




Non x radianetan emaniko angelua den.




Programa bat idatzi kosinua kalkulatuko duena aurreko segidaren N batugai erabiliz. Batugaien N kopurua ez da ezaguna, batugaiak aintzat hartuko dira azken batugaiaren balio absolutua 0.00001 baino txikiagoa izan arte adibidez (doikuntza hori teklatuaren bitartez emango du programaren erabiltzaileak).




Kasu honetan batukaria kalkulatzen duen azpiprogramak emaitza bakarra itzuli behar duelako funtzio baten bitartez programatuko dugu. Diogunez, azpiprograma hori funtzio bat izango da bere goiburukoa hauxe delarik:



function fnrKosinuaKalkulatu(rX, rDoikuntza: real): real ;




Sarrera: rX radianak (teklatuz irakurritako rAngelua graduak radianetara igarota)


Sarrera: rDoikuntza (gogoratu bertsio honetan doikuntza programa nagusian irakurtzen dela)



Programaren...
TaylorFuntzioz1.pas
...lehen hurbilketa honek x sarrerako angelua 0 eta Π/2 artekoa izan dadila
. Gero, programa ongi dabilenean kodifikazioa aberastu edozein koadranteko angelurako, hau da sarrerako x angelua 0 eta 2Π artekoa izan daitekeela. Amaitzeko, programa osatu edozein angelurako, hots, sarrerako x angelua 2Π baino handiagoa denean ere, laguntza hemen.








Bigarren bertsioa





Demagun orain bigarren bertsio honetan bi aldaketa egingo ditugula. Batetik doikuntza konstante batekin lan egingo dugula, eta bestetik programa nagusiak beste emaitza bat agertu behar duela ere (iterazioen kopurua). Beraz, kosinua kalkulatzeko metodo bera erabiliko dugu baina azpiprogramak itzuli beharko dituen emaitzak bi izango dira:


  1. kosinuaren balioa eta horrez gain

  2. zenbat iteraziotan lortu den kalkulatzea




Gogoratu angelu baten kosinua Taylor-ren arabera honela kalkula daiteke:




Non x radianetan emaniko angelua den.





Programa bat idatzi kosinua kalkulatuko duena aurreko segidaren N batugai erabiliz. Batugaien N kopurua ez da ezaguna, batugaiak aintzat hartuko dira azken batugaiaren balio absolutu konstantea 0.00001 baino txikiagoa izan arte.


Kkasu honetan batukaria kalkulatzen duen azpiprogramak bi emaitza itzuli behar dituelako ezingo da funtzio baten bitartez programatuko. Azpiprograma hori prozedura bat izango da eta bere goiburukoa honelakoxea izango da:




procedure KosinuaKalkulatu(rX: real; var iKont: integer; var rEmaitza: real) ;



Sarrera: rX angelua radianetan (gogoratu bertsio honetan doikuntza konstante bat dela)


Irteera: iKont iterazioen kopurua


Irteera: rEmaitza kosinuaren kalkulua



Programaren...
TaylorProzeduraFuntzioak.pas
...bigarren bertsio honek x sarrerako angelua 0 eta Π/2 artekoa izan dadila
. Gero, programa ongi dabilenean kodifikazioa aberastu edozein koadranteko angelurako, hau da sarrerako x angelua 0 eta 2Π artekoa izan daitekeela. Amaitzeko, programa osatu edozein angelurako, hots, sarrerako x angelua 2Π baino handiagoa denean ere, laguntza hemen.











Doikuntza konstante bat izanik:


{ Faktorialaren emaitza longint datu-motakoa da }
program KosinuaTaylorBitartez_LehenKoadrantea;
uses
crt;
const
rDOITASUNA = 0.0009; (* kalkuluaren prezisioa, bederatzi hamarmilaren *)

function fnliFaktoriala(iZbk:integer): longint;
var
j: integer;
liMetatua: longint;
begin
liMetatua := 1;
for j:=1 to iZbk do
begin
liMetatua := liMetatua*j;
//writeln('j=', j, ' ---faktoriala-> ', liMetatua); (* agindu hau indarrean jarri programa ulertzeko *)
end;
fnliFaktoriala := liMetatua;
end;


function fnrBerreketa(rX:real; iZbk:integer): real;
var
k: integer;
rMetatua: real;
begin
rMetatua := 1;
for k:=1 to iZbk do
begin
rMetatua := rMetatua*rX;
//writeln('k=', k, ' ===berredura==> ', rMetatua:0:5); (* agindu hau indarrean jarri programa ulertzeko *)
end;
fnrBerreketa := rMetatua;
end;


function fnrKosinuaKalkulatu(rX: real): real;
var
rKosinua, rBerrek, rBatugaia: real;
iZeinua, iKont: integer;
liFakt: longint;
begin
rKosinua := 1.0; (* lehen iterazioa kanpoan *)
iZeinua := -1;
iKont := 2;
//writeln('Hasi-hasieran... rKosinua = ':18, rKosinua:0:10); (* agindu hau indarrean jarri programa ulertzeko *)
//writeln; (* agindu hau indarrean jarri programa ulertzeko *)

repeat
liFakt := fnliFaktoriala(iKont);
rBerrek := fnrBerreketa(rX, iKont);

rBatugaia := iZeinua*rBerrek/liFakt;
rKosinua := rKosinua + rBatugaia;

//writeln('rBatugaia = ', rBatugaia:13:10, 'rKosinua = ':22, rKosinua:0:10); (* agindu hau indarrean jarri programa ulertzeko *)
//writeln('DOITASUNA = ', rDOITASUNA:13:10); (* agindu hau indarrean jarri programa ulertzeko *)
//writeln; (* agindu hau indarrean jarri programa ulertzeko *)

iZeinua := iZeinua*(-1);
iKont := iKont + 2;
until abs(rBatugaia) < rDOITASUNA;

fnrKosinuaKalkulatu := rKosinua;
end;


(* -------------------------PROGRAMA NAGUSIA--------------------------- *)
var
rGraduak: real; (* angelua graduetan *)
rX: real; (* angelua radianetan *)
rKos: real;
begin
clrscr;
repeat
write('Lehenengo koadranteko angelu bat eman gradutan: ');
readln(rGraduak);
if (rGraduak < 0.0) or (rGraduak >= 90.0) then
writeln('Angelua 0.0 eta 89.999 artekoa izan dadila');
until (rGraduak >= 0.0) and (rGraduak < 90.0);

rX := rGraduak*2*PI/360;

writeln(rGraduak:0:3, ' gradu = ', rX:0:5, ' radian');
writeln;

rKos := fnrKosinuaKalkulatu(rX);

writeln('kos(', rX:0:3, ') = ', rKos:0:10);
writeln('cos(', rX:0:3, ') = ', cos(rX):0:10);
writeln;
writeln('==============================');
writeln('Edozein tekla sakatu amaitzeko');
writeln('==============================');

repeat until keypressed;
end.



 

7. astea | menu bat azpiprogramaz


















Bost aukerako menu baten bitartez gidatzen den programa bat daukagu. Aukerak hautatzeko karaktereak erabiltzen dira eta bostetatik aukera batek programa bukarazten du. Hautatutako aukerari esker CASE-OF agindu baten bitartez gidatzen da programaren exekuzioa. Menua aurkezteko eta aukeraren bat hautatzeko lana fncAukeraHautatu funtzio honek egiten du:







Programa nagusia, funtsean, prozesu errepikakor bat da, errepikapenak eteteko eta programatik irteteko I edo i karakterea sartu behar da. Ikusi ditzagun, banan-banan gainerako lau aukerak.








A aukera



fncAukeraHautatu funtzioan irakurritako A edo a karakterea programa nagusira helduko da eta programa nagusian DiagonalkiPantailaratu prozeduraren sarrrera den karakterea irakurriko da (prozedura horrek datu bakar bat behar du, alfabeto larriaren letra bat). DiagonalkiPantailaratu prozedurak jarraian erakusten den mezua emateko gai da:












B aukera




fncAukeraHautatu funtzioan irakurritako B edo b karakterea programa nagusira helduko da eta programa nagusian TaulaPantailaratu prozeduraren sarrrera den zenbaki osoa irakurriko da (prozedura horrek datu bakar bat behar du, 0 eta 9 arteko zenbaki osoa). TaulaPantailaratu prozedurak jarraian erakusten den mezua emateko gai da:













C aukera




fncAukeraHautatu funtzioan irakurritako C edo c karakterea programa nagusira helduko da eta programa nagusian fnrErroKuboaKalkulatu funtzioaren sarrrera den zenbaki erreala irakurriko da (funtzio horrek datu bakar bat behar du, zenbaki erreala eta positiboa). fnrErroKuboaKalkulatu funtzioaren deia egin ondoren, programa nagusian jarraian erakusten den mezuaren bezalakoak agertuko dira:













D aukera




fncAukeraHautatu funtzioan irakurritako D edo d karakterea programa nagusira helduko da eta programa nagusian fnboFibonaccikoaDa funtzioaren sarrrera den zenbaki erreala irakurriko da (funtzio horrek datu bakar bat behar du, 3 eta 17000 arteko zenbaki osoa). fnboFibonaccikoaDa funtzioaren deia egin ondoren, programa nagusiari balio boolear itzuliko dio eta balio boolear horren arabera programak honelako mezuak erakutsiko ditu:


















Hona hemen MenuBatAzpiprogramaz.pas adibidearen iturburu-programa:




program MenuBatAzpiprogramaz ;
uses
crt ;

function fncAukeraHautatu: char ;
var
cHautapena: char ;
begin
writeln('==========================Menua==========================') ;
writeln(' A Alfabeto zatia diagonalki') ;
writeln(' B Biderkatzeko taula marraztu') ;
writeln(' C Zenbaki baten erro kuboa Newton-Raphson bitartez') ;
writeln(' D Zenbaki bat Fibonacciren sekuentziakoa da?') ;
writeln ;
writeln(' I Programatik irten') ;
writeln('=========================================================') ;
write(' Zure aukera: ') ;

repeat
cHautapena := readkey ;
cHautapena := upcase(cHautapena) ;
writeln(cHautapena) ;

if (cHautapena < 'A') or (cHautapena > 'D') and (cHautapena <> 'I') then
begin
write('Aukera ez da ondo hautatu. Berriro aukeratu: ') ;
end ;
until (cHautapena >= 'A') and (cHautapena <= 'D') or (cHautapena = 'I') ;

fncAukeraHautatu := cHautapena ;
end ;


procedure DiagonalkiPantailaratu(cLetra: char) ;
var
k: char ;
iNon: integer ;
begin
writeln('Alfabeto zatia diagonalki pantailaratu:') ;

iNon := 15 ;
for k:='A' to cLetra do
begin
writeln(k:iNon) ;
iNon := iNon + 1 ;
end ;
writeln ;
end ;


procedure TaulaPantailaratu(iZbk : integer) ;
var
k: integer ;
begin
writeln(iZbk,' zenbakiaren biderkatzeko taula:') ;
for k:=1 to 10 do
begin
writeln(k:35, ' x ', iZbk, ' = ', k*iZbk:2) ;
end ;
writeln ;
end ;


function fnrErroKuboaKalkulatu(rZbk: real): real ;
var
rEpsilon, rKuboa, rAurrekoa : real ;
begin
rEpsilon := 0.000000001 ;
rKuboa := rZbk / 3.0 ; (* lehendabiziko hurbilketa *)

repeat
rAurrekoa := rKuboa ;
rKuboa := (rZbk / (rAurrekoa*rAurrekoa) + 2*rAurrekoa) / 3 ;
rKuboa := rAurrekoa - (rAurrekoa*rAurrekoa*rAurrekoa - rZbk) / (3*rAurrekoa*rAurrekoa) ;
//writeln('rAurrekoa =':14, rAurrekoa:22:16, 'rKuboa =':20, rKuboa:22:16) ;
until abs(rKuboa - rAurrekoa) <= rEpsilon ;

fnrErroKuboaKalkulatu := rKuboa ;
end ;


function fnboFibonaccikoaDa(iZbk: integer): boolean ;
var
iFibo1, iFibo2, iFibo3: integer ;
begin
iFibo1 := 0 ;
iFibo2 := 1 ;
iFibo3 := iFibo1 + iFibo2 ;
while iFibo3 < iZbk do
begin
iFibo1 := iFibo2 ;
iFibo2 := iFibo3 ;
iFibo3 := iFibo1 + iFibo2 ;
writeln('iFibo3 = ':20, iFibo3) ;
end ;

if iFibo3 = iZbk then
fnboFibonaccikoaDa := TRUE
else
fnboFibonaccikoaDa := FALSE ;
end ;


{ ----------------------PROGRAMA NAGUSIA---------------------- }
var
cAukera, cItxoin, cLetra: char ;
iZbk: integer ;
rZbk, rKuboa: real ;
begin
repeat
clrscr ;
cAukera := fncAukeraHautatu ;

writeln ;
case cAukera of
'A' : begin
repeat
write('A eta Z arteko letra bat eman: ') ;
readln(cLetra) ;
cLetra := upcase(cLetra) ;
until (cLetra >= 'A') and (cLetra <= 'Z') ;
DiagonalkiPantailaratu(cLetra) ;
end ;
'B' : begin
repeat
write('0 eta 9 arteko zenbaki osoa eman: ') ;
readln(iZbk) ;
until (iZbk >= 0) and (iZbk <= 9) ;
TaulaPantailaratu(iZbk) ;
end ;
'C' : begin
repeat
write('Zenbaki erreala eta positiboa eman: ') ;
readln(rZbk) ;
until rZbk >= 0.0 ;
rKuboa := fnrErroKuboaKalkulatu(rZbk) ;
writeln(rZbk:0:5 , '-ren erro kuboa: ', rKuboa:0:5) ;
end ;
'D' : begin
repeat
write('3 eta 17000 arteko zenbaki osoa eman: ') ;
readln(iZbk) ;
until (iZbk >= 3) and (iZbk <= 17000) ;
if fnboFibonaccikoaDa(iZbk) then
writeln(iZbk , ' Fibonacciren sekuentziakoa da')
else
writeln(iZbk , ' ez da Fibonacciren sekuentziakoa')
end ;
'I' : begin
writeln('Programa amaitzera doa. Edozein tekla sakatu.') ;
end ;
end ;

cItxoin := readkey ; (* emaitzak ikusi ahal izateko itxaron *)
writeln(cItxoin) ; (* konpilazio abisua kentzeko *)
until cAukera='I' ;
end.

 


7. astea | karaktere bereziak


















Programa honetan karaktere bereziak erabiltzen dira, karaktere
grafikoak. Ikusi ere programa zatika egiten dela, hots, badirela zenbait
prozedura gauza jakinak egiten dituztela. Programa bat modulutan
banatzen laster ikasiko dugu, orain karaktere berezietan arreta jarri
eta identifikatu prozedura bakoitzak zer egiten duen eta nola egiten
duen.



Hauek dira prozeduren izenak:


  • TeilatuaMarraztu prozedura

  • LeihoakMarraztu prozedura

  • AtariaMarraztu prozedura

  • LurzoruaMarraztu prozedura





Eta hauek dira emaitzaren bi irudi:






Lehen irudia programaren irteera da eta bigarrenean azpiprogramak adierazi dira







Mac sistemetan karaktere bereziak ez dira pantailaratzen hemen erakusten den bezala




Eta bukatzeko, hona hemen iturburu-programa:










Programa ondo ulertzeko gogoratu ASCII taula bi zatitan banaturik ematen dela: ASCII estandar eta ASCII hedatua taulak.




Hona hemen ASCII estandar taulari dagokion irudi bat:









Ikusi zenbakien (0, 1, 2, ..., 9) kokapena zein den. Berdin alfabetoa letra larrietan emanik eta alfabetoa minuskuletan emanik.



Hauxe da ASCII hedatua taulari dagokion irudi bat:







Ikusi ñ eta Ñ karaktereak non dauden. Berdin zenbait karaktere grafiko edo alfabeto grekoaren zenbait karaktere. Ikusi ere sinbolo bereziak ere biltzen direla.


 

2023(e)ko otsailaren 24(a), ostirala

Errekurtsibitatea zertan den

















Ez dugu ariketa errekurtsibo asko aurkituko gure programetan, baina interesgarria da kontzeptu hori lantzea azpiprogramak aktibatzen direnean zer gertatzen den ikasteko.



Egoera errekurtsiboak bizitzan eta naturan ematen dira eta jarraian adibide grafikoak erakusten dira:






























Faktoriala funtzio errekurtsibo bezala



iZenbaki zenbaki baten faktoriala kalkulatzen duen funtzio errekurtsiboa erakusten da jarraian. Faktorialaren kalkulu errekurtsiboa algoritmo honetan oinarritzen da:


iZenbaki! = iZenbaki * (iZenbaki - 1)!



program FaktorialErrekurtsiboaAzaltzen ;

function fnliFaktorialaKalkulatu(iZbk: integer) : longint ;
begin
if iZbk = 1 then
begin
WriteLn('1! badakit kalkulatzen, itzuli 1 modulu deitzaileari') ;
fnliFaktorialaKalkulatu := 1 ;
end
else
begin
writeln(iZbk, '! kalkulatzeko ', iZbk-1, '! ezagutu behar dut') ;
fnliFaktorialaKalkulatu := iZbk * fnliFaktorialaKalkulatu(iZbk - 1) ;
writeln(iZbk, '! kalkulatu dut ', iZbk-1, '! * ', iZbk, ' eginez') ;
end ;
end ;


var
liEmaitza : longint ;
iDatua : integer ;

begin
repeat
write('Eman zenbaki osoa: ') ;
readln(iDatua) ;
until iDatua > 0 ;
liEmaitza := fnliFaktorialaKalkulatu(iDatua) ;
writeln(iDatua, '! = ', liEmaitza) ;
readln ;
end.










FaktorialErrekurtsiboa.pas programa hartu eta zuk zeuk exekutatu.


















Fibonacciren zenbakiak funtzio errekurtsibo bidez



Fibonacciren segidaren adierazpen orokorra gogoratuz:

{\displaystyle F_{n}={\begin{cases}0&n=0{\mbox{ bada}}\\1&n=1{\mbox{ bada}}\\F_{n-1}+F_{n-2}&n>1{\mbox{ bada}}\\\end{cases}}}



Hauxe da fniFibonacci funtzio errekurtsiboa:

{-------------------------FUNTZIO ERREKURTSIBOA-------------------------}
function fniFibonacci(iZbk: integer): integer ;
begin
if (iZbk = 0) or (iZbk = 1) then
fniFibonacci := iZbk
else
fniFibonacci := fniFibonacci(iZbk-1) + fniFibonacci(iZbk-2) ;
end ;


Teklatuaren bitartez iZenbat kopuru oso bat irakurri eta Fibonacci-ren lehen iZenbat zenbakiak pantailaratu. Hauxe da programa eta bere exekuzioaren irteera bat:


program FibonacciErrekurtsiboa ;
uses
crt ;
const
AZKENMUGA = 24 ; { integer datu-motak ez du gehiago ematen }


{-------------------------FUNTZIO ERREKURTSIBOA-------------------------}
function fniFibonacci(iZbk: integer): integer ;
begin
if (iZbk = 0) or (iZbk = 1) then
fniFibonacci := iZbk
else
fniFibonacci := fniFibonacci(iZbk-1) + fniFibonacci(iZbk-2) ;
end ;


{---------------------------PROGRAMA NAGUSIA---------------------------}
var
iZenbat, iKont: integer ;
cErantzuna: char ;
begin
writeln ;
repeat
repeat
write('Eman Fibonacci segidaren zenbaki kopurua (1 eta ', AZKENMUGA,' artekoa): ') ;
readln(iZenbat) ;
until (iZenbat >= 1) and (iZenbat <= AZKENMUGA) ;

writeln ;

for iKont:=1 to iZenbat do
begin
if (iKont = 1) or (iKont = 2) then
writeln(iKont:20, ' >>>>>> ', fniFibonacci(iKont-1))
else
writeln(iKont:20, ' -----> ', fniFibonacci(iKont-1)) ;
end ;

writeln ;

write('Amaitu nahi duzu? (B/E): ') ;
repeat
cErantzuna := readkey ;
writeln(cErantzuna) ;
cErantzuna := upcase(cErantzuna) ;
until (cErantzuna = 'B') or (cErantzuna = 'E') ;
writeln ;
writeln ;
until cErantzuna = 'B' ;

write('Programa bukatu da') ;

repeat until keypressed ;
end.







Goiko programa hobeto ulertzeko, aztertu ere FibonacciErrekurtsiboa_formatua.pas bertsioa non pantailan idazketa batzuk egiten diren, eta horiei esker programa exekutatzean ikus daiteke kodearen zein puntutan aurkitzen garen.



 

Azpiprogramak: Divide et Impera




Azpiprogramak → Divide et Impera










program AzpiprogramenParametroak_01 ;
uses
crt;

procedure Gehitu5Gehiago (Zenbaki1: integer; Zenbaki2: integer);
begin
textcolor(Cyan);
writeln(' Gehitu5Gehiago BARRUAN, batuketa egin baino LEHEN: ',
Zenbaki1:4, Zenbaki2:4);
Zenbaki1 := Zenbaki1 + 5;
Zenbaki2 := Zenbaki2 + 5;
writeln(' Gehitu5Gehiago BARRUAN, batuketa egin ONDOREN: ',
Zenbaki1:4, Zenbaki2:4);
textcolor(LightGray);
end;

{------------------------ Programa Nagusia ------------------------}
var
iKopuru1, iKopuru2: integer;
begin
iKopuru1 := 10;
iKopuru2 := 20;
writeln('PROGRAMA NAGUSIAN Gehitu5Gehiago deitu AURRETIK: ',
iKopuru1:4, iKopuru2:4);
writeln;

Gehitu5Gehiago(iKopuru1, iKopuru2);

writeln;
writeln('PROGRAMA NAGUSIAN Gehitu5Gehiago deitu ONDOREN: ',
iKopuru1:4, iKopuru2:4);
writeln;
readln;
end.









































1 Uneko parametroak eta parametro formalak



Programa bat daukagu Gehitu5Gehiago izeneko prozedurari deia egiten diona, honako hauek ikusi:


  • Gehitu5Gehiago prozedurak bi parametro ditu, biak integer datu-motatakoak

  • Gehitu5Gehiago prozeduraren bi parametroak sarrerakoak dira

  • Gehitu5Gehiago prozedurari deia egiteko sententzia bezala idazten da

  • Gehitu5Gehiago prozedurari deia egitean uneko parametroak komaz banatzen dira

  • Gehitu5Gehiago prozeduraren parametro formalak puntu eta komaz banatzen dira


AzpiprogramenParametroak_01.pas programaren bitartez zer ikasi duzu?





2 Sarrerako parametroak



Programa bat daukagu Gehitu5Gehiago prozeduraren parametroak sarrerakoak direla ikusi, honako frogak egin:


  • AzpiprogramenParametroak_02 programa exekutatu eta emaitza aztertu

  • AzpiprogramenParametroak_02 programaren emaitza aztertu aldaketa hauek eginez:


    • iKopuru1 uneko parametroaren balioa 100 izan dadila

    • iKopuru2 uneko parametroaren balioa 200 izan dadila


  • Gehitu5Gehiago prozedura barruko parametroen izenak aldatu:


    • Zenbaki1 parametro formala iKopuru1 izendatu

    • Zenbaki2 parametro formala iKopuru2 izendatu


  • Gehitu5Gehiago prozeduraren deian uneko parametroak elkar trukatu:


    • iKopuru1 uneko parametroaren posizioan iKopuru2 idatzi

    • iKopuru2 uneko parametroaren posizioan iKopuru1 idatzi


  • Gehitu5Gehiago prozeduraren deia aldatu adierazpen matematiko hauek jarriz:


    • Gehitu5Gehiago(iKopuru1 + 10, iKopuru2 + 20) ;


  • Gehitu5Gehiago prozeduraren deia aldatu konstante hauek jarriz:


    • Gehitu5Gehiago(11, 22) ;



AzpiprogramenParametroak_02.pas programaren bitartez zer ikasi duzu?




3 Uneko parametro eta parametro formalen arteko bateragarritasuna



Gehitu5Gehiago prozeduraren parametroen datu-motak aldatu, honako frogak egin:


  • AzpiprogramenParametroak_03 programaren hasieran parametro guztiak integer dira:


    • iKopuru1 eta iKopuru2 aldagaiak integer bezala erazagutu dira

    • Zenbaki1 eta Zenbaki2 parametro formalak integer dira ere


  • Gehitu5Gehiago prozeduraren parametro formal baten datu-mota aldatu:


    • Zenbaki1 parametro formala integer bezala mantendu

    • Zenbaki2 parametro formala real datu-motara aldatu

    • iKopuru1 eta iKopuru2 uneko parametroak integer bezala mantendu


  • Gehitu5Gehiago prozeduraren deian uneko parametro baten datu-mota aldatu:


    • Zenbaki1 parametro formala integer bezala mantendu

    • Zenbaki2 parametro formala integer bezala berriro jarri

    • iKopuru1 uneko parametroa integer bezala mantendu

    • iKopuru2 uneko parametroari datu-mota aldatu real jarriz



AzpiprogramenParametroak_03.pas programaren bitartez zer ikasi duzu?




4 Irteerako parametroak



Gehitu5Gehiago prozeduraren parametro bat irteerakoa izanik, honako frogak egin:


  • Gehitu5Gehiago prozedura hasierakoa da eta lehen bezala:


    • Zenbaki1 parametro formala integer izanik sarrerakoa da

    • Zenbaki2 parametro formala integer izanik sarrerakoa da


  • Programa exekutatu Gehitu5Gehiago prozeduraren deia hasierako hau delarik:


    • Gehitu5Gehiago(iKopuru1, iKopuru2) ;


  • Programa exekutatu Gehitu5Gehiago prozeduraren deia aldatu adierazpen matematiko hauek jarriz:


    • Gehitu5Gehiago(iKopuru1 + 10, iKopuru2 + 20) ;


  • Aldaketa, Gehitu5Gehiago prozeduraren parametro formal baten datu-mota aldatu:


    • iKopuru1 eta iKopuru2 uneko parametroak integer dira

    • Zenbaki1 parametro formala integer bezala mantendu

    • Zenbaki2 parametro formala real datu-motara aldatu



    • Gehitu5Gehiago prozedura berriarekin, programa exekutatu deiak hauek direla:


      • Gehitu5Gehiago(iKopuru1, iKopuru2) ;

      • Gehitu5Gehiago(iKopuru1 + 10, iKopuru2) ;

      • Gehitu5Gehiago(iKopuru1, iKopuru2 + 20) ;


    • Gehitu5Gehiago hasierako egoera berreskuratu (parametro bat sarrerakoa eta bestea irteerakoa) eta prozeduraren deia aldatu konstante hauek jarriz:


      • Gehitu5Gehiago(11, 22) ;



    AzpiprogramenParametroak_04.pas programaren bitartez zer ikasi duzu?




    5 Aldagai orokorrak



    iKopuru1 eta iKopuru2 aldagaiak non erazagutzen diren garrantzitsua da:


    • Gehitu5Gehiago prozedura barruko lehen esleipena aldatu hau idatziz:


      • iKopuru1 := Zenbaki1 + 5 ;

      • Ikusi iKopuru1 eta iKopuru2 aldagaiak prozedura baino lehenago erazaguturik daudela


    • Gehitu5Gehiago prozedura barruko esleipen berria mantenduz, iKopuru1 eta iKopuru2 aldagaiak tokiz aldatu:


      • iKopuru1 := Zenbaki1 + 5 ;

      • iKopuru1 eta iKopuru2 aldagaiak prozedura eta gero erazagutu



    AzpiprogramenParametroak_05.pas programaren bitartez zer ikasi duzu?




    6 Bertako aldagaiak



    Gehitu5Gehiago prozeduraren barruan aldagai laguntzaileak sortuko ditugu, egiteko daukagun asmoa hauxe da urratsez-urrats:


    1. iLaguntzaile1 izeneko aldagaia sortu integer bezala

    2. iLaguntzaile1 izeneko aldagaiari hasieraketarik ez egin eta...

    3. ...iLaguntzaile1 aldagaiaren balioa pantailaratu prozedura barruan


    Gehitu5Gehiago prozeduraren bertako aldagaiak iker ditzagun:


    • Aurrekoa egin bi aldagai laguntzaile sortuz:


      • var iLaguntzaile1, iLaguntzaile2 : integer ;

      • iLaguntzaile1 eta iLaguntzaile2 aldagaiei hasieraketarik ez egin eta...

      • writeln('    iLaguntzaile1 = ', iLaguntzaile1, '      iLaguntzaile2 = ', iLaguntzaile2) ;


    • Aurrekoa errepikatu bi aldagai laguntzaileen sorreran ordena trukatuz:


      • var iLaguntzaile2, iLaguntzaile1 : integer ;

      • iLaguntzaile1 eta iLaguntzaile2 aldagaiei hasieraketarik ez egin eta...

      • writeln('    iLaguntzaile1 = ', iLaguntzaile1, '      iLaguntzaile2 = ', iLaguntzaile2) ;


    • Programa nagusian lan eginez iKopuru1 eta iKopuru2 aldagaien balioak pantailaratu

    • Programa nagusian lan eginez iLaguntzaile1 eta iLaguntzaile2 aldagaien balioak pantailaratu



      AzpiprogramenParametroak_06.pas programaren bitartez zer ikasi duzu?




      7 Funtzioak



      Programa bat daukagu fniBatuBiEtaGehitu5Gehiago izeneko funtzioari deitzen diona, honako hauek ikusi:


      • fniBatuBiEtaGehitu5Gehiago funtzioak bi parametro ditu, biak integer datu-motatakoak

      • fniBatuBiEtaGehitu5Gehiago funtzioaren bi parametroak sarrerakoak dira.

      • fniBatuBiEtaGehitu5Gehiago funtzioak irteera bakarra du eta integer datu-motatakoa da

      • fniBatuBiEtaGehitu5Gehiago funtzioari deia egitean esleipen bat idatziko da

      • fniBatuBiEtaGehitu5Gehiago funtzioaren deia adierazpen aritmetiko batean ager daiteke

      • fniBatuBiEtaGehitu5Gehiago funtzioaren deia beste azpiprograma baten uneko parametroa izan daiteke

      • fniBatuBiEtaGehitu5Gehiago funtzioak emaitza itzuliko dio programa nagusiari, emaitza den balio hori itzultzeko fniBatuBiEtaGehitu5Gehiago etiketa erabiliko du


      AzpiprogramenParametroak_07.pas programaren bitartez zer ikasi duzu?




      8 Faktoriala kalkulatzen duen funtzio iteratiboa



      iZenbaki zenbaki baten faktoriala kalkulatzen duen funtzioak eragiketa hau egin behar du eta horretarako FOR-DO egitura bat erabil daiteke:


      • iZenbaki! = 1 * 2 * 3 * ... (iZenbaki - 1) * iZenbaki





        program FaktorialaKalkulatzen ;

        function fnliFaktoriala(iZbk:integer) : longint ;
        var
        k : integer ;
        liMetatua : longint ;
        begin
        liMetatua := 1 ;
        for k:=1 to iZbk do
        begin
        liMetatua := liMetatua*k ;
        WriteLn(k, ' ---> ', liMetatua) ;
        end ;
        fnliFaktoriala := liMetatua ;
        end ;


        var
        liEmaitza : longint ;
        iDatua : integer ;
        begin
        repeat
        write('Eman zenbaki osoa: ') ;
        readln(iDatua) ;
        until iDatua > 0 ;
        liEmaitza := fnliFaktoriala(iDatua) ;
        writeln(iDatua, '! = ', liEmaitza) ;
        readln ;
        end.






        Programa horretan fnliFaktoriala() funtzioari dei bakar bat egiten zaio,  programa nagusian liEmaitza aldagaiari balioa ematen zaio baino lehenago iDatua aldagaiaren balioa teklatuaren bitartez irakurri dugu. fnliFaktoriala() funtzioaren kodifikazioan FOR-DO egitura bat behar dugu eta hura kontrolatzeko k aldagaia behar dugu, faktoriala kalkulatzen duen liMetatua aldagaia beharko dugu ere.



        fnliFaktoriala() funtzioak programa nagusiari emaitza itzultzeko fnliFaktoriala etiketa erabili behar da derrigorrez, bestela liMetatua aldagaiak faktorialaren balioa gordeko du baina programa nagusiari ez zaio inolaz ere helduko.









        AzpiprogramenParametroak_08.pas programaren bitartez zer ikasi duzu?














        9 Errekurtsibitatea






        Gehitu5Gehiago prozedurari deituko diogu Gehitu5Gehiago prozeduraren barrutik:


        • Gehitu5Gehiago prozedura barruko esleipenak mantendu baina IF-THEN bat gehitu, honelaxe:


          • Zenbaki1 := Zenbaki1 + 5 ;

          • if Zenbaki1 <= 25 then Gehitu5Gehiago(Zenbaki1, Zenbaki2) ;

          • Zenbaki2 := Zenbaki2 + 5 ;


        • Aurrekoa errepikatu baina Zenbaki1 parametro formala irteerakoa izanik:


          • procedure Gehitu5Gehiago (var Zenbaki1: integer; Zenbaki2: integer) ;


        • Aurrekoa errepikatu IF-THEN egitura kenduz eta dei errekurtsiboa mantenduz:


          • Zenbaki1 := Zenbaki1 + 5 ;

          • Gehitu5Gehiago(Zenbaki1, Zenbaki2) ;

          • Zenbaki2 := Zenbaki2 + 5 ;








          AzpiprogramenParametroak_09.pas programaren bitartez zer ikasi duzu?












          10 Faktoriala kalkulatzen duen funtzio errekurtsiboa






          iZenbaki zenbaki baten faktoriala kalkulatzen duen funtzio errekurtsiboa erakusten da jarraian. Faktorialaren kalkulu errekurtsiboa algoritmo honetan oinarritzen da:


          • iZenbaki! = iZenbaki * (iZenbaki - 1)!





            program FaktorialErrekurtsiboa ;

            function fnliFaktoriala(iZbk:integer) : longint ;
            begin
            writeln('Dei errekurtsiboa baino lehen ---> ', iZbk) ;   
            if iZbk = 1 then
            fnliFaktoriala := 1
            else
            fnliFaktoriala := iZbk * fnliFaktoriala(iZbk - 1) ;
            writeln ('Dei errekurtsiboa eta gero ------> ', iZbk) ;   
            end ;


            var
            liEmaitza : longint ;
            iDatua : integer ;

            begin
            repeat
            write('Eman zenbaki osoa: ') ;
            readln(iDatua) ;
            until iDatua > 0 ;
            liEmaitza := fnliFaktoriala(iDatua) ;
            writeln(iDatua, '! = ', liEmaitza) ;
            readln ;
            end.








            AzpiprogramenParametroak_10.pas programaren bitartez zer ikasi duzu? Azalpenak eta irudiak ikusteko Errekurtsibitatea zertan den izeneko blog-artikulua irakurri.