» »

Funkcije in prenos po referenci

Funkcije in prenos po referenci

black ice ::

V C++ se ubadam z reševanjem ulomkov s pomočjo funkcij. Napisal sem funkcijo, ki poišče največji skupni delitelj dveh števil (v našem primeru števca in imenovalca danega ulomka) in vrne NSD; potem imam še funkcije za okrajšanje ulomka, za seštevanje, odštevanje, deljenje in množenje dveh ulomkov.

Problem, ki se pojavlja: kako vrniti več vrednosti z eno funkcijo? Preden sem začel tukaj spraševati sem malo pobrskal in ugotovil, da je dokaj enostavna rešitev prenos po referenci (no, kakor za koga).

Za primer recimo funkcija, ki sešteje dva ulomka:
int sestejUlomka(int &stevec1, int stevec2, int &imenovalec1, int imenovalec2)
{
    stevec1+=stevec2;   
    imenovalec1*=imenovalec2;
}

Ulomek je setavljen iz dveh delov, števca in imenovalca. Kako lahko vrnem vsak del posebej, da bom lahko funkciji, ki okrajša ulomek kot vhodne vrednosti podal izhodne vrednosti funkcije sestejUlomka()?

Edit: Popravil kodo.
  • spremenilo: black ice ()

Vesoljc ::

na tak nacin tezko...
pomoje je bolje narest prav class, ter spisati osnovne operatorje

kaj takega recimo:
http://www.cplusplus.com/forum/beginner...

da potem lahko v miru naredis:
Ulomek a(3,8);
Ulomek b(2,13);
Ulomek c(17,3);

Ulomek d = a + b / c;
Abnormal behavior of abnormal brain makes me normal...

Arto ::

A ni enostavnejša rešitev preprosto array?

dice7 ::

Da ti funkcija vrača več vrednosti lahko recimo uporabiš kazalce (pointerje)

using namespace std;
int sestejUlomka(int stevec1, int stevec2, int imenovalec1, int imenovalec2, int *stevec3, int *imenovalec3)
{
	*stevec3 = stevec2 + stevec1;
	*imenovalec3 = imenovalec2 * imenovalec1;
	return 0;
}

int main()
{
	int
		st1 = 1,
		st2 = 3,
		im1 = 3,
		im2 = 5,
		st3, im3;
	cout << "Vsota ulomkov " << st1 << "/" << im1 << " in " << st2 << "/" << im2 << " je:" << endl;
	sestejUlomka(st1, st2, im1, im2, &st3, &im3);
	cout << st3 << "/" << im3 << endl;
	return 0;
}

Vsota ulomkov 1/3 in 3/5 je:
4/15



Sam ti priporočam, da narediš class, ti bo mnogo lažje

Zgodovina sprememb…

  • spremenil: dice7 ()

black ice ::

Classi so že objektno programiranje, ne? Moram prej obvladati strukturirano :)

Mislil sem, da bo spodnja koda delala, vendar mi vrača vrednosti v šestnajstiški obliki.
Ima kdo kakšen namig kaj ni v redu?
#include <iostream>
using namespace std;

int sestejUlomka(int stevec1,int imenovalec1,int stevec2,int imenovalec2,int *stevec3,int *imenovalec3)
{
    *stevec3 = (stevec1*imenovalec2)+(stevec2*imenovalec1);
    *imenovalec3 = imenovalec1*imenovalec2;
    return 0;
}

int odstejUlomka(int stevec1, int imenovalec1,int stevec2, int imenovalec2, int *stevec3, int *imenovalec3)
{
     *stevec3 = (stevec1*imenovalec2)-(stevec2*imenovalec1);
     *imenovalec3 = imenovalec1*imenovalec2;
     return 0;
}

int zmnoziUlomka(int stevec1, int imenovalec1, int stevec2, int imenovalec2, int *stevec3, int *imenovalec3)
{    
     *stevec3 = stevec1*stevec2;
     *imenovalec3 = imenovalec1*imenovalec2;
     return 0;
}

int deliUlomka(int stevec1, int imenovalec1, int stevec2, int imenovalec2, int *stevec3, int *imenovalec3)
{
     *stevec3 = stevec1*imenovalec2;
     *imenovalec3 =imenovalec1*stevec2;
     return 0;
}

int okrajsajUlomek(int a, int b, int delitelj, int *stevec3, int *imenovalec3)
{
  *stevec3 = a/delitelj;
  *imenovalec3 = b/delitelj; 
  return 0;
}

int najvecjiSkupniDelitelj (int a, int b)
{
    int delitelj=1;
     
     if (a>b)
     {
             for (int i=b; i>1; i--)
             {
                 if ((a%i==0)&&(b%i==0))
                 {
                    delitelj=i;
                    break;
                 }
                 else delitelj=1;
             }
     return delitelj;
     }
     
     else if (b>a)
     {
             for (int i=a; i>1; i--)
             {
                 if ((a%i==0)&&(b%i==0))
                 {
                    delitelj=i;
                    break;
                 }
                 else 
                 delitelj = 1;            
             }
             return delitelj;
     }
     
     else 
          delitelj=a;
          return delitelj;
}

