Fizikus C++ labor

1. hét: make és C ismétlés2. hét: pontosság és pontatlanság3. hét: azonos nevű függvények, referencia
4. hét: egyszerű osztályok5. hét: konstruktor és operator overloading6. hét: osztály dinamikus adattaggal
9. hét: >> és << használata I/O-ra, statikus tagok10. hét / 1: STL vector10. hét / 2: STL string, algorithm
11. hét: generikus algoritmusok és osztályok12. hét: öröklés13. hét: heterogén kollekció
14. hét: C++11 kitekintő15. hét: Nagyházi bemutatás

3. hét: azonos nevű függvények, referencia

0.

Egy rövid írás a referenciáról itt. A benne szereplő példák a megértést igyekeznek segíteni, több esetben nem ez a követendő példa. Ha hibát találtok, vagy valami nem érthető, jelezzétek e-maiben!

1. feladat

a) Definiálj két Abs nevű függvényt, az egyik int, a másik double értéket kapjon, mindkettő a kapott érték abszolút értékét adja vissza!

b) Definiálj vektor struktúrát 3D valós koordináták tárolására! Írj Abs függvényt, amely egy ilyen struktúrát kap paraméterként, és visszaadja a vektor hosszát!

Írj a függvényekbe kiírást, hogy futtatáskor látszódjon, melyik fut éppen. Írj main függvényt, ahol teszteled az eljárásokat!

2. feladat

Írj függvényt, amely az 1/b)-ben definiált vektort kap paraméterként, és nullázza azt! A függvény neve legyen setToZero. Kétféle megoldást készíts:

a) A vektort pointerrel vedd át!

b) A vektort referenciával vedd át!

Próbáld ki a függvényeket!

3. feladat

Írj függvényt, amely paraméterként kap egy valós számokat tartalmazó tömböt, és egy éppen megfelelő méretű dinamikus tömbbe másolja a kapott tömbből a negatív értékeket, majd visszaadja az új tömböt. A függvény referenncia típusú paraméterben adja vissza az új tömb elemszámát!

Írj main függvényt, amely egy, a felhasználó által megadott méretű dinamikus tömböt véletlen értékekkel tölt fel (0.5-rand()/(double)RAND_MAX), és meghívja a fenti függvényt, majd felszabadít minden lefoglalt dinamikus memóriát.

A feladatban a new/delete operátorokat használd!

Gyakorló feladatok

Gy1.

Írj függvényt, amely polár koordinátarendszerben kap egy 2D vektort, és descartes koordintarendszerben adja vissza! Használj referenciát, ahol érdemes!

Gy2.

Írj függvényt, amely egy double elemeket tartalamzó tömböt kap paraméterként, és visszaadja a benne lévő elemek számtani, mértani és harmonikus közepét referencia paraméterben!

Gy3.

Alakítsuk át az órai tömbből negatív számokat leválogató függvényt, hogy ne pointerrel, hanem referenciával adja vissza paraméterlistán az új tömböt:: double* & ujt, int &ujn Módosítsuk ennek megfelelően a hívást is!

Gy4.

Legyen egy enum mod{pol,des} típusunk, mely a polár, ill. descartes-i tárolási módot jelöli. Készítsünk 2D-s vektor típust double a, b és mod m mezőkkel. Készítsünk konvertáló függvényt, mely egy vektort polárból descartes-i koordinátarendszerbe, illetve fordított irányba is tud konvertálni. Az eredményt referencia paraméterben adjuk vissza.

Gy5.

Írj függvényt Concat néven, amely két sztringet kap paraméterként, és a sztringeket összefűzi egy újonnan létrehozott, éppen megfelelő méretű dinamikus tömbben! A függvény ezt a sztinget adja vissza! Egészítsd ki teljes programmá, melyben kipróbálod a Concat függvény működését, és gondoskodsz arról, hogy ne legyen memóriaszivárgás! A feladatban a dinamikus memóriát a megfelelő new/delete operátorokkal kezeld!

Gy6. (érdeklődőbbeknek)

Írj függvényeket Concat néven, amelyek egy sztringet és

a) egy karaktert

a) egy egész számot

b) egy valós számot

c) egy 3D vektort

