2024(e)ko abenduaren 1(a), igandea

Ariketa 19 | Zenbakien funtzio estandarrak


ZER DAKIDAN:
Funtzio batek sarreraren bat hartzen du eta emaitza bakar itzultzen du. Dagoeneko funtzio estandar hauek erabili ditut (denek math unitatea sartzea behar dute):
  • fabs()
  • sin(), cos() eta tan()
  • asin(), acos() eta atan()
  • sqrt()
  • pow()


ZER IKASIKO DUDAN:
Funtzioekin jarraituz rand() funtzio estandarra ikasiko dut eta hori erabiltzeko srand() funtzio estandarra ikasiko dut. Funtzioekin aurrera eginez, log(), log2(), log10(), exp() eta modf() funtzioak ikasiko ditut ere.


Zerrenda honetan azpiprograma estandar batzuk deskribatzen dira, gogoratu #include <math.h> derrigorrezkoa dela:
double fabs(double x);   // x zenbaki errealaren kopuruari dagokion balio absolutua kalkulatzen du
double sin(double x);    // x angeluaren (radianetan neurtuta) sinua itzultzen du
double cos(double x);    // x angeluaren (radianetan neurtuta) kosinua itzultzen du 
double tan(double x);    // x angeluaren tangentea itzultzen du 
double asin(double x);   // x angeluaren (-PI/2 eta +PI/2 tartekoa) arku sinua itzultzen du 
double acos(double x);   // x angeluaren (0.0 eta +PI/2 tartekoa) arku kosinua itzultzen du 
double atan(double x);   // x angeluaren (-PI/2 eta +PI/2 tartekoa) arku tangentea itzultzen du  
double pow(double x, double y);   // x zenbaki errealaren kopurua ber y kalkulatzen du   
double sqrt(double x);   // x erro karratuaren emaitza itzultzen du
double exp(double x);    // e ber x kalkulatzen du
double log(double x);    // logaritmo naturala itzultzen du
double log2(double x);   // bi oinarriko logaritmoa itzultzen du
double log10(double x);  // hamar oinarriko logaritmoa itzultzen du
double fmod(double dbZatikizu, double dbZatitzai);  // zatikizuna eta zatitzailea emanik, zatiketa osoaren hondarra itzultzen du
double modf(double dbBalio, double *dbZatiOsoa);    // dbBalio argumentua zati oso batean eta hamartar bestean bitan zatitzen du, eta bakoitzak argumentuaren zeinu bera du. Zati hamartarra da funtzioak itzultzen duena eta zati osoa double bat bezala gordetzen du dbZatiOsoa argumentuak adierazitako objektuan
Eta zerrenda honetan beste azpiprograma estandar batzuk deskribatzen dira, ez ahaztu #include <stdlib.h> derrigorrezkoa dela:
int abs(int x);                   // x zenbaki osoaren kopuruari dagokion balio absolutua kalkulatzen du
int rand(void);                   // zenbaki oso sasi-aleatoria kalkulatzen du 0tik RAND_MAX=2147483647 bitartean
                                  // RAND_MAX inplementazioaren araberakoa da baina gutxienez RAND_MAX=32767
void srand(unsigned int iHazia);  // iHazia argumentua sasi-ausazko zenbakien sekuentzia berri baterako hazi gisa
                                  // erabiltzen du rand() funtzioak ondorengo deietan balioak itzultzeko

rand() funtzioak kopuru osoak itzultzen ditu, baina zenbaki erreal aleatorioak lor daitezke ere laster ikusiko dugun bezala.


rand() eta srand()

Zenbaki aleatorioak eskuratzeko rand() funtzio estandarra estandarra beharko dugu eta horrekin batera srand() funtzio estandarra ere.

Dado bat 3 aldiz jaurti dela simulatuko dugu. Dadoak 6 posibilitate ditu: 1, 2, 3, 4, 5 eta 6. Gure programak 3 jaurtiketa aleatorien emaitzak batuko ditu eta baturaren arabera mezu hau pantailaratuko du:

  • 3 jaurtiketen baturak 13 edo gehiago balio badu, pantailaraketa Oso ondo izango da
  • 3 jaurtiketen batura 10 eta 12 artekoa bada, pantailaraketa Nahiko ondo izango da
  • 3 jaurtiketen batura 7 eta 9 artekoa bada, pantailaraketa Txarto izango da
  • 3 jaurtiketen baturak 6 edo gutxiago balio badu, pantailaraketa Oso txarto izango da

Zenbaki osoekin jarraituz, kopuru aleatorioak 1 eta 6 artekoak izan ordez, 2 eta 4 bi mugen artekoak eskuratzeko horrela joko dugu:

/* Ariketa-19a1_FuntzioEstandarrak: zenbaki sasi-aleatorioak lortzen (kopuru osoak) */

// rand() ikasiko dugu, baina srand() funtzioarekin lotuta dago.
// Zenbaki aleatorioen segida lortzeko hazi bat behar da eta time() funtzioa erabiliko da NULL parametroarekin.
// rand() bitartez lortuko diren zenbaki aleatorioak kopuru osoak izango dira.

// Dado baten hiru jaurtiketa simulatuko da eta batura lortuz programak adieraziko digu
// jokaldia nolakoa izan den: oso txarra, txarra, ona ala oso ona.

#include <stdio.h>    // printf() funtzioarako
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <math.h>     // fmod() funtzioarako
#include <time.h>     // time() funtzioarako

int main()
{
    int iBatura = 0;
    int iJaurtiketarenBalioa;

    printf("\n");
    printf("\n Dadoa hiru aldiz jaurti ondoren");
    printf("\n -------------------------------");

    srand(time(NULL));   // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du
                         // Hazia, adibidez, time(NULL) funtzioa izan daiteke zeinek igarotako
                         // segundoak itzultzen ditu 1970-01-01 datatik hasita

    iJaurtiketarenBalioa = rand();                                   // 0 eta RAND_MAX=32767 arteko balioa
    iJaurtiketarenBalioa = iJaurtiketarenBalioa % 6 + 1;             // 1 eta 6 arteko balioa
    // edo iJaurtiketarenBalioa = fmod(iJaurtiketarenBalioa, 6) + 1;    1 eta 6 arteko balioa
    printf("\n 1. jaurtiketan %d atera da", iJaurtiketarenBalioa);
    iBatura = iBatura + iJaurtiketarenBalioa;

    iJaurtiketarenBalioa = rand();                                   // 0 eta RAND_MAX=32767 arteko balioa
    iJaurtiketarenBalioa = iJaurtiketarenBalioa % 6 + 1;             // 1 eta 6 arteko balioa
    // edo iJaurtiketarenBalioa = fmod(iJaurtiketarenBalioa, 6) + 1;    1 eta 6 arteko balioa
    printf("\n 2. jaurtiketan %d atera da", iJaurtiketarenBalioa);
    iBatura = iBatura + iJaurtiketarenBalioa;

    iJaurtiketarenBalioa = rand();                                   // 0 eta RAND_MAX=32767 arteko balioa
    iJaurtiketarenBalioa = iJaurtiketarenBalioa % 6 + 1;             // 1 eta 6 arteko balioa
    // edo iJaurtiketarenBalioa = fmod(iJaurtiketarenBalioa, 6) + 1;    1 eta 6 arteko balioa
    printf("\n 3. jaurtiketan %d atera da", iJaurtiketarenBalioa);
    iBatura = iBatura + iJaurtiketarenBalioa;

    printf("\n");
    switch(iBatura)
    {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6: printf("\n OSO TXARTO hiru jaurtiketen batura %d izan delako", iBatura);
                break;
        case 7:
        case 8:
        case 9: printf("\n TXARTO hiru jaurtiketen batura %d izan delako", iBatura);
                break;
        case 10:
        case 11:
        case 12: printf("\n NAHIKO ONDO hiru jaurtiketen batura %d izan delako", iBatura);
                 break;
        default: printf("\n OSO ONDO hiru jaurtiketen batura %d izan delako", iBatura);
                 break;
   }

    printf("\n\n");
    return 0;
}


rand() eta srand()

Zenbaki osoekin jarraituz, kopuru aleatorioak 1 eta 6 artekoak izan ordez, 2 eta 4 bi mugen artekoak eskuratzeko horrela joko dugu:

/* Ariketa-19a2_FuntzioEstandarrak: zenbaki sasi-aleatorioak lortzen (kopuru osoak) */
// Ariketa-19a1_FuntzioEstandarrak bezalakoa, baina 2 eta 4 mugen arteko kopuruekin.

#include <stdio.h>    // printf() funtzioarako
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <time.h>     // time() funtzioarako

#define BEHEMUGA 2
#define GOIMUGA 4

int main()
{
    int iKont;

    printf("\n");
    printf("\n Manipulatutako dadoa %d eta %d artean", BEHEMUGA, GOIMUGA);
    printf("\n -----------------------------------");

    srand(time(NULL));   // zenbaki aleatorioak hasiarazteko

    for (int iKont = 1; iKont <= 10; iKont++)
    {
       // random zenbakiak GOIMUGA=4 eta BEHEMUGA=2 artekoak  (biak barne)
       // rand()%(GOIMUGA-BEHEMUGA+1)             rand()%3    (0, 1 edo 2)
       // rand()%(GOIMUGA-BEHEMUGA+1)+BEHEMUGA    rand()%3+2  (2, 3 edo 4)
       iJaurtiketarenBalioa = rand() % (GOIMUGA - BEHEMUGA + 1) + BEHEMUGA;
       printf("\n %5d. jaurtiketan %d atera da", iKont, iJaurtiketarenBalioa);
    }

    printf("\n\n");
    return 0;
}

Manipulatu den dadoaren programa honetan for agindu errepikakorra agertzen da. Aurrerago azalduko da modu xehean, baina orain jakin dezagun for aginduak balio duela ekintzak errepikatzeko kopuru jakin batean, adibidean ekinza 10 aldiz errepikatzen da.



rand() eta srand()

Zenbaki errealekin lan eginez, balio aleatorioak lortzen dituen programa idatziko dugu. Ikusi dugun rand() funtzioak 0 eta RAND_MAX=32767 arteko kopuru osoa itzultzen duenez kode gehiago gehituko zaio programari zenbaki errealekin lan egiteko, zatiketa bat eta datu-mota beharketa bat. Honelaxe:

    
       fZenbakia = (float)rand()/RAND_MAX;    // 0.0 eta 0.999 arteko balioa
       printf("fZenbakia = %f\n", fZenbakia);

Programa osoa hemen. Non lehen for aginduan 15 iterazio egiten diren 0 eta RAND_MAX=32767 arteko zenbaki sasi aleatorio osoak lortuz, eta bigarren for aginduan beste 15 iterazio egiten diren auzazko zenbaki sasi aleatorio osoak 0.0 eta 0.999 esparrura mugatuz:

/* Ariketa-19b1_FuntzioEstandarrak: zenbaki sasi-aleatorioak lortzen (kopuru errealak) */

// rand() ikasiko dugu, baina srand() funtzioarekin lotuta dago.
// Zenbaki aleatorioen segida lortzeko hazi bat behar da eta time() funtzioa erabiliko da
// NULL parametroarekin zeinek igarotako segundoak itzultzen ditu 1970-01-01 datatik hasita.
// rand() bitartez lortuko diren zenbaki aleatorioak 0 eta RAND_MAX=32767 arteko kopuru
// osoak izango dira. Zenbaki erreala lortzeko zatiketa+beharketa egin daiteke.

#include <stdio.h>    // printf() funtzioarako
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <time.h>     // time() funtzioarako

#define BEHEMUGA 2
#define GOIMUGA 4

