Zadanie z wypisywaniem danych

0

Mam taki problem z zadaniem, że chce zwrócić w funkcji bestClient wskażnik do pary osób która ma największe oszczędności. Jedna z nich musi być w banku podanym w argumencie, a oszczędności mogą być nawet na minusie, chodzi o to że mają najmniejszy dług, w tym przypadku byłaby to para Kenny i Suzy. Czy mógłby ktoś napisać jak prawidłowo przekazać wskażnik z wynikiem oraz czy istnieje jakiś lepszy sposób na warunek na określenie największych oszczędności.

#include <iostream>

using namespace std;

enum Banks { PKO, BGZ, BRE, BPH };

struct Account { Banks bank; int balance; };

struct Person { char name[20]; Account account; };

struct Couple { Person he; Person she; };

const Couple* bestClient(const Couple* cpls, int size, Banks bank) {

	int biggestcash = -2147483648;

	Couple richestcouple;

	for (int i = 0; i < size; i++) {
		if (cpls->he.account.bank == bank || cpls->she.account.bank == bank) {
			if (cpls->he.account.balance + cpls->she.account.balance > biggestcash) {
				richestcouple = cpls[i];
			}
		}
		else { return nullptr; }
	}

	return *richestcouple;
}

	int main() {
	
		Couple cpls[4] = {
			cpls[0] = { "Johny", PKO, 1200, "Mary", BGZ, 1400 },
			cpls[1] = { "Peter", BGZ, 1400, "Suzy", BRE, -1500 },
			cpls[2] = { "Kevin", PKO, 1600, "Suzy", BPH, 1500 },
			cpls[3] = { "Kenny", BPH, 200, "Suzy", BRE, -201 }
		};

		const Couple * p = bestClient(cpls, 4, BRE);

		if (p) 
			cout << p->he.name << " and " << p->she.name
			<< ": " << p->he.account.balance +
			p->she.account.balance << endl;
		else 
			cout << "No such couple...\n";
		}
0

To ci się nie skompiluje. W funkcji bestClient zwracasz **wskaźnik ** a nie obiekt, poprawisz na return &richestcouple i zwracasz wskaźnik do zmiennej lokalnej, czyli mamy UB. I tak dalej i tak dalej... Jak widać próba poprawy jednej rzeczy kończy się jeszcze większymi kłopotami.
Stąd lepiej zostaw te wskaźniki w spokoju i użyj kontenera vector i klasyCouples, która dostarcza metodę bestClient.

class Couples
{

public:

    Couple bestClient( Banks bank ) const
    {
        vector<Couple> data_filtred;
        copy_if( data.begin(), data.end(), back_inserter(data_filtred), [&]( const Couple& couple ) { return couple.he.account.bank == bank || couple.she.account.bank == bank; } );
        return *max_element( data_filtred.cbegin() , data_filtred.cend() ,
                    []( Couple const& lhs, Couple const& rhs )
                     {
                        return (lhs.he.account.balance+lhs.she.account.balance)<(rhs.he.account.balance+rhs.she.account.balance);
                     }
                    );

    }

    void addCouple( Couple couple )
    {
       data.emplace_back( move(couple) );
    }

private:
    vector<Couple> data;
};
0

Możliwe że twoim sposobem byłoby prościej, ale niestety nie mogę zmienić tej linijki:

const Couple* bestClient(const Couple* cpls, int size, Banks bank) 

Wkleję tutaj część polecenia traktującą o tej funkcji by można było dokładnie zobaczyć o co chodzi:

Zdefniować funkcję o nagłówku
const Couple* bestClient(const Couple* cpls, int size, Banks bank);
która zwraca wskażnik do tej pary (Couple) z tablicy przekazanej jako pierwszy argument (o wymiarze size), która ma największą sumę oszczędności jego (he) i jej (she), ale tylko spośród takich par, w których przynajmniej jedno z małżonków ma konto w banku bank. Jeśli żadna z osób nie ma konta w banku bank, to funkcja zwraca nullptr. Nie wolno zakładać, że stan konta jest nieujemny; może być dowolnie duży dodatni i dowolnie duży ujemny. Jeśli dwie lub więcej par spośród tych, które spełniają narzucony warunek ma takie same, największe, oszczędności, to funkcja zwraca wskażnik do dowolnej z nich.

1

Jeżeli narzucona jest z góry sygnatura funkcji, to popatrz na następujący przykład.

const Couple* bestClient( const Couple* cpls , int size , Banks bank )
{
    if( cpls == nullptr || size<=0 ) return nullptr;

    const Couple* richestcouple {nullptr};
    int max {numeric_limits<int>::min()};

    for( int i {0} ; i<size ; ++i )
    {
        if( cpls[i].he.account.bank == bank || cpls[i].she.account.bank == bank )
        {
            if( cpls[i].he.account.balance + cpls[i].she.account.balance > max )
            {
                richestcouple = cpls+i;
                max = cpls[i].he.account.balance + cpls[i].she.account.balance;
            }
        }
    }

    return richestcouple;
}

Musisz uważać na to co zwracasz. Typ musi być zgodny z tym co jest w sygnaturze funkcji. Generalnie jak operuje się na gołych wskaźnikach, to trzeba mieć oczy dookoła głowy, bo popełnić błąd jest bardzo łatwo. Natomiast skutki mogą przez dłuższy czas być niewidoczne, do momentu kiedy coś zaczyna działać nie tak jak trzeba, najczęściej w miejscu zupełnie innym niż powstały błąd.

0

Wielkie dzięki za pomoc, widzę teraz miejsca w których się pomyliłem. Ale mam jeszcza trzy pytania. Czemu trzeba używać const w 5 linijce gdzie deklaruje się najbogatszą parę(rozumiem że w deklaracji funkcji jest to tak zrobione żeby przypadkiem czegoś nie pozmieniać, ale tutaj najbogatsza para może się przecież zmieniać nie jest to stała) i dodałeś tam potem { nullptr } właściwie po co on jest skoro wcześniej był if który mówił o warunku przerwania, oraz w zadaniu mimo że się już kompiluje wyrzuca uwagę "Typ wyliczeniowy „Banks” nie ma zakresu. Preferowany jest element „enum class” zamiast „enum” (enum.3)", nie powoduje to przerwania programu, ale nie wiem o co w tym chodzi lub jak to poprawić.

1

Czemu trzeba używać const w 5 linijce

Nie można przypisywać wskaźników do **stałych **obiektów do wskaźników, które mogą je zmieniać. Linijka 14 wymusza użycie słowa const.
Wskaźnik zawsze powinien być inicjalizowany w momencie jego utworzenia. W tym przypadku ustawiam go na nullptr, tak aby w przypadku kiedy żadna z osób nie ma konta w banku bank, zwracana była poprawna wartość wymagana przez zadanie.

Możesz/powinieneś zmienić typ wyliczeniowy enum na enum class, który jest bardziej bezpieczny - nie mogą zostać przeprowadzone jego niejawne konwersje. Poczytaj

1 użytkowników online, w tym zalogowanych: 0, gości: 1