• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zwracanie wartości funkcji (błąd) c++

VPS Starter Arubacloud
0 głosów
1,826 wizyt
pytanie zadane 19 lutego 2018 w C i C++ przez Sic Dyskutant (8,510 p.)

Piszę program, w którym występują funkcje. Problem polega na tym, że źle dobrałem typy (są to wskaźniki na funkcje). Jestem świadomy popełnionych błędów, jednak nie wiem jak mógłbym je rozwiązać, oto pierwszy błąd:

double * add(double x, double y)
{
        return x + y;
}

drugi:

double *calculate(double p, double m, double * (*add)(double, double))
{       
        double *(*pf)(double, double) = * add(p, m);    

        return pf;
}

Proszę o podpowiedź

komentarz 19 lutego 2018 przez Hiskiel Pasjonat (22,830 p.)
Co oznacza "double * (*add) (double, double)"? Jak to działa?

6 odpowiedzi

+2 głosów
odpowiedź 19 lutego 2018 przez sp00ky Obywatel (1,760 p.)
edycja 23 lutego 2019 przez sp00ky

Chcesz stworzyć funkcję calculate(), która pobierze dwie wartości typu double i wskaźnik funkcji mającej dwa argumenty double, zwracającej wartość double? Jeśli tak to funkcja calculate() też ma być typu double i ma zwracać wartość, którą wyliczy wskazana funkcja po przekazaniu jej obu argumentów.

Jeśli chcesz stworzyć tablicę wskaźników funkcji podobnych do add(),

double add(double x, double y)
{
     return x + y;
}

i w pętli stosować calculate() z tymi funkcjami, to deklaracja takiej tablicy powinna wyglądać następująco:

double(*pf)(double, double);

Przykład:

#include <iostream>

using namespace std;

const int NUMBER_FUNCTIONS = 4; // ustalam liczbę (wskaźników) funkcji dla funkcji calculate()

double add(double, double);         // prototyp funkcji która obliczy sumę
double ratio(double, double);       // prototyp funkcji która obliczy iloczyn
double difference(double, double);  // prototyp funkcji która obliczy różnicę
double quatient(double, double);    // prototyp funkcji która obliczy iloraz

// prototyp funkcji która wywołuje odpowiednie funkcje do obliczeń
double calculate(double, double, double(*calledFunctions)(double, double));

int main() {

    // tablica z 4 wskaźnikami funkcji
    double(*calledFunctions[NUMBER_FUNCTIONS])(double, double) { add, ratio, difference, quatient };

    // stała tablica z nazwami obliczeń
    const char *NAME_CALCULATION[NUMBER_FUNCTIONS] { "Suma", "Iloczyn", "Roznica", "Iloraz" };
    double a = 0, b = 0;    // zmienne do obliczeń
    cout << "Podaj dwie liczby (K koniec): ";

    while (cin >> a >> b) {
        for (int i = 0; i < NUMBER_FUNCTIONS; i++) {
            cout << NAME_CALCULATION[i] << ": " << calculate(a, b, (*calledFunctions[i])) << endl;
        }
        cout << "\nPodaj klolejne dwie liczby (K koniec): ";
    }

    system("pause");
    return 0;
}

// funkcje która liczy sumę
double add(double x, double y) {
    return x + y;
}

// funkcje która liczy iloczyn
double ratio(double x, double y) {
    return x * y;
}

// funkcje która liczy różnicę
double difference(double x, double y) {
    return x - y;
}

// funkcje która liczy iloraz
double quatient(double x, double y) {
    return x / y;
}

// funkcje która zwraca wynik innej funkcji
double calculate(double x, double y, double(*calledFunctions)(double, double)) {
    return (*calledFunctions)(x, y);
}

 

+1 głos
odpowiedź 19 lutego 2018 przez mokrowski Mędrzec (155,460 p.)
double add(double x, double y)
{
        return x + y;
}
double calculate(double p, double m, double (*add)(double, double))
{       
        return add(p, m);    
}

O ile dobrze zrozumiałem intencję.. 

 

komentarz 20 lutego 2018 przez Sic Dyskutant (8,510 p.)
Dobrze zrobiłeś, ale jednak nie o to.
+1 głos
odpowiedź 19 lutego 2018 przez Radfler VIP (101,030 p.)
przywrócone 27 marca 2018 przez Radfler

W pierwszym przypadku powinieneś zwracać obiekt typu double, a nie wskaźnik:

double add(double x, double y){ return x+y; } // typ wyrażenia (x+y) to double

W drugim przypadku trzecim argumentem powinien być wskaźnik na funkcję zwracającą typu double, czyli