int main()
{
    float fZenbakia;
    int iKopurua;

    printf("\n");

    srand(time(NULL));   // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du
                         // Hazia, adibidez, time(NULL) funtzioa izan daiteke zeinek igarotako
                         // segundoak itzultzen ditu 1970-01-01 datatik hasita
    iKopurua = rand();
    printf("Zenbaki sasi aleatorioen hazia %d da\n", iKopurua);

    printf("\n \t 0 eta RAND_MAX=%d artekoak", RAND_MAX);
    printf("\n \t -----------------------------\n");
    for (int iKont = 1; iKont <= 15; iKont++)
    {
       iKopurua = rand();   // 0 eta RAND_MAX=32767 arteko kopuru osoa
       printf("%10d \t iKopurua = %d\n", iKont, iKopurua);
    }

    printf("\n \t 0.0 eta 0.999 arteko balioak");
    printf("\n \t ----------------------------\n");
    for (int iKont = 1; iKont <= 15; iKont++)
    {
       fZenbakia = (float)rand()/RAND_MAX;   // 0.0 eta 0.999 arteko balio erreala
       printf("%10d \t fZenbakia = %f\n", iKont, fZenbakia);
    }

    printf("\n");
    return 0;
}


rand() eta srand()

Zenbaki errealekin lan eginez, balio aleatorioak lortzen dituen programa idatziko dugu. Ikusi dugun rand() funtzioak kopuru osoa itzultzen duenez kode gehiago gehituko zaio programari zenbaki errealekin lan egiteko, hauxe:

    #define BEHEMUGA1 70.5  // abiadura aleatorioaren minimoa
    #define GOIMUGA1 100.6  // abiadura aleatorioaren maximoa
    
    fAbiadura = ((float)rand()/(float)(RAND_MAX)) * (GOIMUGA1-BEHEMUGA1);        // 0.0 eta 0.999 artekoa bider (GOIMUGA1-BEHEMUGA1)
    printf("\n %10f  (0.0 eta %.1f artekoa)", fAbiadura, GOIMUGA1-BEHEMUGA1);    // 0.0 eta 30.1 artekoa
    fAbiadura= fAbiadura + BEHEMUGA1;
    printf("\n %10f  (%.1f eta %.1f artekoa)", fAbiadura, BEHEMUGA1, GOIMUGA1);  // 70.5 eta 100.6 artekoa

Auto baten abiadura adierazten duen zenbaki erreal bat aleatorioki lortuko da, baina zenbaki aleatorio horren balioa bi mugen artekoa izan beharko da: behemuga 70.5 km/h eta goimuga 100.6 km/h.

Auto horren denbora adierazten duen zenbaki erreal bat aleatorioki lortuko da, eta bigarren zenbaki aleatorio horren balioa bi mugen artekoa izan beharko da ere: behemuga 0.5 segundo eta goimuga 2.0 segundo.

Aurreko bi datuekin (abiadura eta denbora) distantziaren kalkulua burutuko da. Eskatzen den programaren exekuzio-adibide bat jarraian erakusten da:

Eta hemen azalpena:


Goiko irudian Ariketa-19b2_FuntzioEstandarrak programaren bigarren for aginduaren pantailaraketak iruzkindu dira, adibideko 1.961043 denbora aleatorioa (0.5 segundo eta 2.0 segundo artekoa) lau urratsetan lortzen da:

  1. rand() funtzioa aplikatu auzazko balio osoa eskuratzeko (31916 adibidean)
  2. Lortutako balio osoa normalizatu 0.0 eta 0.999 esparrura (0.974029 adibidean)
  3. Balio erreala eskalatu (GOIMUGA-BEHEMUGA2) esparrura (1.461043 adibidean)
  4. Aurreko urratsean lortutakoari BEHEMUGA2 oinarria gehitu (1.961043 adibidean)


rand() eta srand()

Demagun azterketa baten notak auzaz lortu nahi direla, jakinik kalifikaziorik txikiena 0.00 dela eta kalifikaziorik handiena 9.99 dela. Nahiz eta notak zenbaki errealak diren, balio aleatorioak lortzean 0 eta 9 arteko kopuru osoak erabiliko ditugu:

/* Ariketa-19b3_FuntzioEstandarrak: zenbaki sasi-aleatorioak lortzen (kopuru errealak) */

// rand() ikasiko dugu, baina srand() funtzioarekin lotuta dago.
// Zenbaki aleatorioen segida lortzeko hazi bat behar da eta time() funtzioa erabiliko da
// NULL parametroarekin zeinek igarotako segundoak itzultzen ditu 1970-01-01 datatik hasita.
// rand() bitartez lortuko diren zenbaki aleatorioak 0 eta RAND_MAX=32767 arteko kopuru
// osoak izango dira. Hamartar bakarra duen zenbaki erreala lortzeko osoekin lan egin daiteke.

// Demagun azterketa baten nota adierazten duten 0.00 eta 9.99 arteko hainbat zenbaki erreal
// ditugula eta nota guztien batezbesteko aritmetikoa kalkulatu nahi dela.

#include <stdio.h>    // printf() funtzioarako
#include <stdlib.h>   // rand() eta srand() funtzioetarako
#include <time.h>     // time() funtzioarako

#define iZENBAT 20

int main()
{
    float fNota;
    int iUnitatea;
    int iHamarrekoa;
    int iEhunekoa;
    float fBatukaria = 0.0;

    srand(time(NULL));   // srand() zenbaki aleatorioak berriro hasiarazteko, hazia behar du
                         // Hazia, adibidez, time(NULL) funtzioa izan daiteke zeinek igarotako
                         // segundoak itzultzen ditu 1970-01-01 datatik hasita

    printf("\n");
    printf(" %d kalifikazio: 0.00 eta 9.99 arteko balio sasi-aleatorioak\n", iZENBAT);
    printf(" -----------------------------------------------------------\n");
    for (int iKont = 1; iKont <= iZENBAT; iKont++)
    {
       iUnitatea = rand() % 10;     // 0 eta 9 arteko balioak
       iHamarrekoa = rand() % 10;   // 0 eta 9 arteko balioak
       iEhunekoa = rand() % 10;     // 0 eta 9 arteko balioak
       fNota = iUnitatea + 0.1*iHamarrekoa + 0.01*iEhunekoa;
       fBatukaria = fBatukaria + fNota;
       printf("%4d    iUnitatea=%d  iHamarrekoa=%d  iEhunekoa=%d  fNota=%.2f\n", iKont, iUnitatea, iHamarrekoa, iEhunekoa, fNota);
    }
    printf(" -----------------------------------------------------------\n");

    printf("\n Bataztesteko aritmetikoa %.2f da\n", fBatukaria/iZENBAT);

    printf("\n");
    return 0;
}


log() eta exp()

5.2x=7.9  bezalako ekuazio esponentziala ebazteko logaritmoa erabil behar da, hots, logaritmo nepertarra kalkulatzen duen log() funtzio estandarra. Modu beretsuan, 7.13.4=x bezalako ekuazioak ebazteko exp() funtzio estandarra aplika dezakegu.

Eskatzen den programaren exekuzio-adibide bat ikusi:








log(), log2(), log10() eta beste oinarriko logaritmoak

Zenbaki errealekin lan eginez, balio positibo bat teklatuz irakurri eta programak zenbakiaren logaritmo hamartarra kalkula dezala log10() funtzio estandarra erabili gabe. Logaritmo bitarra eskuratzeko funtzio estandarrik ez dagoenez, logaritmo nepertarraren funtzioa aplikatu beharko da formula hauen arabera:

log10(x) = log(x)/log(10)
log2(x) = log(x)/log(2)



exp() eta beste oinarriko potentziak

Zenbaki errealekin lan eginez, exponentea izango den balio positibo edo negatibo bat teklatuz irakurri (adibidez Z=4.001), ondoren oinarria izango den balio positibo edo negatibo bat teklatuz irakurri (adibidez Y=2.001). Programak datuen potentzia kalkula dezala (emaitza X=2.0014.001). Horrelako lana burutzeko adibidez pow()funtzio estandarra izan arren, logaritmo nepertarraren log() funtzioa eta e zenbakiari dagokion exp() potentziaren funtzioa aplikatuko dira esleipen hau eginez:

fEmaitza = exp(fZenbakia*log(fOinarria));

Goiko esleipenaren justifikazioa jarraian ematen da:
            Z datua den zenbaki erreala (exponentea)
            Y datua den zenbaki erreala (oinarria)
            X lortu nahi den potentzia

            X = Y^Z    logaritmo nepertarrak hartuz:
                       log(X) = log(Y^Z)  --->  log(X) = Z·log(Y) 
                       log(X) = Z·log(Y)
            exp() funtzioa aplikatuz:
                       log(X) = Z·log(Y) 
                       exp(log(X)) = exp(Z·log(Y))
                       X = exp(Z·log(Y))




fmod() eta modf()

Funtzio guztiz desberdinak dira, baina izenak oso antzekoak direlako nahasteko arriskua dago. Funtzio biek bi parametro dituzte, baina parametroen esanahia eta funtzioaren emaitzak oso bestelakoak dira.

fmod() funtzioaren helburua da zatiketa osoaren hondarra itzultzea. Bere ohiko deia honelako zerbait da, non parametroen datu-motak float izan daitezke eta int izan daizteke.

dbHondarra = dbZatikizuna % dbZatitzailea;  // edo
dbHondarra = fmod(dbZatikizuna, dbZatitzailea);

modf() funtzioaren helburua da zenbaki erreal baten zati hamartarra eta zati osoa eskuratzea, kasu honetan datua bakarra da (zenbaki errealaren balioa) eta emaitzak bi dira (zati hamartarra eta zati osoa), hona hemen modf() funtzioaren balizko dei bat:

dbZatiHamartarra = modf(dbBalioa, &dbZatiOsoa);

Ikusten denez bigarren parametroa helbide bat da, zati osoa gordeko duen zenbaki errealaren helbidea hain zuzen ere. Ikusten da ere zati hamartarra modf() funtzioak itzultzen duen emaitza dela.

Hauxe izan daiteke eskatzen den programaren irteera:




asin(), acos() eta atan()

Zenbaki errealekin lan eginez, angelu baten sinua adierazten duen balio bat teklatuz irakurri (-1.0 eta +1.0 arteko balioa) eta programak angelua lortuko du radianetan:

fAngelua = asin(fSinuarenDatua);

Gauza bera egin daiteke datua angeluaren kosinua baldin bada acos funtzioa aplikatuz. Edozein kasutan, asin eta acos funtzio estandarrak erabil ahal izateko math liburutegia kargatu beharko da (berdin atan funtzioarekin, math liburutegia beharrezkoa da).

Hemen asin funtzioaren grafikoa (irudiaren gainean klik egin balioak emateko):



Hauxe izan daiteke eskatzen den programaren irteera:







  • Ariketa-19a1_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19a2_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19b1_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19b2_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19b3_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19c_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19d_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19e_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19f_FuntzioEstandarrak.cbp | main.c  
  • Ariketa-19g_FuntzioEstandarrak.cbp | main.c  

 

Ariketa 18 | switch: Aukera anitzen arteko hautapena

ZER DAKIDAN:
if baldintzazko egitura eta if-else baldintzazko egitura menperatzen ditut.



ZER IKASIKO DUDAN:
Aldagai aukeratzailea zenbaki oso bat izanik, switch baldintzazko egitura ikasiko dut.

Ariketa 13 | Ekuazioa sistema artikulua edo Ariketa 14 | Bigarren graduko ekuazioa artikulua gogora ekarriz, programaren fluxua desbideratu daiteke if agiduari esker eta if-else aginduari esker. Baina fluxuaren aukerak hiru edo gehiago direnean switch kontrol-agindua erabil daiteke.



ESKATZEN DEN PROGRAMA

Demagun lurrazaleko lau leku ditugula, bakoitza hemisferiko banakoa. Lau lekuak hauek dira: 1 Adelaide, 2 Brasilia, 3 Calgary eta 4 Donetsk. Lau leku horiek zenbaki oso baten bitartez identifikatuko ditugu. Zenbaki identifikatzailea teklatuz irakurri eta balioaren arabera, lurrazaleko lekuari dagokion informazioa pantailaratu:



  1 identifikatzailea:
