Függvények - Paraméterátadás

Érték szerinti paraméterátadás

Mit ír ki a következő program?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
using namespace std;

int f(int x)
{
    cout << "f-1: " << x << endl; // 9
    x++;
    cout << "f-2: " << x << endl; // 10
    return x;
}

int main()
{
    int x = 9;

    cout << "main-1: " << x << endl; // 9

    int a = f(x);

    cout << "main-2: " << x << endl; // 9
    cout << "main-3a: " << a << endl; // 10


    return 0;
}

A paraméterátadás alapból érték szerinti (pass by value). Ezért a függvényben történő változtatás nincs hatással a main-beli x-re (mert a függvényben csak egy másolat van az eredeti értékből).

Referencia-alapú (cím szerinti) paraméterátadás

Ezt használjuk, ha mégis szeretnénk, hogy a függvény változtatásai a kinti változókra is hatással legyenek. Például:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;

void csere(int &x, int &y)
{
    int temp = x;
    x = y;
    y = temp;
}

int main()
{
    int a = 10, b = 20;

    cout << "a = " << a << ", b = " << b << endl;

    csere(a,b);

    cout << "a = " << a << ", b = " << b << endl;


    return 0;
}

Nem az értékek másolódnak le, hanem egy-egy hivatkozás van a függvényben a kinti változókra, tehát tudjuk azokat változtatni.

Feladat:

Írjunk egy függvényt, ami kap két számot és visszaadja paramétereken keresztül a lnko-jukat és az átlagukat!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
using namespace std;

void f(int a, int b, int &lnko, double &atlag)
{
    int d = 1;

    for (int i = 2; i <= a && i <= b; i++)
        if (a%i == 0 && b%i == 0)
            d = i;

    lnko = d;
    atlag = (a+b) / 2.0;
}

int main()
{
    int a = 10, b = 13;

    int lnko;
    double atlag;

    f(a,b,lnko,atlag);

    cout << lnko << endl;
    cout << atlag << endl;
    return 0;
}

HF:

1. Írjunk függvényt, ami kap két, a és b paramétert, és megváltoztatja őket (felcseréli), ha kell, úgy, hogy a hívás után a ≤ b igaz legyen.

2. Írjunk függvényt, ami kap egy n természetes számot és két másik paraméteren keresztül visszaküldi az n első és utolsó számjegyét.

3. Írjunk függvényt, ami adott a, b, c valós számokra (ahol a ≠ 0) visszatéríti az ax2 + bx + c = 0 egyenlet valós megoldásainak számát, illetve, ha ez pontosan 1 vagy 2, akkor további referenciaparamétereken keresztül visszatéríti a gyököket (a nem használt referenciákat pedig nullára állítja).

1
2
3
4
int masodfoku(double a, double b, double c, double &x1, double &x2)
{
    //...
}

Megoldások

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <iostream>
#include <cmath>
using namespace std;

void csere_ha_kell(int &a, int &b)
{
    if (a > b) {
        int temp = a;
        a = b;
        b = temp;
    }
}

void szamjegyek(int n, int &elso, int &utolso)
{
    utolso = n % 10;

    while (n >= 10)
        n = n/10;

    elso = n;
}

int masodfoku(
    double a, double b, double c,
    double &x1, double &x2)
{
    double delta = b*b - 4*a*c;

    if (delta < 0) {
        x1 = x2 = 0;
        return 0;
    }
    else if (delta == 0) {
        x1 = -b / (2*a);
        x2 = 0;
        return 1;
    }
    else {
        x1 = (-b - sqrt(delta)) / (2*a);
        x2 = (-b + sqrt(delta)) / (2*a);
        return 2;
    }
}


int main()
{
    double a, b, c;
    cin >> a >> b >> c;

    double x1, x2;
    int hany = masodfoku(a,b,c,x1,x2);

    cout << hany << " db megoldas";
    if (hany >= 1)
        cout << ": " << x1 << " ";
    if (hany == 2)
        cout << x2;
    cout << endl;

    return 0;
}

Tömbök / mátrixok átadása paraméterként

Példa:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;


void f(int tomb[])
{
    tomb[0]++;
}

int main()
{
    int a[3] = {10,20,30};

    f(a);
    cout << a[0] << endl; // 11

    int b[10] = {1,2,3,4,5};
    f(b);
    cout << b[0];

    return 0;
}

Mátrixok átadása

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

void f(int tomb[][3])
{
    tomb[0][0]++;
}


int main()
{
    int a[3][3] = {};

    f(a);

    cout << a[0][0] << endl;

    return 0;
}

Feladatok (HF)

  1. Függvény, ami kiír egy tömböt (már írtunk ilyet)
  2. Függvény, ami beolvas egy tömböt.
  3. Függvény, ami egy tömb minden elemét megduplázza.
  4. https://www.pbinfo.ro/probleme/4238/nrzero

Megoldások

1., 2., 3.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
using namespace std;

void ird_ki(int n, int t[])
{
    for (int i = 0; i < n; i++)
        cout << t[i] << " ";
    cout << endl;
}

int beolvas1(int t[])
{
    int n;
    cin >> n;

    for (int i = 0; i < n; i++)
        cin >> t[i];

    return n;
}

void beolvas2(int t[], int &n)
{
    cin >> n;

    for (int i = 0; i < n; i++)
        cin >> t[i];
}

void duplaz(int n, int t[])
{
    for (int i = 0; i < n; i++)
        t[i] *= 2;
}

int main()
{
    /*
    int a[100];
    int n = beolvas1(a);
    ird_ki(n, a);
    */
    
    int a[100];
    int n;
    beolvas2(a, n);
    duplaz(n, a);
    ird_ki(n, a);

    return 0;
}

4. (egyszerű vs. hatékony változat)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
using namespace std;

int bin_keres_elso_nulla(int n, int a[])
{
    int bal = 1, jobb = n;

    while (bal < jobb) {
        int kozep = (bal + jobb) / 2;

        if (a[kozep]%2 == 1)
            bal = kozep+1;
        else
            jobb = kozep;
    }

    // itt: bal == jobb
    if (a[bal] == 0)
        return bal;
    else
        return -1;
}


int bin_keres_utolso_nulla(int n, int a[])
{
    int bal = 1, jobb = n;

    while (bal < jobb) {
        int kozep = (bal + jobb + 1) / 2;

        if (a[kozep]%2 == 0 && a[kozep] > 0)
            jobb = kozep-1;
        else
            bal = kozep;
    }

    // itt: bal == jobb
    if (a[bal] == 0)
        return bal;
    else
        return -1;
}

int NrZero_naiv(int a[], int n)
{
    int db = 0;

    for (int i = 1; i <= n; i++)
        if (a[i] == 0)
            db++;

    return db;
}

// smecher...
int NrZero(int a[], int n)
{
    int poz1 = bin_keres_elso_nulla(n, a);
    if (poz1 == -1)
        return 0;

    int poz2 = bin_keres_utolso_nulla(n, a);
    return poz2 - poz1+1;
}


int main()
{
    int n = 6;
    int a[100] = { -200, 1, 1, 1, 1, 0, 0 };

    cout << NrZero(a, n) << endl;

    return 0;
}