kapnak paraméterként, és a kapott sztring végéhez fűzik a kapott másik értéket. Az eredmény egy új sztring, amely egy éppen megfelelő méretű dinamikus tömbbe kerüljön. Ezt adja vsssza a függvény! Írj main függvényt is, amelyben kipróbálod a függvények működését, és gondoskodsz a dinamikus memória megfelelő kezeléséről!

 

tipp: használhatsz kellően nagy ideiglenes tömböt, ahová a sztringgé alakított szám/vektor kerül. Számot vagy vektort sztringgé alakítani legegyszerűbb az sprintf függvénnyel, amely ugyanúgy működik, mint a printf, csak az eredmény egy sztringbe kerül. (Eszedbe juthat, hogy egyből a végeredményt hozd létre a "kellően nagy" ideiglenes tömbben, de ettől óva intelek, mert az első paraméterkét átvett sztring bármekkora lehet. A számnak/vektornak viszont meg lehet becsülni a méretét. Ha nem %f-et használsz, hanem %g-t vagy %e-t, akkor biztonságosan becsülhető egy "kellően nagy" tömbméret.)

Órai feladatok mintamegoldása

1. feladat
int Abs(int a){
    return a >= 0 ? a : -a;
}

double Abs(double a){
    return a >= 0 ? a : -a;
}

struct Vektor{
    double x, y, z;
};

double Abs(const Vektor &v){
// A paraméter lehetne simán Vektor v is
    return sqrt(v.x*v.x + v.y*v.y + v.z*v.z);
}

 

2. feladat
void setToZero(Vektor *p){
    p->x = p->y = p->z = 0;
}

void setToZero(Vektor &v){
    v.x = v.y = v.z = 0;
}

int main(){
    Vektor a, b;
    setToZero(&a);
    setToZero(b);
}

 

3. feladat
#include <iostream>
#include <time.h>

double * negativok(const double * be, int n, int & ki_elemszam) {
    int i, j;
    ki_elemszam = 0;
    for (i = 0;i < n;i++)
        if (be[i] < 0)
            ki_elemszam++;
    double *ki = new double[ki_elemszam];
    for (i = j = 0;i < n;i++)
        if (be[i] < 0)
            ki[j++] = be[i];
    return ki;
}

int main() {
    double szamok[20];
    srand(time(NULL));
    for (int i = 0;i < 20;i++)
        szamok[i] = 0.5 - (double)rand() / RAND_MAX;
    int neg_n;
    double *uj = negativok(szamok, 20, neg_n);
    for (int i = 0;i < neg_n;i++)
        std::cout << i << ": " << uj[i] << std::endl;
    delete[] uj;
    return 0;
}
Megoldás pointer referenciával:
#include <iostream>
#include <time.h>

void negativok(const double * be, int n, int & ki_elemszam, double *& ki) {
    int i, j;
    ki_elemszam = 0;
    for (i = 0;i < n;i++)
        if (be[i] < 0)
            ki_elemszam++;
    ki = new double[ki_elemszam];
    for (i = j = 0;i < n;i++)
        if (be[i] < 0)
            ki[j++] = be[i];
}

int main() {
    double szamok[20];
    srand(time(NULL));
    for (int i = 0;i < 20;i++)
        szamok[i] = 0.5 - (double)rand() / RAND_MAX;
    int neg_n;
    double *uj;
    negativok(szamok, 20, neg_n, uj);
    for (int i = 0;i < neg_n;i++)
        std::cout << i << ": " << uj[i] << std::endl;
    delete[] uj;
    return 0;
}

 

Gy1. feladat
void polar2desc(double r, double fi, double &x, double &y){
    x = r*cos(fi);
    y = r*sin(fi);
}

 

Gy5. feladat
#include <string.h>
#include <stdio.h>

char *Concat(const char *str1, const char *str2){
    char *eredmeny = new char[strlen(str1) + strlen(str2) + 1];
    strcpy(eredmeny, str1);
    strcat(eredmeny, str2);
    return eredmeny;
}

int main(){
    char *s1 = "Elso ";
    char *s2 = "masodik";
    char *s3 = Concat(s1, s2);
    printf("%s\n", s3);
    delete[]s3;
    return 0;
}