ZER DAKIDAN: Agindu errepikakorretan do-while eta for ezagutzen ditut.
ZER IKASIKO DUDAN: Menpekoa den for agindu errepikakor bat beste for nagusi baten barnean nola erabili ikasiko dut, hots, for habiaratuekin jarraituko dugu.
Aurreko programa aintzat harturik eta FOR-DO agindu errepikakorra ezagutzen duzula hurrengo bi ariketak egin:
Batugaien iZenbat kopurua zehazten duen balioa teklatuz irakurriz eta iOina oinarria teklatuz irakurriz, kalkulatu ondoko batukaria eta emaitza liBatukaria aldagaian gorde. Ziurtatu iZenbat kopuru osoa, positiboa eta bikoitia dela. Ziurtatu ere iOina kopuru osoa eta positiboa dela.
Batukariaren batugaiak zenbait zenbakien potentziak dira, hauek:
Batugaien iZenbat kopurua zehaztuko duen balioa teklatuz irakurriz eta iOina oinarria teklatuz irakurriz, kalkulatu ondoko batukaria eta emaitza liBatukaria aldagaian gorde. Ziurtatu iZenbat kopuru osoa, positiboa eta bikoitia dela. Ziurtatu ere iOina kopuru osoa eta positiboa dela.
Batukariaren batugaiak zenbait zenbakien faktorialak dira, hauek:
2025 urtea duela gutxi hasi dela, zenbaki honi buruzko jakingarri batzuk ikus ditzagun. Hasteko, "karratu perfektu" esaten esaten zaiola hau betetzen delako: 2025=452. Beste karratu perfektu batzuk hauek dira: 1, 4, 9, 16, 25, 36, 49, 64, 81, ...
Baina 2025 zenbakiak beste bi ekuazio hauek betetzen ditu ere:
2025 = (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9)² sistema hamartarraren digitu
guztien batura lortu ondoren
emaitza 45 da, bere karratua
2025 da
2025 = 0³ + 1³ + 2³ + 3³ + 4³ + 5³ + 6³ + 7³ + 8³ + 9³ sistema hamartarraren
digitu guztien kuboen
batura 2025 da
Bi ekuazio horien zuzentasuna frogatzen duen programa jarraian erakusten da:
ZER DAKIDAN: Agindu errepikakorretan do-while eta for ezagutzen ditut.
ZER IKASIKO DUDAN: Menpekoa den for agindu errepikakor bat beste for nagusi baten barnean nola erabili ikasiko dut; hau da, for habiaratuekin jarraituko dugu.
Aurreko programa aintzat harturik eta for agindu errepikakorra ezagutzen duzula hurrengo bi ariketak egin:
Batugaien iZenbat kopurua zehaztuko duen balioa teklatuz irakurriz, kalkulatu ondoko batukaria eta emaitza lBatukaria aldagaian gorde. Ziurtatu iZenbat kopuru osoa, positiboa eta bikoitia dela.
Batukariaren batugaiak hainbat zenbakien faktorialak dira, hauek:
Batugaien iZenbat kopurua zehaztuko duen balioa teklatuz irakurriz, kalkulatu ondoko batukaria eta emaitza lBatukaria aldagaian gorde. Ziurtatu iZenbat kopuru osoa, positiboa eta bikoitia dela.
Batukariaren batugaiak hainbat zenbakien faktorialak dira, hauek:
ZER DAKIDAN: Agindu errepikakorretan do-while eta for ezagutzen ditut.
ZER IKASIKO DUDAN: Menpekoa den for agindu errepikakor bat beste for nagusi baten barnean nola erabili ikasiko dut (beheko irudiak adierazten duen bezala for habiaratuak kasuaz ariko gara).
Kanpoko begiztak 5 iterazio ematen ditu eta barruko begiztak 10
Arestian ikusitako Ariketa 21 | for adibideak (1) artikulua gogora ekarriz, hurrengo adibideetan for egitura errepikakorrarekin jarraituko dugu lanean. Baina adibideen bigarren sorta honetan for aginduaren barruan beste for agindu bat aurkituko dugu, goiko irudiak erakusten duen antzera.
Bi prozesu errepikakor koordinatuak, bata nagusia eta bestea bere menpekoa. Hurrengo hiru ariketetan for bat beste for baten barnean aurkituko ditugu:
/* Ariketa-22a_forAdibideak-2: bi lauki marrazten. */
// {--------------------------------------------------------------
// Zenbaki osoa eta positiboekin lan eginez, sarrerako
// kopuruarean araberako lauki parea pantailaratuko da.
// --------------------------------------------------------------}
#include <stdio.h> // printf() funtzioarako
#define BEHEMUGA 1
#define GOIMUGA 9
int main()
{
int iKanpokoKont, iBarrukoKont, iZenbakia;
printf("\n\n");
do
{
printf(" %d eta %d artekoa den zenbaki osoa eman (5 adibidez): ", BEHEMUGA, GOIMUGA);
scanf("%d", &iZenbakia);
} while ((iZenbakia < BEHEMUGA) || (iZenbakia > GOIMUGA));
printf("\n %dx%d laukia: ", iZenbakia, iZenbakia);
printf("\n ----------\n");
for (iKanpokoKont=1; iKanpokoKont<=iZenbakia; iKanpokoKont++)
{
for (iBarrukoKont=1; iBarrukoKont<=iZenbakia; iBarrukoKont++)
{
printf("%2d", iZenbakia);
}
printf("\n");
}
printf("\n %dx%d laukia: ", iZenbakia, 2*iZenbakia);
printf("\n -----------\n");
for (iKanpokoKont=1; iKanpokoKont<=iZenbakia; iKanpokoKont++)
{
for (iBarrukoKont=1; iBarrukoKont<=2*iZenbakia; iBarrukoKont++)
{
printf("%2d", iZenbakia);
}
printf("\n");
}
printf("\n\n");
return 0;
}
/* Ariketa-22b_forAdibideak-2: triangelu bat marrazten. */
// {-----------------------------------------------------------------
// Zenbaki osoa eta positiboekin lan eginez, sarrerako kopuruarean
// araberako triangelu laukizuzen bat pantailaratuko da.
// -----------------------------------------------------------------}
#include <stdio.h> // printf() funtzioarako
#define BEHEMUGA 1
#define GOIMUGA 9
int main()
{
int iKanpokoKont, iBarrukoKont, iZenbakia;
printf("\n\n");
do
{
printf(" %d eta %d artekoa den zenbaki osoa eman (5 adibidez): ", BEHEMUGA, GOIMUGA);
scanf("%d", &iZenbakia);
} while ((iZenbakia < BEHEMUGA) || (iZenbakia > GOIMUGA));
printf("\n %dx%d hirukia: ", iZenbakia, iZenbakia);
printf("\n -----------\n");
for (iKanpokoKont=1; iKanpokoKont<=iZenbakia; iKanpokoKont++)
{
for (iBarrukoKont=1; iBarrukoKont<=iKanpokoKont; iBarrukoKont++)
{
printf("%2d", iZenbakia);
}
printf("\n");
}
printf("\n\n");
return 0;
}
/* Ariketa-22c_forAdibideak-2: potentziak batzen. */
// {--------------------------------------------------------------------
// iMuga emanda >>> liBatukaria = 1^1 + 2^2 + 3^3 + ... + iMuga^iMuga
// KONTUZ!!! long datu-motarekin iMuga=10 denean gainezkatzea dago.
// --------------------------------------------------------------------}
#include <stdio.h> // printf() funtzioarako
#include <limits.h> // LONG_MAX erabiltzeko
#define BEHEMUGA 0
#define GOIMUGA 10
int main()
{
int iMuga, iKontKanpo, iKontBarru;
long lBatugaia, lBatukaria;
printf("\n\n");
printf("\n ---------------------------------------------------------");
printf("\n liBatukaria = 1^1 + 2^2 + 3^3 + 4^4 + ... + iMuga^iMuga");
printf("\n ---------------------------------------------------------\n\n");
do
{
printf(" Muga adierazten duen zenbaki osoa eta positiboa eman (5 adibidez): ");
scanf("%d", &iMuga);
if (iMuga < BEHEMUGA)
printf("\n Muga kopuru positiboa izan behar da\n");
if (iMuga >= GOIMUGA)
{
printf("\n\t Mugaren kopuru maximoa 9 da. Muga 10 bada");
printf("\n\t long datu-motako batukariaren emaitzak");
printf("\n\t LONG_MAX=%ld balioa gainditzen du.\n", LONG_MAX);
}
} while ((iMuga < BEHEMUGA) || (iMuga >= GOIMUGA));
lBatukaria = 0;
for (iKontKanpo=1; iKontKanpo<=iMuga; iKontKanpo++)
{
lBatugaia = 1;
for (iKontBarru=1; iKontBarru<=iKontKanpo; iKontBarru++)
{
lBatugaia = lBatugaia*iKontKanpo;
printf("\n\t iKontKanpo=%d \t\t iKontBarru=%d \t\t lBatugaia=%ld", iKontKanpo, iKontBarru, lBatugaia);
}
lBatukaria = lBatukaria + lBatugaia;
printf("\n\t\t lBatugaia=%ld \t\t lBatukaria=%ld", lBatugaia, lBatukaria);
printf("\n");
}
printf("\n\t\t Azken batukaria = %ld", lBatukaria);
printf("\n\n");
return 0;
}
ZER DAKIDAN: Sekuentzialki multzokatzen diren aginduak ezagutzen ditut, bide desberdinak erabakitzeko baldintzazko aginduak (if eta switch) ezagutzen ditut. Datuak teklatuz modu kontrolatuan jasotzeko do-while agindu errepikakorra ere erabili izan dut.
ZER IKASIKO DUDAN: Agindu errepikakorrekin jarraituz for ikasiko dut (for soil-soilak kasu hauetan).
Batugaien kopurua ezaguturik batukariak kalkula ditzagun
Hurrengo adibideetan for egitura errepikakorra landuko dugu. Adibide guztiak oinarrizkoak direnez for aginduaren barruan ez da izango beste agindu errepikakorrik, horregatik for artikulu honek jarraipena izango du beste artikulu batean —Ariketa 22 | for adibideak (2)— non for agindu habiaratuak landuko ditugun.
Gogoratu for agindu erabili ahal izateko iterazioen kopurua ezaguna izango dela. Iruzkinak:
Iterazioen kopurua kontrolatzeko Kontagailua izeneko aldagaia diskretua izango da (int datu-mota familiakoa edo char datu-motakoa)
Kontagailua izeneko aldagaiaren hasieraketa for aginduan bertan egiten da
Prozesu errepikakorra eteteko Kontagailua aldagaiaren balioa aztertzen da adierazpen logiko batean (egia ala gezurra ebaluatzen den adierzpena), eta baldintzaren emaitza egia den bitartean prozesu errepikakorrak jarraituko du
Kontagailua aldagaiaren balioa aldatuz doa iterazio batetik bestera
Batukariak eta biderkariak kalkulatzen for aginduarekin trebatzeko:
/* Ariketa-21a_forAdibideak-1: batukari baten kalkulua. */
// {------------------------------------------------------------------------------
// iMuga emanda lortu iBatukaria = 1 + 2 + 3 + ... + (iMuga-1) + iMuga
// ------------------------------------------------------------------------------}
#include <stdio.h> // printf() funtzioarako
int main()
{
int iKont, iMuga, iBatukaria;
printf("\n\n");
do
{
printf(" 'iMuga' zenbaki osoa eta positiboa eman (5 adibidez): ");
scanf("%d", &iMuga);
} while (iMuga < 0);
iBatukaria = 0;
printf("\n Hasieran iBatukaria=%d", iBatukaria);
printf("\n ---------------------------------------------");
for (iKont=1; iKont<=iMuga; iKont++)
{
iBatukaria = iBatukaria + iKont;
printf("\n \t %2d iterazioan iBatukaria=%d", iKont, iBatukaria);
}
printf("\n ---------------------------------------------");
printf("\n Irten ondoren: iKont=%d", iKont);
printf("\n Azkenean: iBatukaria=%d", iBatukaria);
printf("\n\n");
return 0;
}
iBatukaria = 1 + 2 + 3 + ... + (iMuga-1) + iMuga
/* Ariketa-21b_forAdibideak-1: biderkari baten kalkulua (faktorialaren kalkulua). */
// {------------------------------------------------------------------------------
// iMuga emanda lortu liBiderkaria = 1 * 2 * 3 * ... * (iMuga-1) * iMuga
// ------------------------------------------------------------------------------}
#include <stdio.h> // printf() funtzioarako
int main()
{
int iKont, iMuga;
long lBiderkaria;
printf("\n\n");
do
{
printf(" 'iMuga' zenbaki osoa eta positiboa eman (5 adibidez): ");
scanf("%d", &iMuga);
} while (iMuga < 0);
lBiderkaria = 1;
printf("\n Hasieran lBiderkaria=%ld", lBiderkaria);
printf("\n ---------------------------------------------------");
for (iKont=1; iKont<=iMuga; iKont++)
{
lBiderkaria = lBiderkaria*iKont;
printf("\n \t %2d iterazioan lBiderkaria=%ld", iKont, lBiderkaria);
}
printf("\n ---------------------------------------------------");
printf("\n Irten ondoren: iKont=%d", iKont);
printf("\n Azkenean: lBiderkaria=%ld", lBiderkaria);
printf("\n\n");
return 0;
}
ZER DAKIDAN: Sekuentzialki multzokatzen diren aginduak ezagutzen ditut, bide desberdinak erabakitzeko baldintzazko aginduak (if eta switch) ezagutzen ditut. Datuak teklatuz modu kontrolatuan jasotzeko do-while agindu errepikakorra ere erabili izan dut.
ZER IKASIKO DUDAN: Agindu errepikakorrekin jarraituz for ikasiko dut.
C programazioan, begizta bat erabiltzen da kode bloke bat hainbat aldiz errepikatzeko. Begizta bat osatzeko for agindua da modurik trinkoena da.
Hona hemen 1 eta 5 zenbakiak inprimatzen dituen adibide sinple bat:
for (int iKont=1; iKont<=5; iKont++)
{
printf("%d\n", iKont);
}
Nola funtzionatzen duen. Begiztak hiru zati ditu:
Hasieraketa: Begizta kontrolatzen duen iKont aldagaiari hasierako balioa ematen zaio.
Baldintza: Begiztak jarraitzen du baldintza betetzen den bitartean.
Iterazioa: Begiztaren iterazo bakoitzaren printf() funtzioa exekutatzen da eta iKont inkrementatzen da.
Baldintzak adierazten duen egoera faltsua denean (iKont-ek 6 balioko duenean), amaitzen da begizta.
Ondoko adibidea aztertu non do-while aginduari esker ziurtatzen da iZbk datu positiboa den, eta, for aginduari esker lFakt faktoriala kalkulatzen den.
Hona hemen Ariketa-20a_FaktorialaKalkulatzen.cbp proiektuaren main() funtzioa gordetzen duen main.c fitxategiaren edukia:
/* Ariketa-20a_FaktorialaKalkulatzen: for aginduaren adibidea. */
// Zenbaki osoekin lan egingo dugu, iZbk teklatuaren bitartez
// irakurri eta lFakt=iZbk! faktoriala kalkulatu for bitartez.
#include <stdio.h> // printf() funtzioarako
int main()
{
int iZbk, iKont;
long lFakt;
printf("\n");
printf("\n Kopuru osoko eta positiboekin lan egingo da");
printf("\n -------------------------------------------\n");
printf("\n Zenbaki osoa eta positiboa eman eta dagokion");
printf("\n faktoriala kalkulatu eta pantailaratuko da.\n\n");
do
{
printf(" Zenbaki osoa eta positiboa eman (5 adibidez): ");
scanf("%d", &iZbk);
} while (iZbk < 0);
lFakt = 1;
for (iKont=1; iKont<=iZbk; iKont++)
{
lFakt = lFakt*iKont;
printf("\n \t %d iterazioan lFakt= %ld", iKont, lFakt);
}
printf("\n\n \t \t %d! = %ld", iZbk, lFakt);
printf("\n\n");
return 0;
}
Ondoko adibidea aztertu non do-while aginduari esker ziurtatzen da iBerretzailea datu positiboa den, eta, for aginduari esker 2 konstantearen lBerredura potentzia kalkulatzen den. Lortutako emaitzaren zuzentasuna konprobatuko dugu pow(2, iBerretzailea) funtzioa aplikatuz.
Hauxe da potenzia edo berredura kalkulatzen duen Ariketa-20b_PotentziaKalkulatzen.cbp proiektuaren main.c fitxategiaren edukia:
/* Ariketa-20b_PotentziaKalkulatzen: for aginduaren adibidea. */
// Zenbaki osoekin lan eginez, iBerretzailea teklatuz irakurri
// eta 2^iBerretzailea potentzia kalkulatu for bitartez, emaitza
// konprobatuko dugu pow(2, iBerretzailea) funtzioa aplikatuz.
// ADI: Emaitza long bada 31 datuarekin gainezkatzea gertatzen da.
#include <stdio.h> // printf() funtzioarako
#include <math.h> // pow() funtzioarako
#define OINARRIA 2
#define MUGA 30
int main()
{
int iBerretzailea, iKont;
long lBerredura;
printf("\n");
printf("\n Kopuru osoko eta positiboekin lan egingo da");
printf("\n -------------------------------------------\n");
printf("\n iBerretzailea zenbaki osoa eta positiboa eman eta dagokion");
printf("\n 2^iBerretzailea potentzia (edo berredura) kalkulatuko da.\n\n");
do
{
printf(" Berretzailea adierazten duen zenbaki osoa eta positiboa eman (5 adibidez): ");
scanf("%d", &iBerretzailea);
if ((iBerretzailea < 0) || (iBerretzailea > MUGA))
printf(" Datua 0 eta %d artekoa (biak barne) \n", MUGA);
} while ((iBerretzailea < 0) || (iBerretzailea > MUGA));
lBerredura = 1;
for (iKont = 1; iKont <= iBerretzailea; iKont++)
{
lBerredura = lBerredura*OINARRIA;
printf("\n \t %2d iterazioan lBerredura= %ld", iKont, lBerredura);
}
printf("\n\n \t \t 2^%d = %ld", iBerretzailea, lBerredura);
printf("\n \t pow(2, %d) = %.0f", iBerretzailea, pow(2, iBerretzailea));
printf("\n\n");
return 0;
}
Orain arte aginduen sekuentziak ikusi ditugu eta erabakiak hartzeko baldintzako if eta switch aginduak. Hemendiak aurrera agindu errepikakorrekin (do-while, while eta for) ere lan egingo dugu, hauei esker iterazioak burutu daitezke.
Hona hemen aginduak antolatzeko hiru moduen eskemak:
Sekuentziazko aginduen, baldintzazko aginduen eta agindu errepikakorren eskemak
Aginduen sekuentzietan programaren fluxuak beti aurrera egiten du eta agindu guztiak betetze dira bide bakar bat dagoelako. Baldintzako aginduetan ere programaren fluxuak beti aurrera egiten du, baina bide desberdinak daudelako, agindu batzuk beteko dira ala ez. Agindu errepikakorretan programaren fluxuak atzera egiten du agindu batzuk berriro betetzeko, horri iterazio esaten zaio:
Baldintzazko aginduetan fluxuak aurrera egiten du
Agindu errepikakorretan fluxuak atzera egiten du
do-while eta while agindu errepikakorren arteko aldea kontzeptu bakarrean ematen da: Prozesu errepikakorra eteteko baldintza non kokatzen den, iterazioa baino lehen ala iterazioaren ostean. Bietan, bai do-while aginduan zein while aginduan prozesu errepikakorra eteteko baldintzaren logika berdina da: galderaren erantzuna ezezkoa bada eteteko da prozesu errepikakorra. Eskematikoki:
while: iterazioa baino lehen ebaluatzen da galdera do-while: iterazioa bukatzean ebaluatzen da galdera
Hirugarren agindu errepikakorra for da, agindu oso trinkoa delako bere erabilpena erraza da baina bere eskema marraztea ez da horren erraza. Noiz erabili for, do-while edo while agindu errepikakorrak? Araua argia da: prozesu errepikakorraren iterazio kopurua ezaguna denean for agindua erabiliko dugu, eta prozesu errepikakorraren iterazio kopurua ez dugunean ezagutzen do-while agindua edo while agindua erabili beharko dugu ezin bestean.
C lengoaiak adierazpen berean datu-mota ezberdineko gaiak agertzea ahalbidetzen du, konpiladorea arduratzen da eragiketak behar bezala egiteaz. Adierazpen berean bi datu-mota edo gehiago agertzen direnean, eragigai guztien datu-motak bihurtzen ditu C lengoaiaren konpiladoreak eragigaietan dagoen datu-motarik handienera, honako bi arau hauen arabera:
char eta short int guztiak int bihurtzen dira, float guztiak double bihurtzen dira
Eragigai pare guztietarako, honako hau sekuentzian gertatzen da:
Eragigaietako bat long double bada, bestea long double bihurtzen da
Eragigaietako bat double bada, bestea double bihurtzen da
Eragigaietako bat long bada, bestea long bihurtzen da
Eragigaietako bat unsigned bada, bestea unsigned bihurtzen da.
Konpiladoreak bihurketa-arau horiek aplikatu ondoren, eragigaiak datu-mota berekoak izango dira, eta emaitza eragigaien datu-motako horretakoa izango da. Adibide bat ikus dezagun:
Adierazpen aritmetikoan datu-mota desberdinak daudelako, lehenengo araua aplikatuko da. Lehenengo arauaren arabera, char datu-motako cKarak aldagaiaren balioa int bihurtzen da, eta, era berean, float datu-motako fZbk aldagaiaren balioa double bihurtzen da. Egoera berria hau delarik:
( cKarak / iKop ) - ( fZbk + iKop ) + ( fZbk * dZbk ) ;
int int double int double double
Hiru blokeak ikus ditzagun banan-banan. Lehen blokeko bi eragigaiak mota berekoak direnez, lehenengo eragiketa egingo dugu (cKarak/iKop), eta emaitza int datu-motakoa izango da. Era berean, hirugarren blokeko eragiketan bi biderkagaiak datu-mota berekoak direnez fZbk*dZbk eragiketa burutuko da emaitza double datu-motakoa delarik. Baina, bigarren blokeko batugaiak datu-mota desberdinekoak dira, horregatik, bigarren araua aplikatuz int datu-motakoa double datu-motara bihurtzen da eta fZbk+iKop emaitza double izango da.
( cKarak / iKop ) - ( fZbk + iKop ) + ( fZbk * dZbk ) ;
int int double int double double
------------- ------------- ---------------
intdoubledouble
Hiru blokeak ebaluatu ondoren, haien integrazioa egin beharko da. Lehen blokea int datu-motakoa izango denez, eta bigarren blokea double datu-motakoa denez, lehen blokeari bihurketa bat egiten zaio double izan dadin eta bi bloken arteko kendura double datu-motakoa izango da. Amaitzeko hirugarren blokea gehituko zaio aurreko emaitzari eta biak double datu-motakoak direnez azken emaitza ere double izango da.
( cKarak / iKop ) - ( fZbk + iKop ) + ( fZbk * dZbk ) ;
int int double int double double
------------- ------------- ---------------
int double double
---------------------------
doubledouble
-----------------------------------------
double
Hurrengo taulako operadoreak lehentasunaren arabera zerrendatzen dira, handienetik txikienera. Operadore bat baino gehiago agertzen badira lerro berean edo talde batean, lehentasun bera dute eta asoziatibitateari begiratu beharko zaio hurrenkera jakiteko.
Azken lerroko esleipen-operadore soil eta esleipen-operadore konposatu guztiek lehentasun bera dute.
Operadoreen lehentasuna eta asoziatibitatea (goitik beherako lehentasuna)
Eragiketa mota
Asoziabilitatea
Sinboloa
1
Adierazpena
Ezkerretik eskumara
>>>
[] () . -> ++ --(atzizki)
2
Unarioa
Eskumatik ezkerrera
<<<
sizeof & * + - ~ ! ++ --(aurrizki)
3
Behartzea (edo typecast)
Eskumatik ezkerrera
<<<
(datu-mota)
4
Biderkatzailea
Ezkerretik eskumara
>>>
* % /
5
Batutzailea
Ezkerretik eskumara
>>>
+ -
6
Erlaziozkoa
Ezkerretik eskumara
>>>
> < >= <=
7
Berdintasuna
Ezkerretik eskumara
>>>
== !=
8
AND logikoa
Ezkerretik eskumara
>>>
&&
9
OR logikoa
Ezkerretik eskumara
>>>
||
10
Baldintzazko adierazpena
Eskumatik ezkerrera
<<<
? :
11
Esleipen soila eta konposatua
Eskumatik ezkerrera
<<<
= *= /= %= += -=
Esan bezala, azken lerroko esleipen-operadoreek (soilak eta konposatuek) lehentasun berdina daukate.
Adierazpen batek lehentasun bera duten operadore bat baino gehiago izan ditzake. Mota horretako operadore batzuk adierazpenean maila berean agertzen direnean, ebaluazioak jarraitu egiten du, operadorearen asoziatibitatearen arabera, eskuinetik ezkerrera batzuetan eta ezkerretik eskuinera beste batzuetan. Beraz, adierazpen bat ebaluatzeko, lehentasunari begiratzen zaio lehenik eta gero asoziabilitateari.
Goiko taulari so eginez, ikus daiteke eragile aritmetikoek biderkatzaileak eta batutzaileak direla. Jarraian hiru adibide aurkeztuko dira: lehen adibidean behartze operadorea landuko dugu, bigarren adibidean parentesiak soberan ote dauden aztertuko da operadore biderkatzailekin lan egitean, eta, azkenik, hirugarren adibidean operadore biderkatzailea eta operadore batutzailea nahastuko dira.
Behartze operadorea nola aplikatu
Hau da OperadoreenLehentasuna_1.cbp proiektua non emaitza biak zilegiak diren, baina programa jakin batean bietariko bat ondo egongo den eta bestea txarto legokeen:
Hona hemen OperadoreenLehentasuna_1.cbp proiektua exekutatzean lortzen den irteera:
Operadore biderkatzailekin parentesien beharra
OperadoreenLehentasuna_2.cbp proiektuan bi zeregin betetzen dira, fGraduak aldagaiari balioa ematea fRadianak ezaguna dela, eta, fSegundoenErdia aldagaiari balioa ematea fGraduak ezaguna dela. Lehen kasuan parentesiak guztiz derrigorrezkoa dira eta bigarren kasuan parentisirik ez da behar baina programa irakurterraza egitearren komenigarriak izan daitezke.
Hona hemen OperadoreenLehentasuna_2.cbp proiektua exekutatzean lortzen den irteera:
Biderkatzaileen asoziabilitatea ezkerretik eskumara doanez, lehen adibidean parentesiak derrigorrezkoak dira
Operadore biderkatzailea eta operadore batutzailea konbinatuz
Hau da OperadoreenLehentasuna_3.cbp proiektua non emaitza biak zilegiak diren, baina programa jakin batean bietariko bat ondo egongo den eta bestea txarto legokeen:
Hona hemen OperadoreenLehentasuna_3.cbp proiektua exekutatzean lortzen den irteera:
Eragile logikoek eta konparatzaileek beren eragigaien ebaluazioa bermatzen dute ezkerretik eskuinera (taulako 6., 7., 8. eta 9. errenkadak). Hala ere, adierazpenaren emaitza zehazteko behar diren eragigaien kopururik txikiena ebaluatzen dute, eta horri "zirkuitulaburraren" ebaluazioa esaten zaio. Beraz, baliteke adierazpen logikoaren eragigai batzuk ez ebaluatzea. Azter dezagun, adibidez, adierazpen logiko hau:
if (x>=5 && y==3)
Aurreko if adibidean AND operadore logikoak (&&) lehentasun txikiagoa du erlaziozko operadoreak baino (>=) eta berdintasunaren operadoreak baino (==). Hori dela eta, lehenik ezkerreko konparaketa ebaluatuko da eta, adibidez, x aldagaiaren balioa 4 balitz, orduan eskumako konparaketa ez litzateke ebaluatuko; izan ere, y aldagaiaren balioa edozein dela adierazpen logikoak FALSE emaitzara ebaluatuko litzateke x>=5 alderaketak FALSE balio duelako.
Baina, aurreko if adibidean AND operadore logikoaren ordez OR operadore logikoa (||) idatziko balitz, honek ere lehentasun txikiagoa du erlaziozko operadoreak baino (>=) eta berdintasunaren operadoreak baino (==). Hori dela eta, alderaketa biak ebaluatuko dira, lehenik ezkerreko konparaketa ebaluatuko da eta ondoren eskumako konparaketa ebaluatuko da:
if (x>=5 || y==3)
Izan ere, x txikiago 5 izan arren, baliteke y aldagaiaren balioa 3 izatea eta kasu horretan if aginduaren baldintza beteko litzateke.
Jakina denez, eslipen mota desberdinak daude: esleipen soila alde batetik eta esleipen konposatuak bestetik. Ikastaro honetan gehien-gehienetan esleipen soila erabiliko da.
Berrikus ditzagun lehentasun arauak adierazpen aritmetiko konplexu bat duen esleipen honetan:
Adierazpen aritmetiko honetan bi parentesi multzo nagusi daude, baina biak ez dira berdinak:
(int) parentesia, taulako hirugarren lerroko behartze operadorea da
( fRadianak*360/(2*PI) + (fHasiera*7)/pow(fAmaiera+0.2,PI) ) parentesia taulako lehen lerroko adierazpena delako, lehen-lehenik ebaluatuko da eta ondoren bere emaitzari behartze operadorea aplikatuko zaio
Beraz, aipatu ditugun parentesi nagusi biak ordena honetan ebaluatuko dira:
II I
===== ----------------------------------------------------------
iGraduOsoak = (int)( fRadianak*360/(2*PI) + (fHasiera*7)/pow(fAmaiera+0.2,PI) );
I izendatu dugun fRadianak*360/(2*PI) + (fHasiera*7)/pow(fAmaiera+0.2,PI) zatian hiru parentesi multzo daude eta hauek ere ez dira guztiz berdinak:
(2*PI) taulako lehen lerroko adierazpen operadorea da eta ezkerrean dagoelako ebaluatzen den aurrenekoa izango da
(fHasiera*7) taulako lehen lerroko adierazpen operadorea da, baina aurrekoaren eskuman dagoelako bigarrena izango da ebaluatze-segidan
(fAmaiera+0.2,PI) funtzio baten parametro-zerrenda mugatzeko parentesiak dira eta multzo honek aurreko biekin zerikusirik ez dauka, funtzioa ebaluatzeko unean aintzat hartuko da parentesi barnekoa
II I
===== ----------------------------------------------------------
iGraduOsoak = (int)( fRadianak*360/(2*PI) + (fHasiera*7)/pow(fAmaiera+0.2,PI) );
------ ============
1 2
Hurrengoak ebaluatzen hiru biderkatzaileak izango dira eta ezkerreik eskumara ebaluatuko dira. Lehenik fRadianak*360, gero fRadianak*360/(2*PI) eta (fHasiera*7)/pow(fAmaiera+0.2,PI) bukatzeko; honelaxe: a, b eta c. Eskematikoki:
II I
===== ----------------------------------------------------------
iGraduOsoak = (int)( fRadianak*360/(2*PI) + (fHasiera*7)/pow(fAmaiera+0.2,PI) );
------ ============
1 2
-------------
a
--------------------
b ---------------------------------
c
Azkenik, batutzaile operadorearen txanda izango da eta horrela bukatzen da I zatiaren ebaluazioa. Helburuko iGraduOsoak aldagaiaren balioa IIbehartze operadoreari esker lortuko da.
Hona hemen OperadoreenLehentasuna_4.cbp proiektua exekutatzean lortzen den irteera: