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?
Hemen laburpena eta jarraian adibideak:
Integer, Real, Boolean, Char eta String datu-motak programa nagusiari itzultzeko, bai prozedura batean eta bai funtzio batean programa daiteke
Array eta Record datu-motak programa nagusiari itzultzeko, beti prozedura erabiliko dugu eta funtziorik ez dugu erabiliko
File datu-mota ez dugu azpiprogrametara pasako, ez sarrera bezala ezta irteera bezala
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
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.
{ KateakLantzekoBaliabideak programan delete(), insert(), copy() }
{ eta pos() azpiprogramen alternatibak kodetu dira. }
program KateakLantzekoBaliabideak;
uses
crt;
function fncAukeraHautatu: char;
var
cHautapena: char;
begin
writeln('===========================Menua============================');
writeln(' A delete() prozeduraren bezalako fnsEzabatu() funtzioa');
writeln(' B insert() prozeduraren bezalako fnsTxertatu() funtzioa');
writeln(' C copy() funtzioaren bezalako kopiatu() prozedura');
writeln(' D pos() funtzioaren bezalako kokatu() prozedura');
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;
function fnsEzabatu(sDatua: string; iNondik, iZenbat: integer): string;
var
sEmaitza: string;
iKont: integer;
begin
sEmaitza := '';
for iKont:=1 to iNondik-1 do
begin
sEmaitza := sEmaitza + sDatua[iKont];
writeln(iKont:10, sDatua[iKont]:10);
end;
for iKont:=iNondik+iZenbat to length(sDatua) do
begin
sEmaitza := sEmaitza + sDatua[iKont];
writeln(iKont:14, sDatua[iKont]:10);
end;
fnsEzabatu := sEmaitza;
end;
function fnsTxertatu(sAzpikatea, sDatua: string; iNondik: integer): string;
var
sEmaitza: string;
iKont: integer;
begin
sEmaitza := '';
for iKont:=1 to iNondik-1 do
begin
sEmaitza := sEmaitza + sDatua[iKont];
writeln(iKont:10, sDatua[iKont]:10);
end;
for iKont:=1 to length(sAzpikatea) do
begin
sEmaitza := sEmaitza + sAzpikatea[iKont];
writeln(iKont:12, sAzpikatea[iKont]:10);
end;
for iKont:=iNondik to length(sDatua) do
begin
sEmaitza := sEmaitza + sDatua[iKont];
writeln(iKont:14, sDatua[iKont]:10);
end;
fnsTxertatu := sEmaitza;
end;
procedure kopiatu(sDatua: string; iNondik, iZenbat: integer; var sEmaitza: string);
var
iKont: integer;
begin
sEmaitza := '';
for iKont:=iNondik to iNondik+iZenbat-1 do
begin
sEmaitza := sEmaitza + sDatua[iKont];
writeln(iKont:10, sDatua[iKont]:10);
end;
end;
procedure kokatu(sAzpikatea, sDatua: string; var iNon: integer);
var
iKont, k, i: integer;
boAurkitua, boDesberdinak: boolean;
begin
boAurkitua := FALSE;
iKont := 1;
while (iKont <= length(sDatua)) and not boAurkitua do
begin
boDesberdinak := FALSE;
k := iKont;
i := 1;
while (k < iKont+length(sAzpikatea)) and not boDesberdinak do
begin
writeln('iKont=', iKont:2, 'k=':6, k:2, sDatua[k]:6, 'i=':6, i:2, sAzpikatea[i]:6, 'boDesberdinak=':18, boDesberdinak:5);
if sDatua[k] <> sAzpikatea[i] then
boDesberdinak := TRUE
else
begin
k := k +1;
i := i +1;
end;
end;
if boDesberdinak = FALSE then
boAurkitua := TRUE
else
iKont := iKont +1;
end;
if boAurkitua then
begin
iNon := iKont;
writeln('boAurkitua=', boAurkitua:5, 'iNon=Kont=':15, iNon:2);
end
else
begin
iNon := 0;
writeln('boAurkitua=', boAurkitua:5, 'iNon=':10, iNon:2);
end;
writeln;
end;
{ ----------------------PROGRAMA NAGUSIA---------------------- }
var
cAukera, cItxoin: char;
iNon: integer;
sDatua, sEmaitza: string;
sAzpikatea: string;
iNondik, iZenbat: integer;
begin
repeat
clrscr;
cAukera := fncAukeraHautatu;
writeln;
case cAukera of
'A' : begin
writeln('sDatua emanik, fnsEzabatu() funtzioa kodetu delete() prozedurarena betetzeko');
writeln;
writeln(' procedure delete(var sKatea: string;');
writeln(' iNondik: integer;');
writeln(' iZenbat: integer);');
writeln;
writeln(' function fnsEzabatu( sDatua: string;');
writeln(' iNondik: integer;');
writeln(' iZenbat: integer): string;');
writeln;
write('sDatua eman: ');
readln(sDatua);
writeln('sDatua |', sDatua, '|');
repeat
write('Ezabaketa zein karakteretan hasiko da? ');
readln(iNondik);
if iNondik < 1 then
writeln('Posizioa gutxienez 1 izan behar da');
if iNondik > length(sDatua) then
writeln('Posizioa gehinez ', length(sDatua), ' izan behar da');
until (iNondik >= 1) and (iNondik <= length(sDatua));
repeat
write('Zenbat karaktere ezabatuko dira? ');
readln(iZenbat);
if iZenbat < 1 then
writeln('Gutxienez karaktere 1 kendu behar da');
if iZenbat > length(sDatua)-iNondik+1 then
writeln('Kopurua gehinez ', length(sDatua)-iNondik+1, ' izan behar da');
until (iZenbat >= 1) and (iZenbat <= length(sDatua)-iNondik+1);
sEmaitza := fnsEzabatu(sDatua, iNondik, iZenbat);
writeln('|', sDatua, '|');
writeln('|', sEmaitza, '|');
end;
'B' : begin
writeln('sDatua emanik, fnsTxertatu() funtzioa kodetu insert() prozeduraren lana betez');
writeln;
writeln(' procedure insert(sSartukoDenKatea: string;');
writeln(' var sKateNagusia: string;');
writeln(' iNon: integer);');
writeln;
writeln(' function fnsTxertatu(sAzpikatea: string;');
writeln(' sDatua: string; ');
writeln(' iNondik: integer): string;');
writeln;
write('sDatua eman: ');
readln(sDatua);
writeln('sDatua |', sDatua, '|');
write('sAzpikatea eman: ');
readln(sAzpikatea);
writeln('sAzpikatea |', sAzpikatea, '|');
repeat
write('Txertaketa zein karakteretan hasiko da? ');
readln(iNondik);
if iNondik < 1 then
writeln('Posizioa gutxienez 1 izan behar da');
if iNondik > length(sDatua) then
writeln('Posizioa gehinez ', length(sDatua), ' izan behar da');
until (iNondik >= 1) and (iNondik <= length(sDatua));
sEmaitza := fnsTxertatu(sAzpikatea, sDatua, iNondik);
writeln('|', sDatua, '|');
writeln('|', sEmaitza, '|');
end;
'C' : begin
writeln('sDatua emanik, kopiatu() prozedura kodetu copy() funtzioaren lana betetzeko');
writeln;
writeln(' function copy(sDatuaDenKatea: string;');
writeln(' iNonHasi: integer;');
writeln(' iZenbat: integer): string;');
writeln;
writeln(' procedure kopiatu( sDatua: string;');
writeln(' iNondik: integer;');
writeln(' iZenbat: integer;');
writeln(' var sEmaitza: string);');
writeln;
write('sDatua eman: ');
readln(sDatua);
writeln('sDatua |', sDatua, '|');
repeat
write('Kopiaketa zein karakteretan hasiko da? ');
readln(iNondik);
if iNondik < 1 then
writeln('Posizioa gutxienez 1 izan behar da');
if iNondik > length(sDatua) then
writeln('Posizioa gehinez ', length(sDatua), ' izan behar da');
until (iNondik >= 1) and (iNondik <= length(sDatua));
repeat
write('Zenbat karaktere kopiatuko dira? ');
readln(iZenbat);
if iZenbat < 1 then
writeln('Gutxienez karaktere 1 kendu behar da');
if iZenbat > length(sDatua)-iNondik+1 then
writeln('Kopurua gehinez ', length(sDatua)-iNondik+1, ' izan behar da');
until (iZenbat >= 1) and (iZenbat <= length(sDatua)-iNondik+1);
kopiatu(sDatua, iNondik, iZenbat, sEmaitza);
writeln('|', sDatua, '|');
writeln('|', sEmaitza, '|');
end;
'D' : begin
writeln('sDatua emanik, kokatu() prozedura kodetu pos() funtzioaren lana betetzeko');
writeln;
writeln(' function pos(sBilatukoDenAzpikatea: string;');
writeln(' sKateNagusia: string): integer;');
writeln;
writeln(' procedure kokatu(sAzpikatea: string;');
writeln(' sDatua: string;');
writeln(' var iNon: integer);');
writeln;
write('Kate nagusia den sDatua eman: ');
readln(sDatua);
writeln('sDatua |', sDatua, '|');
write('Bilatuko den sAzpikatea eman: ');
readln(sAzpikatea);
writeln('sAzpikatea |', sAzpikatea, '|');
kokatu(sAzpikatea, sDatua, iNon);
if iNon = 0 then
writeln('|', sAzpikatea, '| ez dago |', sDatua, '| katean')
else
writeln('|', sAzpikatea, '| |', sDatua, '| katearen ', iNon, ' posizioan dago');
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 | 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.
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
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, edo bestela balio konstante bat izan dadila).
Algoritmoa:
Erabiliko den rDoikuntza prezisioa teklatuz irakurri (edo konstante ezagun bat izan dadila)
Lehenego koadranteko rAng angelua graduetan, teklatuz irakurri
Lehenego koadranteko rAng angelua radianetara igaro rX lortuz
rX angeluari dagokion rKos kosinua lortu Taylor bitartez (azken batugaia rDoikuntza baino txikiagoa)
Taylor bitartez lortu den rKos emaitza eta cos(rX) balioa pantailan erakutsi eta bi balioak elkar alderatu
Demagun lehen kasu honetan batukaria kalkulatzen duen azpiprogramak emaitza bakarra itzuli behar duela, kosinua. Hori dela eta, funtzio baten bitartez programatuko dugu. Diogunez, azpiprograma hori funtzio bat izango da bere goiburukoa hauxe delarik:
function fnrKosinuaKalkulatu(rX, rDoikuntza: real): real;
Sarrera: rDoikuntza (gogoratu bertsio honetan doikuntza programa nagusian irakurtzen dela)
Hauxe izan daiteke lehen bertsioaren Programa Nagusia:
{-----------------------Programa Nagusia-----------------------}
var
rAng, rX, rKosinua, rDoikuntza: real;
begin
clrscr;
repeat
write(' Angelu baten kosinua kalkulatzeko prezisioa eman (adibidez 0.0005): ');
readln(rDoikuntza);
until (rDoikuntza > 0.0) and (rDoikuntza < 0.0005);
repeat
write(' Eman lehenengo koadranteko angelua graduetan: ');
readln(rAng);
until (rAng >= 0.0) and (rAng < 90.0);
rX := rAng*2*Pi/360; (* sarrerako angelua radianetara igaro *)
writeln(' 1. koadrantean: ', rAng:0:3, ' gradu = ', rX:0:5, ' radian');
writeln;
rKosinua := fnrKosinuaKalkulatu(rX, rDoikuntza);
writeln;
writeln(' Gure programaz lortutako kosinua[',rX:0:5,' radian] -----> ',rKosinua:0:5);
writeln(' cos() funtzioak ematen duena cos(',rX:0:5,' radian) -----> ',cos(rX):0:5);
writeln;
writeln(' RETURN tekla sakatu programatik irteteko');
readln;
end.
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.
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:
kosinuaren balioa, eta horrez gain
zenbat iteraziotan lortu den kalkulatzea
Kasu 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
Hauxe da bigarren bertsioaren Programa Nagusia, non EPSILON doikuntza konstante bat den:
{------------------PROGRAMA NAGUSIA------------------}
var
rAng, rX, rKosinua: real;
iIterazioKopurua: integer;
begin
clrscr;
writeln('1. koadranteko angelu baten kosinua kalkulatu ', EPSILON:0:4, ' prezisioarekin');
writeln;
repeat
write('Lehenengo koadranteko angelua graduetan: ');
readln(rAng);
until (rAng <= 90) and (rAng >= 0);
rX := rAng*2*Pi/360; (* sarrerako angelua radianetara igaro *)
KosinuaKalkulatu(rX, rKosinua, iIterazioKopurua); (* bi emaitza *)
writeln;
writeln('Emaitza ', iIterazioKopurua, ' iterazioetan lortu da');
writeln('Gure programaz lortutako kosinua[',rAng:0:3,' gradu] -----> ',rKosinua:0:5);
writeln('cos() funtzioak ematen duena cos(',rAng:0:3,' gradu) -----> ',cos(rX):0:5);
writeln;
writeln('RETURN tekla sakatu programatik irteteko');
readln;
end.
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.
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. Deskriba ditzagun, banan-banan gainerako lau aukerak, eta ikus dezagun ere programaren kodea.
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:
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:
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:
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:
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.
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 etaalfabetoa 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.
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:
iZenbaki zenbaki baten faktoriala kalkulatzen duen funtzio errekurtsiboa erakusten da jarraian. Faktorialaren kalkulu errekurtsiboa algoritmo honetan oinarritzen da:
iZenbaki! = iZenbaki * (iZenbaki - 1)!
/* 14-Jarduera_Faktorial-Errekurtsiboa: faktoriala errekurtsiboki */
#include ++stdio.h>
long int faktorialaKalkulatu(int iZbk)
{
if (iZbk == 1)
{
printf(" 1! badakit kalkulatzen, itzuli 1 modulu deitzaileari\n");
return 1;
}
else
{
printf("%3d! kalkulatzeko... %d! ezagutu behar dut\n", iZbk, iZbk - 1);
long int emaitza = iZbk * faktorialaKalkulatu(iZbk - 1);
printf("%3d! kalkulatu dut... %d! * %d eginez\n", iZbk, iZbk - 1, iZbk);
return emaitza;
}
}
int main()
{
int iDatua;
long int liEmaitza;
do
{
printf("Eman zenbaki osoa bere faktoriala kalkulatzeko (adibidez 6): ");
scanf("%d", &iDatua);
} while (iDatua ++= 0);
liEmaitza = faktorialaKalkulatu(iDatua);
printf("%d! = %ld\n", iDatua, liEmaitza);
return 0;
}
Fibonacciren segidaren adierazpen orokorra gogoratuz:
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.