Adelaide
Latitudea: -34.927499
Longitudea: 138.600000
Hego-Ekialdeko hemisferioa

  2 identifikatzailea:
Brasilia
Latitudea: -15.793889
Longitudea: -47.882778
Hego-Mendebaldeko hemisferioa

  3 identifikatzailea:
Calgary
Latitudea: 51.047500
Longitudea: -114.062500
Ipar-Mendebaldeko hemisferioa

  4 identifikatzailea:
Donetsk
Latitudea: 48.008889
Longitudea: 37.804167
Ipar-Ekialdeko hemisferioa


Exekuzioan 1 zenbakia aukeratzean lortzen dena

Exekuzioan 4 zenbakia aukeratzean lortzen dena


LASTER ESKATUKO DEN PROGRAMA

char datu mota ikasiko dugunean, sarrerako datua zenbaki bat izan ordez karaktere bat izango da: A Adelaide, B Brasilia, C Calgary eta D Donetsk. Beraz, ataria identifikatzeko sarrerako datua A, B, C edo D letrak izango dira. Bide batez, laster eskatuko den programa horretan, system("cls") aginduaren bitartez, pantaila garbitzen ikasiko dugu ere.

Esan bezala, switch batean aukeratzailea balio diskretua izango da beti, ikusi zer gertatzen den 1 eta 2 arteko balio zatigarria aukeratzen bada:




switch baldintzazko aginduak aldagai aukeratzaile bat darabil eta aukeratzaile hori datu-mota ordinal bat izango da (zenbaki osoa adibidez edo karakterea adibidez). Sintaxiari dagokiolarik, switch kontrol-aginduan break bati esker bukatzen da agindua hurrengo aukerak ebaluatu gabe.

Ebaluazio baten nota adierazten duen zenbaki osoa irakurri ondoren dagokion hitzezko kalifikazioa pantailaratu:
Hau da Ariketa-18a_AukeraAnitzenArtekoHautapena.cbp proiektuaren iturburu-programa



Ebaluazio baten nota adierazten duen zenbaki ez-osoa irakurri eta dagokion hitzezko kalifikazioa pantailaratu:
Ariketa-18b1_AukeraAnitzenArtekoHautapena.cbp proiektuaren kodea non esparruak mugatzeko baldintza konposatua daukaten hainbat if kontrol-egiturak erabiltzen diren

Goian erakutsi den Ariketa-18b1_AukeraAnitzenArtekoHautapena.cbp proiektuaren baldintza konposatuak sahiestu ahal izateko if-else sorta bat kateatuz lor daiteke; esate baterako, Ariketa-18b2_AukeraAnitzenArtekoHautapena.cbp proiektuan egiten den bezala. Lehen if-aren bitartez behemuga zaintzen da eta azken else-aren bitartez goimuga zaintzen da, tartean dauden else if bikoteak bloke bana definitzen du. Kodea ikusi:

/* Ariketa-18b2_AukeraAnitzenArtekoHautapena: Zenbaki errealekin,
                                              kalifikazioak pantailaratu. */

// switch kontrol-agindua ezin daiteke erabili aldagai aukeratzailea
// float bat delako, horregatik if-else kateatuekin programatuko da.


#include <stdio.h>

#define NOTAMINIMOA 0.0
#define NOTAMAXIMOA 10.0

int main()
{
    float fNota;

    printf("\n");

    printf("\n Notari dagokion zenbakia eman");
    printf(" (0.0 eta 10.0 arteko datua): ");
    scanf("%f", &fNota);

    if (fNota <= 0.0)
        printf("\n Nota %.1f eta %.1f artean egongo da!", NOTAMINIMOA, NOTAMAXIMOA);
    else if (fNota < 3.0)
        printf("\n %.2f puntu | Oso txarto!", fNota);
    else if (fNota < 5.0)
        printf("\n %.2f puntu | Txarto!", fNota);
    else if (fNota < 6.0)
        printf("\n %.2f puntu | Nahiko!", fNota);
    else if (fNota < 7.0)
        printf("\n %.2f puntu | Ondo!", fNota);
    else if (fNota < 9.0)
        printf("\n %.2f puntu | Oso ondo!", fNota);
    else if (fNota <= 10.0)
        printf("\n %.2f puntu | Bikain!", fNota);
    else  // bestelako daturik ematean
        printf("\n Nota %.1f eta %.1f artekoa izango da!", NOTAMINIMOA, NOTAMAXIMOA);

    printf("\n\n");
    return 0;
}






  • Ariketa-18_MenuBat.cbp | main.c  
  • Ariketa-18a_AukeraAnitzenArtekoHautapena | main.c  
  • Ariketa-18b1_AukeraAnitzenArtekoHautapena | main.c  
  • Ariketa-18b2_AukeraAnitzenArtekoHautapena | main.c  

 

Ariketa 17 | Edozein triangeluren azalera

ZER DAKIDAN:
Ikasi dudan Ariketa 16 | Triangeluaren azalera artikuluko programan ekidin dira AB zuzen perpendikularraren kasu partikularra eta CP zuzen perpendikularraren kasu partikularra.



ZER IKASIKO DUDAN:
Ariketa honetan edozein maldatako zuzenekin lan egiten ikasiko dut.


Programa bat inkrementalki garatzen

Ariketa 16 | Triangeluaren azalera ariketa gogoratu eta osatu: XOY lehen koadranteko triangelu bat bere ABC erpinen bitartez definiturik dator (erpinen koordenatuak zenbaki errealak dira). A puntua eta B puntua lotzen dituen AB lerroa edozein izan daiteke: bertikala, horizontala edo zeiharra.

A, B eta C sarrerako datuek bete behar dituzten baldintza bakarrak hiru dira:
  • A, B  eta C puntuak lehen koadrantean kokaturik daude
  • A eta B puntuak ez direla bat
  • C puntua ez dagoela kokaturik AB segmentuaren zuzenean
