[C++] Array einer Struktur als Zeiger einer Funktion Übergeben - Problem

Dentho

Grünschnabel
Also ich habe das nun so geändert:

Code:
		case (1):
			{
				cout << "----------" << endl;
				personal_pruefen(&mnr);
				daten_eingabe(Mitarbeiter_ID, &mnr);
				system ("cls");
			} break;

		case (2):
			{
				cout << "----------" << endl;
				personal_pruefen(&mnr);
				daten_anzeigen(Mitarbeiter_ID, &mnr);
				system ("cls");
			} break;

Er ruft also bevor ich die Daten eingeben oder Anzeigen kann die Funktion zur Prüfung der Nummer auf.
und dann:

Code:
void daten_eingabe(S_Mitarbeiter Mitarbeiter_ID[mza], int *mnr){
	
		cout << "--------------" << endl;
		cout << "Bitte geben sie die Daten fuer Mitarbeiter Nr." << *mnr << " ein:" << endl;
		cout << "Name: ";
		cin.ignore();
		cin.get (Mitarbeiter_ID[*mnr-1].chName, 29);
		cout << "Bruttoeinkommen: ";
		cin >> Mitarbeiter_ID[*mnr-1].fBruttoeinkommen;
		cout << "Sozialabgaben: ";
		cin >> Mitarbeiter_ID[*mnr-1].fSozialabgaben;
		cout << "--------------" << endl;
		cout << "Vielen Dank fuer ihre Eingabe." << endl;
	
	_getch();
}
-
Code:
void daten_anzeigen(const S_Mitarbeiter Mitarbeiter_ID[mza], int *mnr){
	
		cout << "--------------" << endl;
		cout << "Mitarbeiter: " << *mnr << endl;
		cout << "Name: " << Mitarbeiter_ID[*mnr-1].chName << endl;
		cout << "Bruttoeinkommen: " << Mitarbeiter_ID[*mnr-1].fBruttoeinkommen << " Euro" << endl;
		cout << "Sozialabgaben: " << Mitarbeiter_ID[*mnr-1].fSozialabgaben << " Euro" << endl;

	_getch();
}

ruft er je nach auswahl eine der Funktionen auf und liest die daten ein bzw zeigt sie an. Und zwar nur für die jweilige mitarebiter nummer deren adresse ich mit einem zeiger mit übergeben habe. Richtig so? :)
 

deepthroat

Erfahrenes Mitglied
ruft er je nach auswahl eine der Funktionen auf und liest die daten ein bzw zeigt sie an. Und zwar nur für die jweilige mitarebiter nummer deren adresse ich mit einem zeiger mit übergeben habe. Richtig so? :)
Nicht ganz. Du übergibst immer noch das gesamte Mitarbeiter Array. Wozu?
C++:
void daten_anzeigen(const S_Mitarbeiter& m);

daten_anzeigen(Mitarbeiter_ID[mnr]);
Auf diese Weise ist auch noch die Datenhaltung von dieser Funktion separiert - d.h. man kann auch das Array durch eine andere Datenstruktur ersetzen ohne die Funktionen ändern zu müssen, die nur auf einem einzelnen Mitarbeiter agieren.

Gruß
 

Dentho

Grünschnabel
Ah, verstanden :) nun klappt es.
Vielen dank aber eine letze Frage hätte ich noch.
Du sagtest ja das man die einzelnen Aufgaben alle separieren sollte.
Auf welche Art sollte ich diese If-Bedingung dann schreiben?

Code:
case (2):
			{
				cout << "----------" << endl;
				personal_pruefen(&mnr);
				if (Mitarbeiter_ID[mnr-1].bDaten_vorhanden == false)
				{
					cout << "--------------" << endl;
					cout << "Es sind keine Daten fuer Mitarbeiternummer. "
					<< Mitarbeiter_ID[mnr-1].ident << " vorhanden." << endl;
					_getch();
				}
				else
				{
				daten_anzeigen(Mitarbeiter_ID[mnr-1]);
				}
				system ("cls");
			} break;

oder in die Funktion daten_anzeigen
oder dafür eine Extra Funktion schreiben?
Mein Gedanke dabei wäre halt das ich, wenn ich die Funktion eh nicht aufrufe da keine Daten vorhanden sind , ich nicht extra das Array für eine Fehlermeldung übergeben müsste da das ja unnötig Speicher kosten würde, auf der anderen Seite, wenn ich das so sehe könnte ich ja auch die gesamte Funktion in den case 2 schreiben.....? :/
 

deepthroat

Erfahrenes Mitglied
Du sagtest ja das man die einzelnen Aufgaben alle separieren sollte.
Auf welche Art sollte ich diese If-Bedingung dann schreiben?

Code:
case (2):
			{
				cout << "----------" << endl;
				personal_pruefen(&mnr);
				if (Mitarbeiter_ID[mnr-1].bDaten_vorhanden == false)
				{
					cout << "--------------" << endl;
					cout << "Es sind keine Daten fuer Mitarbeiternummer. "
					<< Mitarbeiter_ID[mnr-1].ident << " vorhanden." << endl;
					_getch();
				}
				else
				{
				daten_anzeigen(Mitarbeiter_ID[mnr-1]);
				}
				system ("cls");
			} break;

oder in die Funktion daten_anzeigen
Nein, eher nicht. Es gibt ein Konzept das nennt sich Programming-by-Contract. Wie bereits gesagt sollte die daten_anzeigen Funktion für einen einzelnen Mitarbeiter funktionieren. D.h. aber auch, das der Mitarbeiter, der als Parameter übergeben wurde, existieren muss, also an sich valide sein muss. Das stellt die sog. Vorbedingung und den Vertrag der Funktion dar: rufe mich mit einem existierenden, korrekt initialisiertem Mitarbeiter auf (Vorbedingung), und ich zeige die Daten dieses Mitarbeiters entsprechend an. Ist die Vorbedingung nicht erfüllt, kann die Funktion ihre Aufgabe nicht erfüllen.

Das Problem liegt aber eigentlich auch noch woanders. Und zwar hast du (gezwungenermaßen) dieses leidliche bDaten_vorhanden Attribut zu jedem Mitarbeiter hinzugefügt. Das ist sehr unschön und es vermischt schon wieder die Datenhaltung im Array mit den eigentlichen Daten eines Mitarbeiters. Das hat beides miteinander nichts zu tun.

Eigentlich sollte man an dieser Stelle eine geeignete Datenstruktur zur Verwaltung der Mitarbeiter verwenden. Ein statisches Array ist relativ schlecht geeignet.

Aber um es nicht gleich alles umzustellen und nicht allzu kompliziert zu machen, würde ich dir empfehlen ein zweites Array anzulegen, in dem du an Position i vermerkst ob der Mitarbeiter mit dem Index i bereits initialisiert wurde. Diese beiden Arrays könntest du dann wiederum in einer Struktur zusammenfassen.

oder dafür eine Extra Funktion schreiben?
Ich denke ich würde dafür die personal_pruefen Funktion erweitern. (wobei der Name der Funktion evlt. auch nicht so gut ist. Was prüft diese Funktion denn? Besser wäre evlt. frage_nach_mitarbeiter_nr o.ä.)

Dann solltest du gleich die Möglichkeit vorsehen, das man evlt. keine Mitarbeiternr. eingeben möchte so dass die Funktion einen boolschen Wert zurückgibt wenn das Einlesen einer validen Mitarbeiter-Nr. erfolgreich war oder nicht.
C++:
if (frage_nach_mitarbeiter_nr(&mnr)) {
  daten_anzeigen(Mitarbeiter[mnr]);
}
Gruß