ZER DAKIDAN: Orain arte datu-mota xeheak erabili ditut, adibidez: int, long, char, float, e.a. Ikasi dut ere zenbakien array bat datuz nola bete dezakedan teklatua erabiliz. ZER IKASIKO DUDAN: Zenbaki errealen array datu-motako aldagai batekin lan eginez, algoritmo batzuk programatzen ikasiko dut. |
Zenbaki errealen afBektorea izeneko array-aldagai batekin lan egingo dugu. Suposa dezagun bektoreak gehienez LUZMAX=20 elementu izan ditzakeela, eta bektore horrek 0.0 eta 99.9 zenbaki errealak gordetzen dituela. Adibidez, une jakin batean 4 elementu dituen afBektorea array horren edukia hau izan daiteke, non iLuzera aldagaiak bektorearen luzera efektiboa gordetzen duen:
afBektorea
61.27
|
7.68
|
12.72
| 98.41
| |||
0
|
1
|
2
|
3
|
4
|
...
|
19
|
4
|
iLuzera aldagaiak bektorearen luzera efektiboa gordetzen duenez, hots, zenbat elementu dituen une horretan, bere mugak 0 eta LUZMAX=20 dira. Bektorea beterik izatean iLuzera aldagaian LUZMAX=20 balioa gordeko da (lehen elementuren indizea 0) eta azkenarena LUZMAX-1=19, eta, aldiz, bektoreak iLuzera=4 elementu dituenean haien indizeak 0, 1, 2 eta 3=iLuzera-1 izango dira. Noski, arraya hutsik izatean iLuzera aldagaian 0 marka gordeko da.
Aurreko programa batean erabiltzaileak teklatuz erabakitzen zuen bektorean gordeko diren elementuen kopurua. Orain, iLuzera kopurua modu aleatorioan lortuko da, gehienez 19 elementu eta gutxienez 1 elementu (beraz, 1. posiziotik 19. posizioraino), eta, modu aleatorioan ere 0.0 eta 99.99 arteko zenbakiak bektorean biltegituko dira. Funtzio nagusian ondoko funtzioak deituko dira:
- BektoreaAleatoriokiBete() arraya datuz betetzeko
- BektoreaIkusi() arrayaren edukia pantailaratzeko
/* Ariketa-45a_ArrayaAleatoriokiBete: arraya aleatorioki bete eta erakutsi */ // Errealen array bat. Array bat datuz auzaz bete funtzio batean // eta ondoren arrayaren edukia pantailaratu arraya bera erabiliz. #include <stdio.h> #include <stdlib.h> // rand() eta srand() funtzioetarako #include <time.h> // time() funtzioarako #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino void BektoreaAleatoriokiBete(float[], int *); void BektoreaIkusi(const float[], int); int main() { float afBektorea[LUZMAX]; int iLuzera; printf("\n"); printf("\n\t Arrayaren luzera efektiboa eta bere balioak auzaz harturik"); printf("\n\t ----------------------------------------------------------\n"); BektoreaAleatoriokiBete(afBektorea, &iLuzera); printf("\n\t Arrayaren %d elementuak %d elementu gorde ondoren: \n", LUZMAX, iLuzera); BektoreaIkusi(afBektorea, LUZMAX); printf("\n\t Arrayaren %d elementuak: \n", iLuzera); BektoreaIkusi(afBektorea, iLuzera); printf("\n"); return 0; } void BektoreaAleatoriokiBete(float afBektorea[], int *iLuzera) // bi parametroak irterakoak dira { int iKont; srand(time(NULL)); // srand() zenbaki aleatorioak berriro hasiarazteko, srand()-ek hazia behar duenez, // time(NULL) funtzioak igarotako segundoak itzultzen ditu 1970-01-01 datatik hasita printf("\n\t Auzaz:"); *iLuzera = rand() % LUZMAX + 1; // [(0 eta 19 artekoa) + 1] = [1 eta 20 artekoa] elementu kopurua (gutxienez elementu 1, gehienez 20) printf("\n\t *iLuzera=%d (1 eta %d artekoa)", *iLuzera, LUZMAX); // posizio txikiena 0 eta handiena 19, baldin eta 20 elementu balira for (iKont=0; iKont < *iLuzera; iKont++) { afBektorea[iKont] = ((float)rand()/RAND_MAX) * (GOIMUGA-BEHEMUGA); // 0.0 eta 0.999 artekoa bider (GOIMUGA-BEHEMUGA) printf("\n %15.2f (0.0 eta %.2f artekoa)", afBektorea[iKont], GOIMUGA-BEHEMUGA); // emaitza: 0.0 eta 99.9 artekoa } printf("\n"); } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } }
Gainerako aldagai soilek bezala, array batek hasieraketa onartzen du bere deklarazioan. Arrayaren hasieraketa egiterakoan static marka jarri behar zaio aurretik. Zenbaki errealen arrayaren hasieraketa egiterakoan bere posizio guztiak betetzen ez badira, ziurtatuta dago falta direnetan 0.0 balio jartzen zaiela.
Arrayak balioak dituela, bi aldaketa mota egingo zaizkio; aldaketa bat datuen posizioen araberakoa eta beste aldaketa bat datuen balioen araberakoa:
- Array osoa korritu, hau da 0. posiziotik iLuzera posizioraino arraya ibili eta datua aldatu posizioaren arabera BektorearenDatuakHandituEtaTxikituPosizioenArabera() funtzioa aplikatuz: posizio bakoitiko elementuei +0.5 gehitu handitzeko eta bektorearen posizio bikoitiko elementuei -0.5 gehitu txikiago egiteko.
- Array osoa korritu, hau da 0. posiziotik iLuzera posizioraino arraya ibili eta datua aldatu bere balioaren arabera BektorearenDatuakHandituEtaTxikituBalioenArabera() funtzioa aplikatuz: elementu txikiei (50.0 baino txikiagoei) gehitu +0.75 konstantea, eta bektorearen elementu handiei (50.0 edo handiagoei) gehitu -0.75 konstantea.
Hona hemen programa:
/* Ariketa-45b_ArrayarenHasieraketa: arraya hasieratu ondoren, elementuak aldatu posizioaren eta balioaren arabera */ // Array baten hasieraketa. Datuak dituen array bateko datuak aldatu, posizio // bakoitikoei +0.5 egin eta posizio bikoitietan daudenei -0.5 egin. Elementu // txikiei +0.75 egin eta handiei -0.75 egin. #include <stdio.h> #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino void BektoreaIkusi(const float[], int); void BektorearenDatuakHandituEtaTxikituPosizioenArabera(float[], int); void BektorearenDatuakHandituEtaTxikituBalioenArabera(float[], int); int main() { static float afBektorea[LUZMAX] = { 67.34, 32.17, 89.37, 15.08, 16.16, 72.44, 5.09, 8.77, 22.29, 43.08 }; int iLuzera = 10; printf("\n"); printf("\n\t Arrayaren eta bere luzera efektiboaren hasieraketak"); printf("\n\t ---------------------------------------------------\n"); printf("\n\t Arrayaren LUZMAX=%d elementuak hasieraketa ondoren: \n", LUZMAX); BektoreaIkusi(afBektorea, LUZMAX); printf("\n\t Arrayaren iLuzera=%d elementuak hasieraketa ondoren: \n", iLuzera); BektoreaIkusi(afBektorea, iLuzera); BektorearenDatuakHandituEtaTxikituPosizioenArabera(afBektorea, iLuzera); printf("\t Posizioen arabera datuak aldatu ondoren: \n"); BektoreaIkusi(afBektorea, iLuzera); BektorearenDatuakHandituEtaTxikituBalioenArabera(afBektorea, iLuzera); printf("\t Balioen arabera datuak aldatu ondoren: \n"); BektoreaIkusi(afBektorea, iLuzera); printf("\n"); return 0; } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; // babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } void BektorearenDatuakHandituEtaTxikituPosizioenArabera(float afBektorea[], int iLuzera) // lehen parametroa irterakoa da { // bigarren parametroa sarrerakoa da int iKont; for (iKont=0; iKont < iLuzera; iKont++) { if (iKont % 2 == 1) // posizio bakoitia afBektorea[iKont] = afBektorea[iKont] + 0.5; else // posizio bikoitia afBektorea[iKont] = afBektorea[iKont] - 0.5; } printf("\n"); } void BektorearenDatuakHandituEtaTxikituBalioenArabera(float afBektorea[], int iLuzera) // lehen parametroa irterakoa da { // bigarren parametroa sarrerakoa da int iKont; for (iKont=0; iKont < iLuzera; iKont++) { if (afBektorea[iKont] < 50.0) // txikia afBektorea[iKont] = afBektorea[iKont] + 0.75; else // handia afBektorea[iKont] = afBektorea[iKont] - 0.75; } printf("\n"); }
Arrayaren luzera efektiboa teklatuz eta balioak auzaz. Funtziooen deskribapen laburra hauxe da.
- Elementuetan txikienaren posizioa zehaztu eta itzuli iMinimoaNonDago() funtzioari esker, minimoaren posizioa ezagutzean minimoaren balioa eskura daiteke.
- Elementuetan handienaren posizioa zehaztu eta itzuli iMaximoaNonDago() funtzioari esker, maximoaren posizioa ezagutzean maximoaren balioa eskura daiteke.
- Elementuetan txikienaren balioa zehaztu eta dagokion posizioa pantailaratu, horretarako MinimoaZeinNon() funtzioa aplikatzen delarik (ez da gomendatzen).
- Elementuetan handiena eta dagokion posizioa pantailaratu MaximoaZeinNon() funtzioa aplikatuz (ez da gomendatzen).
- Elementu txikiena eta handiena posizioz elkar trukatu ElkarTrukatu() funtzioa aplikatuz.
/* Ariketa-45c_MinimoaMaximoa: maximoa eta minimoa zehaztu */ // Arrayaren elementuen artean txikienaren balioa zehaztu eta dagokion // posizioa pantailaratu. Elementuetan handiena eta dagokion posizioa // pantailaratu. Elementu txikiena eta handiena posizioz elkar trukatu. #include <stdio.h> #include <stdlib.h> // rand() eta srand() funtzioetarako #include <time.h> // time() funtzioarako #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino void BektoreaAleatoriokiBete(float[], int); void BektoreaIkusi(const float[], int); int iMinimoaNonDago(const float[], int); int iMaximoaNonDago(const float[], int); float fMinimoaZeinNon(const float[], int, int *); // ez da gomendatzen void MaximoaZeinNon(const float[], int, float *, int *); // ez da gomendatzen void ElkarTrukatu(float[], int, int); int main() { float afBektorea[LUZMAX]; int iLuzera; float fMinimoa, fMaximoa; int iMinimoaNon, iMaximoaNon; printf("\n"); printf("\n\t Zerrenda auzaz betetzen zenbaki errealez"); printf("\n\t ----------------------------------------\n"); do { printf("\n\t Zenbat balio sartuko dira? (gehienez %d): ", LUZMAX); scanf("%d", &iLuzera); if (iLuzera < 1 || iLuzera > LUZMAX) printf("\t\a Kopuru desegokia, errepikatu!!! (datua 1 eta %d artekoa)", LUZMAX); } while (iLuzera < 1 || iLuzera > LUZMAX); BektoreaAleatoriokiBete(afBektorea, iLuzera); BektoreaIkusi(afBektorea, iLuzera); printf("\n\t %d datu auzaz hartuko dira, %.1f eta %.1f arteko balioak.", iLuzera, BEHEMUGA, GOIMUGA); printf("\n\n\t Hauek dira minimoa eta maximoa:"); iMinimoaNon = iMinimoaNonDago(afBektorea, iLuzera); printf("\n\t - Minimoaren balioa %.2f da eta bere posizioa %d da", afBektorea[iMinimoaNon], iMinimoaNon); iMaximoaNon = iMaximoaNonDago(afBektorea, iLuzera); printf("\n\t - Maximoaren balioa %.2f da eta bere posizioa %d da", afBektorea[iMaximoaNon], iMaximoaNon); printf("\n\t Hauek biak ez dira gomendatzen:"); fMinimoa = fMinimoaZeinNon(afBektorea, iLuzera, &iMinimoaNon); printf("\n\t - Minimoaren balioa %.2f da eta bere posizioa %d da", fMinimoa, iMinimoaNon); MaximoaZeinNon(afBektorea, iLuzera, &fMaximoa, &iMaximoaNon); printf("\n\t - Maximoaren balioa %.2f da eta bere posizioa %d da", fMaximoa, iMaximoaNon); printf("\n\n\t Minimoa eta maximoa posizioz elkar trukatzen...\n"); ElkarTrukatu(afBektorea, iMinimoaNon, iMaximoaNon); BektoreaIkusi(afBektorea, iLuzera); printf("\n"); return 0; } void BektoreaAleatoriokiBete(float afBektorea[], int iLuzera) // lehen parametroa irteerakoa da { // bigarren parametroa sarrerakoa da int iKont; // printf("\n"); // printf("\n\t [%.2f <= BalioOnargarria <= %.2f]", BEHEMUGA, GOIMUGA); // printf("\n\t ----------------------------------"); srand(time(NULL)); // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du // time(NULL) funtzioak igarotako segundoak itzultzen ditu 1970-01-01 datatik hasita for (iKont=0; iKont < iLuzera; iKont++) { afBektorea[iKont] = ((float)rand()/RAND_MAX) * (GOIMUGA-BEHEMUGA); // 0.0 eta 0.999 artekoa bider (GOIMUGA-BEHEMUGA) // printf("\n %15.2f (0.0 eta %.2f artekoa)", afBektorea[iKont], GOIMUGA-BEHEMUGA); // 0.0 eta 99.9 artekoa } printf("\n"); } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; // babestuta dago printf("\n"); printf("\t Posizioa Balioa\n"); printf("\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } int iMinimoaNonDago(const float afBektorea[], int iLuzera) // funtzioaren emaitza posizioa da { int iKont; int iMinNon; iMinNon = 0; for (iKont=1; iKont < iLuzera; iKont++) { if (afBektorea[iKont] < afBektorea[iMinNon]) // txikiagoa da iMinNon = iKont; } return iMinNon; } int iMaximoaNonDago(const float afBektorea[], int iLuzera) // funtzioaren emaitza posizioa da { int iKont; int iMaxNon; iMaxNon = 0; for (iKont=1; iKont < iLuzera; iKont++) { if (afBektorea[iKont] > afBektorea[iMaxNon]) // txikiagoa da iMaxNon = iKont; } return iMaxNon; } // Ondo dago baina ez da gomendatzen. Minimoaren posizioa kanporatzearekin nahikoa da. float fMinimoaZeinNon(const float afBektorea[], int iLuzera, int *iMinNon) // hirugarren parametroa irteerakoa da { int iKont; float fMinimoarenBalioa; fMinimoarenBalioa = afBektorea[0]; *iMinNon = 0; for (iKont=1; iKont < iLuzera; iKont++) { if (afBektorea[iKont] < afBektorea[*iMinNon]) // txikiagoa da { fMinimoarenBalioa = afBektorea[iKont]; *iMinNon = iKont; } } return fMinimoarenBalioa; } // Ondo dago baina ez da gomendatzen. Maximoaren posizioa kanporatzearekin nahikoa da. void MaximoaZeinNon(const float afBektorea[], int iLuzera, float *fMaximoarenBalioa, int *iMaxNon) // hirugarren eta laugarren parametroak irteerakoa dira { int iKont; *fMaximoarenBalioa = afBektorea[0]; *iMaxNon = 0; for (iKont=1; iKont < iLuzera; iKont++) { if (afBektorea[iKont] > afBektorea[*iMaxNon]) // handiagoa da { *fMaximoarenBalioa = afBektorea[iKont]; *iMaxNon = iKont; } } } void ElkarTrukatu(float afBektorea[], int iMinimoaNon, int iMaximoaNon) { float fLaguntzailea; fLaguntzailea = afBektorea[iMinimoaNon]; afBektorea[iMinimoaNon] = afBektorea[iMaximoaNon]; afBektorea[iMaximoaNon] = fLaguntzailea; }
Arrayaren luzera efektiboa teklatuz eta balioak auzaz. Arrayak gutxienez elementu bat izango duelako, luzera efektibo txikiena 1 izango da (eta handiena 19, noski). Ondoren, modu aleatorioan 0.0 eta 99.99 arteko zenbakiak bektorean biltegituko dira.
Datuak ditugula fMediaKalkulatu() eta MediaKalkulatu() funtzioen bitartez balio guztien arteko batezbesteko aritmetikoa kalkulatzen da eta emaitza modulu deitzaileari itzultzen zaio, bertan pantailaratu dadin. Biak ondo egon arren, fMediaKalkulatu() funtzioa hobesten da MediaKalkulatu() funtzioa baino errazagoa delako.
/* Ariketa-45d_ElementuGuztiakProzesatu: arrayaren elementuen media kalkulatu */ // Errealekin lan eginez. Array bat datuz auzaz bete funtzio batean eta // ondoren arrayaren elementuen media kalkulatu beste funtzio bati esker. #include <stdio.h> #include <stdlib.h> // rand() eta srand() funtzioetarako #include <time.h> // time() funtzioarako #define BEHEMUGA 0.0 #define GOIMUGA 99.9 #define LUZMAX 20 // 20 elementu gehienez: 0. posiziotik 19. posizionarino void BektoreaAleatoriokiBete(float[], int); void BektoreaIkusi(const float[], int); float fMediaKalkulatu(const float[], int); void MediaKalkulatu(const float[], int, float *); int main() { float afBektorea[LUZMAX]; int iLuzera; float fMedia, fBBA; printf("\n"); printf("\n\t Zerrenda auzaz betetzen zenbaki errealez"); printf("\n\t ----------------------------------------\n"); do { printf("\n\t Zenbat balio sartuko dira? (gehienez %d): ", LUZMAX); scanf("%d", &iLuzera); if (iLuzera < 1 || iLuzera > LUZMAX) printf("\t\a Kopuru desegokia, errepikatu!!! (datua 1 eta %d artekoa)", LUZMAX); } while (iLuzera < 1 || iLuzera > LUZMAX); printf("\n\t %d datu auzaz hartuko dira, %.1f eta %.1f arteko balioak.", iLuzera, BEHEMUGA, GOIMUGA); BektoreaAleatoriokiBete(afBektorea, iLuzera); BektoreaIkusi(afBektorea, iLuzera); fMedia = fMediaKalkulatu(afBektorea, iLuzera); printf("\n\t\t fMedia = %.2f (hau errazagoa da)", fMedia); MediaKalkulatu(afBektorea, iLuzera, &fBBA); printf("\n\t\t fBBA = %.2f (bestea hobesten da)", fBBA); printf("\n"); return 0; } void BektoreaAleatoriokiBete(float afBektorea[], int iLuzera) // lehen parametroa irteerakoa da { // bigarren parametroa sarrerakoa da int iKont; // printf("\n"); // printf("\n\t [%.2f <= BalioOnargarria <= %.2f]", BEHEMUGA, GOIMUGA); // printf("\n\t ----------------------------------"); srand(time(NULL)); // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du // time(NULL) funtzioak igarotako segundoak itzultzen ditu 1970-01-01 datatik hasita for (iKont=0; iKont < iLuzera; iKont++) { afBektorea[iKont] = ((float)rand()/RAND_MAX) * (GOIMUGA-BEHEMUGA); // 0.0 eta 0.999 artekoa bider (GOIMUGA-BEHEMUGA) // printf("\n %15.2f (0.0 eta %.2f artekoa)", afBektorea[iKont], GOIMUGA-BEHEMUGA); // 0.0 eta 99.9 artekoa } printf("\n"); } void BektoreaIkusi(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; // afBektorea[3] = 3.33; // babestuta dago printf("\n"); printf("\t\t Posizioa Balioa\n"); printf("\t\t -------- ------\n"); for (iKont=0; iKont < iLuzera; iKont++) { printf("\t\t %9d %13.2f\n", iKont, afBektorea[iKont]); } } float fMediaKalkulatu(const float afBektorea[], int iLuzera) // bi parametroak sarrerakoak { int iKont; float fMetatua; // afBektorea[3] = 3.33; // babestuta dago fMetatua = 0.0; for (iKont=0; iKont < iLuzera; iKont++) { fMetatua = fMetatua + afBektorea[iKont]; } return fMetatua / iLuzera; } void MediaKalkulatu(const float afBektorea[], int iLuzera, float *fBBA) // azken parametroa irteerakoa { int iKont; float fMetatua; // afBektorea[3] = 3.33; // babestuta dago fMetatua = 0.0; for (iKont=0; iKont < iLuzera; iKont++) { fMetatua = fMetatua + afBektorea[iKont]; } *fBBA = fMetatua / iLuzera; //BatazBestekoAritmetikoa irteerakoa da }
Esan bezala, lehen bertsioa ikastea ezinbestekoa da, bigarren bertsioa ulertzea besterik ez da eskatzen:
|
iruzkinik ez:
Argitaratu iruzkina