Triangeluaren azalera kalkulatzeko 4 urratsetan egingo dugu:
  1. Emanik A puntua eta B puntua, AB zuzena lortu eta bere izaeraren arabera (bertikala, horizontala edo zeiharra) erabaki hurrengo urratsak nola burutuko diren
  2. Emanik C puntua, AB zuzenari dagokion lerro perpendikularra C puntuan lortu
  3. AB zuzena eta bere perpendikularra C puntuan ditugula, lerro biren ebakidura kalkulatu (P puntua lortu)
  4. Erpinen arteko AB distantzia eta puntuen arteko CP distantzia kalkulatu ondoren azalera zehaztu

Emanik A puntua eta B puntua, programak hiru atal izago ditu. Honako hiru atal hauek:

/* Ariketa-17_EdozeinTriangelu: kasu partikularrak aintzat hartzen dira,
                                AB segmentua bertikala edo horizontala. */

//  A eta B bi puntu desberdin eman jakinik ez direla bertikal berean egongo
//  ezta horizontal berean, dagozkien zuzenaren y = mx + n ekuazioa lortu
//  ondoren, beste hirugarren C puntu bat eskatu aurrekoen lerroan ez dagoena
//  eta hortik pasatzen den zuzen perpendikularraren y = m'x + n' ekuazioa
//  kalkulatu. Ostean, bi lerroen arteko ebakidura P puntua zehaztu.

//  A eta B puntuen arteko distantzia lortu (oinarria), C eta P puntuen arteko
//  distantzia eskuratu (altuera). ABC triangeluaren azalera kalkulatu.

//  Kasu partikularrak:

/*
      if (fAx == fBx)  // 1. ATALA: AB segmentua bertikala denean
      {
         ...
      };
      else  // AB segmentua bertikala EZ denean
      {
         if (fAy == fBy)  // 2. ATALA: AB segmentua horizontala denean
         {
            ...
         };
         else // 3. ATALA: AB segmentua zeiharra denean, ez bertikala ez horizontala
         {
            ...
         };
      };
*/

#include <stdio.h>
#include <math.h>    // sqrt() funtziorako

int main()
{
    float fAx, fAy, fBx, fBy;
    float fMalda, fDesplazamendua;
    float fCx, fCy;
    float fMaldaPerpendikularra, fDesplazamenduPerpendikularra;
    float fPx, fPy;
    float fOinarria, fAltuera;

    printf("\n");
    // A puntua lehen koadrantekoa da
    do
    {
        printf("\n OXY lehen koadrantean lan eginez...\n");
        printf(" Eman A puntuaren x koordenatua: ");
        scanf("%f", &fAx);
        printf(" Eman A puntuaren y koordenatua: ");
        scanf("%f", &fAy);

    } while (_________________);

    printf("\n");
    // B puntua ere lehen koadrantekoa izango da eta horrez gain
    // B puntua eta A puntua ez dira bat izango
    do
    {
        printf("\n OXY lehen koadrantean lan eginez...\n");
        printf(" Eman B puntuaren x koordenatua: ");
        scanf("%f", &fBx);
        printf(" Eman B puntuaren y koordenatua: ");
        scanf("%f", &fBy);

    } while (_________________);

    if (fAx == fBx)  // 1. ATALA: AB segmentua bertikala denean
    {
        printf("\n");
        printf("\n AB segmentua bertikala da");
        printf("\n -------------------------\n");
        printf("\n Zuzenaren malda = INFINITU");
        printf("\n Zuzen perpendikularraren desplazamendu bertikala = INFINITU");
        printf("\n Zuzenaren ekuazioa  r |  x=%.3f", fAx);

        // C puntua ere lehen koadrantekoa izango da eta horrez gain
        // C puntua ez da egongo bertikala den AB segmentuaren zuzenean
        printf("\n");
        printf("\n OXY lehen koadrantean jarraituz...\n");
        do
        {
             printf(" Eman C puntuaren x koordenatua: ");
             scanf("%f", &fCx);
             printf(" Eman C puntuaren y koordenatua: ");
             scanf("%f", &fCy);

        } while (_________________);
        ...
        printf("\n Bi zuzenen arteko ebakidura puntua P(%.3f, %.3f)", fPx, fPy);
    }
    else   // AB segmentua bertikala EZ denean: AB horizontala da, edo AB zeiharra da
    {
        if (fAy == fBy)  // 2. ATALA: AB segmentua horizontala denean
        {
 
            printf("\n");
            printf("\n AB segmentua horizontala da");
            printf("\n ---------------------------\n");

            fMalda = 0.0;
            fDesplazamendua = fAy;
            printf("\n Zuzenaren malda = %.3f", fMalda);
            printf("\n Zuzenaren desplazamendu bertikala = %.3f", fDesplazamendua);
            printf("\n Zuzenaren ekuazioa  r | y=%.3f", fDesplazamendua);

            // C puntua ere lehen koadrantekoa izango da eta horrez gain
            // C puntua ez da egongo bertikala den AB segmentuaren zuzenean
            printf("\n");
            printf("\n OXY lehen koadrantean jarraituz...\n");
            do
            {
                 printf(" Eman C puntuaren x koordenatua: ");
                 scanf("%f", &fCx);
                 printf(" Eman C puntuaren y koordenatua: ");
                 scanf("%f", &fCy);

            } while (_________________);
            ...
            printf("\n Bi zuzenen arteko ebakidura puntua P(%.3f, %.3f)", fPx, fPy);
        }
        else  // 3. ATALA: AB segmentua zeiharra denean, ez bertikala ez horizontala
        {
            printf("\n");
            printf("\n AB segmentua zehiarra da");
            printf("\n ------------------------\n");
            // C puntua ere lehen koadrantekoa izango da eta horrez gain
            // C puntua ez da egongo AB segmentuari dagokion r zuzenean
            printf("\n");
            printf("\n OXY lehen koadrantean jarraituz...\n");
            do
            {
                printf(" Eman C puntuaren x koordenatua: ");
                scanf("%f", &fCx);
                printf(" Eman C puntuaren y koordenatua: ");
                scanf("%f", &fCy);

            } while (_________________);
            ...
            printf("\n Bi zuzenen arteko ebakidura puntua P(%.3f, %.3f)", fPx, fPy);
        }
    }
    // AB segmentuaren luzera oinarria da eta CP segmentuaren luzera altuera da
    ...
    printf("\n Triangeluaren azalera = %.3f m^2\nºn", fOinarria*fAltuera/2);
    getchar();
    getchar();
    return 0;
}