double (*add)(double, double)

Wynikiem wywołania jest typu double, więc zmienna pf (3 linijka) powinna też być typu double:

double pf = add(p, m); // przed add nie ma operatora *, gdyż funkcja nie zwraca wskaźnika

I sama funkcja powinna też zwracać zmienną typu double:

double calculate(/*...*/)

 

+1 głos
odpowiedź 19 lutego 2018 przez Arkadiusz Sikorski Pasjonat (20,160 p.)

pf to po prostu wartość zwrócona przez wywołaną funkcję add, więc musi być być typu zwracanego przez tę funkcję (czyli double*). Zamiast:

double *(*pf)(double, double) = * add(p, m); 

wystarczy:

double * pf =  add(p, m); 

Wywołujemy funkcję add i przypisujemy zwróconą wartość do tej zmiennej pf.

Chociaż nie jestem pewien, czy na pewno chcesz używać w tym przypadku typu double*, może chodziło Ci o zwykłego double'a? W takim razie spróbuj:

double add(double x, double y){return x + y;}
double calculate(double p, double m, double (*add)(double, double))
{       
    double pf =  add(p, m);    
    return pf;
}

 

komentarz 20 lutego 2018 przez Sic Dyskutant (8,510 p.)
edycja 20 lutego 2018 przez Sic
Jeżeli w ogóle to możliwe to:

Właśnie chodzi o ten wskaźnik, program który już został wielokrotnie tu napisany zrobiłem i nie miałem z nim problem, chodzi tutaj o stworzenie wskaźnika funkcji w tym przypadku add() oraz funkcji calculate (double, double , i właśnie funkcja, która jest wskaźnikiem)

Problem polega na zwracaniu obydwu funkcji tak, aby działała tak jak ta na górze, która napisałeś (biorąc pod uwagę również adresy tych funkcji).
0 głosów
odpowiedź 22 lutego 2018 przez Sic Dyskutant (8,510 p.)

Błędy, które się pojawiają:

start_10-b.cpp: In function ‘double* add(double, double)’:
start_10-b.cpp:24:13: error: cannot convert ‘double’ to ‘double*’ in return
  return x + y;
             ^
start_10-b.cpp: In function ‘double* calculate(double, double, double* (*)(double, double))’:
start_10-b.cpp:29:45: error: cannot convert ‘double*’ to ‘double* (*)(double, double)’ in initialization
  double *(*pf)(double, double) = (*add)(p, m);
                                             ^
start_10-b.cpp:31:14: error: cannot convert ‘double* (*)(double, double)’to ‘double*’ in return
  return  (*pf);

 

komentarz 22 lutego 2018 przez Patipati0 Nowicjusz (100 p.)
Też miałam podobną sytuację, cieżko było to naprawić.
0 głosów
odpowiedź 22 lutego 2018 przez Sic Dyskutant (8,510 p.)

Ominąłem kilka zasad, jednak program działa poprawnie:

#include <iostream>
// wzorowac sie na 7.19
void * add(double x, double y);
void * calculate(double p, double m, void * (*add)(double, double));

int main()
{
        double l, k;
        for(int i=0; i < 3; i++)
        {
                std::cout << "Podaj wartosc 1: ";
                std::cin >> l;
                std::cout << "Podaj wartosc 2: ";
                std::cin >> k;

                calculate(l, k, *add);
        }
        return 0;
}

void * add(double x, double y) { std::cout << "Wartosc: " <<  x + y << std::endl; }

void * calculate(double p, double m, void * (*add)(double, double)){ std::cout << "Adres: " << (*add)(p, m) << std::endl; }

 

komentarz 23 lutego 2018 przez Qwerty96 Stary wyjadacz (13,580 p.)

Ten program ma niezdefiniowane zachowanie. Deklarujesz w funkcjach, że zwracają void*, a w kodzie nigdzie tego nie robią (brak return).

Parę osób już napisało jak to powinno wyglądać. Jak chcesz wyświetlić adres funkcji, to w ten sposób:

double (*ptr)(double, double) = &add;
std::cout << reinterpret_cast<void*>(ptr);

 

Podobne pytania

0 głosów
3 odpowiedzi 543 wizyt
pytanie zadane 12 stycznia 2020 w C i C++ przez dominik195k Obywatel (1,030 p.)
0 głosów
1 odpowiedź 516 wizyt
0 głosów
1 odpowiedź 742 wizyt
pytanie zadane 28 maja 2018 w C i C++ przez periedynek Obywatel (1,320 p.)

92,451 zapytań

141,261 odpowiedzi

319,073 komentarzy

61,853 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...