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

2024(e)ko martxoaren 20(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?

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

Hona hemen, datu-mota bakoitzeko, gorago esandakoaren 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:
 

2024(e)ko martxoaren 14(a), osteguna

8. astea | menu bat azpiprogramekin






Karaktere-kateak lantzen

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.
 

2024(e)ko martxoaren 1(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.


 Emaitza laster... 

 

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:




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:

  1. Erabiliko den rDoikuntza prezisioa teklatuz irakurri (edo konstante ezagun bat izan dadila)
  2. Lehenego koadranteko rAng angelua graduetan, teklatuz irakurri
  3. Lehenego koadranteko rAng angelua radianetara igaro rX lortuz
  4. rX angeluari dagokion rKos kosinua lortu Taylor bitartez (azken batugaia rDoikuntza baino txikiagoa)
  5. 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: rX radianak (teklatuz irakurritako rAngelua graduak radianetara igarota)
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:
  1. kosinuaren balioa, eta horrez gain
  2. 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.



 Emaitza laster... 
 

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. 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:





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.
 

2024(e)ko otsailaren 28(a), asteazkena

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:











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;
}


FaktorialErrekurtsiboa.pas programa hartu eta zuk zeuk exekutatu.



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.