Hauxe izan daiteke programaren balizko exekuzio bat, AB segmentua bertikala denean:

Hau izan daiteke programaren balizko exekuzio bat, AB segmentua horizontala denenan:

Eta hauxe izan daiteke programaren balizko beste exekuzio bat, AB segmentua zeiharra denenan:


AB eta CP bi segmentuen luzera ezagutzean, triangeluaren azalera berehala lor daiteke. Ariketa osatuago honen programa exekutagarria Triangelu_5.exe hartu eta hura exekutatuz programaren logika zein den ulertu.




      |||||||||||||||||||| LASTER IKUSGAI ||||||||||||||||||||  

     

    Ariketa 16 | Triangeluaren azalera

    ZER DAKIDAN:
    printf() eta scanf() funtzioak menperatzen ditut. Programan bideak aukeratzeko if agindua ikasi dut ere.



    ZER IKASIKO DUDAN:
    Aurrera jo baino lehen, if baldintzako kontrol-agindu erabiliko dut programa handiago batean. Planteamendua gogoratu Ariketa 15 | Triangeluaren azalera (hasiera) artikuluan eta programa aztertu Ariketa 16 | Triangeluaren azalera artikulu honetan.


    Programa bat inkrementalki garatzen

    XOY lehen koadranteko triangelu bat bere ABC erpinen bitartez definiturik dator (erpinen koordenatuak zenbaki errealak dira). ABC triangeluaren azalera kalkula dezagun jakinik A, B eta C sarrerako datuek ondoko baldintzak betetzen dituztela:
    • A, B  eta C puntuak lehen koadrantean kokaturik daude
    • A eta B puntuak ez direla bat
    • AB segmentua zeiharra dela, horregatik:
      • AB segmentua ez da bertikala eta...
      • ...AB segmentua ez da horizontala.
    • C puntua ez dagoela kokaturik AB segmentuaren zuzenean
    A, B eta C puntuen koordenatu kartesiarrak teklatuz irakurri ondoren triangeluaren azalera kalkulatzeko 4 urratsetan egingo dugu:
    1. Emanik A puntua eta B puntua, AB zuzena lortu
    2. Emanik C puntua, AB zuzenari dagokion lerro perpendikularra C puntuan lortu
    3. AB zuzena eta bere perpendikularra C puntuan ditugula, lerro biren ebakidura kalkulatu (P puntua lortu)
    4. Erpinen arteko AB distantzia eta puntuen arteko CP distantzia kalkulatu ondoren azalera zehaztu   
    Hauxe izan daiteke azken programaren balizko exekuzio bat:

    Ariketa honek 4 urrats dituenez, goian enuntziatu diren 4 urratsak, zatika eta inkrementalki egin dezagun urrats bakoitzeko programa bana garatuz:
    1. Ariketa-16a_Triangelua|main.c programaren bitartez AB zuzena lor daiteke
    2. Ariketa-16b_Triangelua|main.c programaren bitartez AB zuzenekoa ez den C puntua irakur daiteke
    3. Ariketa-16c_Triangelua|main.c programaren bitartez P puntuaren koordenatuak kalkula daitezke
    4. Ariketa-16d_Triangelua|main.c programaren bitartez AB distantzia eta CP distantzia lor daitezke eta ondorioz triangeluaren azalera zehaz daiteke


    Lehen programa honek A puntua eta B puntua (lau zenbaki erreal) teklatuz irakurtzen ditu eta lerro zuzenaren ekuazioa zehazten du, hots, AB lerroaren m malda eta bere desplazamendu bertikala n.
    Lehen programa hau ebazteko bi algoritmo daude behintzat. Bat, goiko irudian adierazten dena, non zuzenaren P(x,y) edozein hirugarren puntu hartuz bi triangelu angeluzuzeni esker malda eta desplazamendua kalkulatzen diren. Bigarren algoritmoarekin bat egiten duen irudia behean erakusten da, non y = m·x + n ekuazioan m eta n inkognitak diren.




    Bigarren programa hau aurrekoaren jarraipena da. Bigarren programa honek C puntua (bi zenbaki erreal) teklatuz irakurtzen du AB lerroan ez dagoela zainduz. Gero, C puntutik igarotzen den AB lerroaren perpendikularra kalkulatzen du.



    Hirugarren programa hau aurreko bien jarraipena da. AB lerroa dugula eta bere perpendikularra C puntutik dugula, lerro biak elkartzen dituen P puntua kalkulatzen du programa honek. P puntuaren koordenatuak kalkulatzeko Cramer-en metodoa erabil daiteke 13. Ariketa | Ekuazio-sistema ariketan egiten den bezala, ondoko irudia ikusi:



    Laugarren programa hau aurrekoen jarraipena da. Laugarren programa honek ABC triangeluaren azalera kalkulatzen du, horretarako AB distantzia eta CP distantzia zehaztuko ditu. Bi segmentuen luzera ezagutzean, triangeluaren azalera berehala lor daiteke.






    • Ariketa-16a_Triangelua | main.c   lehen iturburu-programa honek AB segmentuari dagokion zuzena erakusten du
    • Ariketa-16b_Triangelua | main.c   bigarren programa hau aurrekoarren jarraipena da eta AB zuzenari dagokion perpendikularra C puntuan erakusten du
    • Ariketa-16c_Triangelua | main.c   hirugarren programa hau aurrekoen jarraipena da eta zuzen biren P ebakidura puntua kalkulatu eta erakusten du
    • Ariketa-16d_Triangelua | main.c   laugarren programa hau aurrekoen jarraipena da ere, AB segmetuaren luzera eta CP segmentuaren luzera kalkulatuz triangeluaren azalera lortu eta erakusten du




    16. Ariketa | Triangeluaren azalera honen hedapena garatzen da 17. Ariketa | Edozein triangeluren azalera izenburuko artikuluan. XOY lehen koadranteko triangeluekin jarraituz, A puntua eta B puntua lotzen dituen AB lerroa edozein izan daiteke: bertikala, horizontala edo zeiharra. Sarrerako datuek bete behar dituzten baldintzak hauexek dira:
    • A, B eta C puntuak lehen koadrantean kokaturik daudela
    • A eta B puntuak ez direla bat
    • C puntua ez dagoela kokaturik AB segmentuari dagokion zuzenean
     

    Ariketa 15 | Triangeluaren azalera (hasiera)

    ZER DAKIDAN:
    printf() eta scanf() funtzioak menperatzen ditut. Programan bideak aukeratzeko if agindua ikasi dut ere.



    ZER IKASIKO DUDAN:
    Aurrera jo baino lehen, if baldintzako kontrol-agindu erabiliko dut programa handiago batean. Planteamendua ikusi Ariketa 15 | Triangeluaren azalera (hasiera) artikulu honetan eta programa aztertu Ariketa 16 | Triangeluaren azalera artikuluan.


    XOY lehen koadranteko triangelu bat bere ABC erpinen bitartez definiturik dator (erpinen koordenatuak zenbaki errealak dira). A puntua eta B puntua lotzen dituen AB lerroa ez da bertikala ezta horizontala, eta C puntua ez dago kokaturik AB lerroan. Datuak:
    • A eta B puntuak AB zuzena lortzeko, AB zuzena zeiharra izango da (ez bertikala, ez horizontala)
    • C puntua AB segmentuaren zuzenetik kanpo dago

    Algoritmoa:
    1. Emanik A puntua eta B puntua, AB zuzena lortu
    2. Emanik C puntua, AB zuzenaren perpendikularra C puntuan lortu
    3. AB zuzena eta bere perpendikularra C puntuan ditugula, lerro biren ebakidura kalkulatu (P puntua lortu)
    4. Erpinen arteko AB distantzia eta puntuen arteko CP distantzia kalkulatu ondoren azalera zehaztu
    Ariketaren urratsak ikusteko Ariketa 16 | Triangeluaren azalera artikulua aztertu.

    Goian erakutsi den algoritmoaren 1. urratsa erakusten da programa hasiera honetan. Emanik A puntua eta B puntua, AB zuzena lortu:

    /* Ariketa-15_Triangelua: A eta B puntuak emanik, dagokien zuzenaren ekuazioa y=mx+n lortu.  */
    
    // A eta B bi puntu desberdin eman (jakinik ez direla bertikal berean egongo
    // ezta horizontal berean) eta dagozkien zuzenaren ekuazioa y = mx + n lortu.
    
    #include <stdio.h>
    
    int main()
    {
        float fAx, fAy, fBx, fBy;
        // float fMalda, fDesplazamendua;
    
        printf("\n");
        // A puntua lehen koadrantekoa da
        do
        {
            printf("\n A puntua:");
            printf("\n OXY lehen koadrantean lan eginez...\n");
            printf(" Eman A puntuaren x koordenatua: ");
            scanf("%f", &fAx);
            printf(" Eman A puntuaren y koordenatua: ");
            scanf("%f", &fAy);
            if (fAx < 0.0 || fAy < 0.0)   // A-ren bi koordenatuak positiboak izan behar dira
            {
                printf(" A puntuaren bi koordenatuak positiboak izan behar dira\n");
                if (fAx < 0.0)
                    printf(" A puntuaren x koordenatua ezin daiteke negatiboa izan\n");
                if (fAy < 0.0)
                    printf(" A puntuaren y koordenatua ezin daiteke negatiboa izan\n");
            }
        } while (fAx < 0.0 || fAy < 0.0);
    
        printf("\n");
        // B puntua ere lehen koadrantekoa izango da eta horrez gain
        // B puntua eta A puntua "diagonal" batean egongo dira kokaturik
        do
        {
            printf("\n B puntua:");
            printf("\n OXY lehen koadrantean jarraituz...\n");
            printf(" Eman B puntuaren x koordenatua: ");
            scanf("%f", &fBx);
            printf(" Eman B puntuaren y koordenatua: ");
            scanf("%f", &fBy);
    
            if (fBx < 0.0 || fBy < 0.0)     // B-ren bi koordenatuak positiboak izan behar dira
                printf(" B puntuaren bi koordenatuak positiboak izan behar dira\n");
            if (fAx == fBx && fAy == fBy)   // A eta B bat dira?
                printf(" A eta B ezin dira bat izan\n");
            else if (fAx == fBx)
                    printf(" AB segmentua ezin daiteke bertikala izan\n");
            else if (fAy == fBy)
                    printf(" AB segmentua ezin daiteke horizontala izan\n");
        } while (fBx < 0.0 || fBy < 0.0 || fAx == fBx || fAy == fBy);
    
        printf("\n\n");
    
        // A eta B ezagunak direla, AB segmentuari dagokion r zuzenaren bi
        // parametroak kalkulatu:
        //                          fMalda := _______________;
        //                          fDesplazamendua := ___________;
    
        // ALGORITMO OSOA:
        //    1.  Emanik A puntua eta B puntua, AB zuzena lortu
        //    2.  Emanik C puntua, lortu AB zuzenaren perpendikularra C puntuan
        //    3.  AB zuzena eta bere perpendikularra C puntuan ditugula, lerro
        //        biren ebakidura kalkulatu (P puntua lortu)
        //    4.  Erpinen arteko AB distantzia eta puntuen arteko CP distantzia
        //        kalkulatu ondoren azalera zehaztu
    
        printf(" fMalda eta fDesplazamendua kalkulatu...\n");
    
        printf("\n");
        return 0;
    }


    • Ariketa-15_Triangelua.cbp | main.c