int main()
{
    int imenovalec1, stevec1, imenovalec2, stevec2, stevec3, imenovalec3, delitelj;
    
    cout << "Vnesi stevca in imenovalca obeh ulomkov " << endl<< "(v zaporedju stevec1 imenovalec1 stevec2 imenovalec2): " << endl << "Pozor! Imenovalca ne smeta biti enaka 0! " << endl;
    cin >> stevec1 >> imenovalec1 >> stevec2 >> imenovalec2;
    
    do
    {    
        delitelj = najvecjiSkupniDelitelj(stevec1,imenovalec1);
        
        cout << "Ulomek: " << stevec1 << "/" << imenovalec1 << endl;
        cout << "Najvecji skupni delitelj stevil " << stevec1 << " in " << imenovalec1 << " je: " << delitelj << endl;
        
        okrajsajUlomek(stevec1,imenovalec1,delitelj,&stevec3,&imenovalec3);
        cout << "Okrajsan ulomek " << stevec1 << "/" << imenovalec1 << " je: " << &stevec3 << "/" << &imenovalec3 << endl;
        
        sestejUlomka(stevec1,imenovalec1,stevec2,imenovalec2,&stevec3,&imenovalec3);
        cout << "Vsota ulomkov " << stevec1 << "/" << imenovalec1 << " + " << stevec2 << "/" << imenovalec2 << " je: " << &stevec3 << "/" << &imenovalec3 << endl;
        
        odstejUlomka(stevec1,imenovalec1,stevec2,imenovalec2,&stevec3,&imenovalec3);
        cout << "Razlika ulomkov " << stevec1 << "/" << imenovalec1 << " - " << stevec2 << "/" << imenovalec2 << " je: " << &stevec3 << "/" << &imenovalec3 << endl;
        
        zmnoziUlomka(stevec1,imenovalec1,stevec2,imenovalec2,&stevec3,&imenovalec3);
        cout << "Produkt ulomkov " << stevec1 << "/" << imenovalec1 << " * " << stevec2 << "/" << imenovalec2 << " je: " << &stevec3 << "/" << &imenovalec3 << endl;
        
        deliUlomka(stevec1,imenovalec1,stevec2,imenovalec2,&stevec3,&imenovalec3);
        cout << "Kvocient ulomkov " << stevec1 << "/" << imenovalec1 << ":" << stevec2 << "/" << imenovalec2 << " je: " << &stevec3 << "/" << &imenovalec3 << endl;
        
    } while ((imenovalec1 || imenovalec2)==0);
    
    system ("PAUSE"); 
    return 0;
}

Zgodovina sprememb…

  • spremenilo: black ice ()

Senitel ::

Jah tale spaka tud ni strukturirano... Pa zakaj izpisujes pointerje na stevec3? Hint. :)

amacar ::

Do 23.10 imaš čas za oddajo naloge :-)

black ice ::

Imam delujoč program že nekaj časa, samo sem želel poenostaviti vse skupaj.
Očitno me čaka še precej branja. :)

technolog ::

@amacar, če je pa tako, ima pa samo še -1 oz 11 mesecev. :)

amacar ::

technolog, narobe si razumel. Rok je do danes ampak zvečer do 23ure in 10minut :-)

xordie ::

In zakaj si se potem odlocil za kazalce, ko si ze enkrat uporabljaj reference?
x

Spura ::

int okrajsajUlomek(int a, int b, int delitelj, int *stevec3, int *imenovalec3) je parameter delitelj cisto odvec, saj lahko ta funkcija sama klice
najvecjiSkupniDeljitelj. Pa v funkciji najvecji skupni delitelj je en sam for loop dovolj.

technolog ::

Referenca in kazalec je ubistvu eno in isto. Referenca je samo navodilo compilerju, da vedno kadar se spremenljivka rabi, zravn da še en dereference operator.

Pri kazalcih imaš malo več kontrole, morš pa tud zmeri pol pisat tisto *.

Zgodovina sprememb…

ERGY ::

Primer zgornje kode z objekti, če bo koga zanimalo.

#include <iostream>
#include <cmath>

class Fraction
{
      public:
             Fraction(): numerator(0), denominator(1) {}
             Fraction(int i): numerator(i), denominator(1) {}
             Fraction(int i, int j): numerator(i), denominator(j) {}
             Fraction(const Fraction& fr)
                            {
                              numerator = fr.numerator;
                              denominator = fr.denominator;
                            }
             Fraction show() const;
             const Fraction& simplify();
      private:
              int numerator;
              int denominator;

};

Fraction Fraction::show() const
{
        Fraction temp(*this);
        std::cout << temp.numerator << "/" << temp.denominator << "\n";
        return temp;
}


const Fraction& Fraction::simplify()
{
     int init = 0;

     if( std::abs(numerator) <= std::abs(denominator) )
        init = std::abs(numerator);
     else
        init = std::abs(denominator);
     //preverimo ostanek pri deljenju
     for(int i = init; i > 1 ; i--)
     {
      if(numerator % i == 0 && denominator % i == 0)
          {
            numerator /= i;
            denominator /= i;
          }
     }

     return *(this);
}

int main()
{
    Fraction A(9,6), B(15,5);
    A.simplify().show();
    B.simplify().show();
    return 0;
}

xordie ::

@technolog: V tem primeru kazalci niso potrebni. V bistvu vnasajo samo doloceno zmedo, ki se je potrdila pri izpisovanju vrednosti.
x


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Naloga iz Putka - UPM

Oddelek: Programiranje
242057 (1393) NejcSSD
»

krajšanje ulomkov

Oddelek: Programiranje
81344 (1276) Karak
»

problem s programiranjem ulomka

Oddelek: Programiranje
191601 (1041) KaRkY
»

[Naloga][Java] Ulomki

Oddelek: Programiranje
62543 (2391) SkIDiver
»

[C++] Ulomek: +, -, *, /

Oddelek: Programiranje
82713 (2608) Vesoljc

Več podobnih tem