C++ Funktion - Werte übergeben

yxy

Lieutenant
Registriert
Juli 2014
Beiträge
552
Hallo,
ich bin gerade dabei mir selbst C++ beizubringen.

Jetzt komme ich gerade aber an die Grenzen meines Wissens :D.

Funktionen bestehen ja aus Rückgabetyp, Funktionsname und Parameterliste.

In der Parameterliste stehen ja alle Werte/ Variablen,... die der Funktion übergeben werden.
Aber wie geht das nochmal genau?
Kann ich einer Funktion auch eine ganze Funktion übergeben?

Wenn jetzt z.B. die Funktion A die Werte Leben, Gesundheit und Stärke beinnhaltet.
Wenn ich nun die Stärke der Funktion B übergeben will, was muss ich dann machen?
Muss dazu die Funktion A die Stärke "returnen" (also ausgeben)?

Für ein paar klärende Worte wäre ich sehr dankbar ;).
 
Kommt drauf an wie du es machen willst...

Code:
int MethodA(void){
int stärke, leben, baum;

MethodB(stärke);
}

int MethodB(int x){
//stuff happens
return y
}

ginge genauso wie

Code:
int MethodA(void){
int stärke, leben, baum;

return stärke;
}

IrgendwoImCode{
MethodB(MethodA());
}
Wobei zweiteres unsinn ist, denn dafür bieten Klassen die getter an, die du bei bedarf wie hier implementiert hast :D
Der Code ist jetzt natürlich nicht C++ konform wie du siehst, aber das Prinzip verstehst du hoffentlich :p

Im Prinzip kommt es eben drauf an wo du Methode B einsetzt und warum deine Klasse keinen getter für Stärke hat =)

Code:
int getStaerke(void){
return staerke;
}

void setStaerke(int x){
staerke = x;
}

void MethodB(int addition){
int staerkeCalc;
staerkeCalc = getStaerke() + addition;
setStaerke(staerkeCalc )
​}
(Wäre zb eine kleine verwendung von getter und setter)


(Ich bin ebenfalls selbstlern c++ Anfänger :) - habe allerdings ein wenig Grundlagenerfahrung in Java was doch recht nützlich ist)
 
Zuletzt bearbeitet:
yxy schrieb:
Kann ich einer Funktion auch eine ganze Funktion übergeben?

Das nennt sich "Higher Order Procedure" und C++ kann das meines Wissens nicht richtig, weil es keine Closures gibt. Aber bin nun auch nicht der Experte.
 
Code:
#include <iostream>
using namespace std;

//Funktionsprototypen

int Spielfeldzeigen();
int Feldbesetzen();
char Felddatenanzeigen();
int Spielfeldlöschen();
int AutomatischeFeldbesetzen();

//Konstanten (Feldausmaß)

const int Breite = 3;		//Breite des Feldes
const int Hoehe = 3;	//Höhe des Feldes


//Hauptprogramm

int main()
{
	//Variablen
	int Auswahl;

	//Menü Innhalt
	
	do
	{
		
		//Menü ausgeben

		cout << "Spielfeld erstellen" << endl;
		cout << "-------------------" << endl;
		cout << "1 - Spielfeld anzeigen" << endl;
		cout << "2 - Feld besetzen" << endl;
		cout << "3 - Felddaten anzeigen" << endl;
		cout << "4 - Spielfeld loeschen" << endl;
		cout << "5 - Programm beenden" << endl;

		//Eingabe abfragen
		cout << "Auswahl: " << endl;
		cin >> Auswahl;

		//Je nach Eingabe verzweigen
		switch (Auswahl)
		{

			//Spielfeld anzeigen?
			case (1) :
			{
				Spielfeldzeigen();
			} break;

			//Feld besetzen
			case (2) :
			{
				Feldbesetzen();
			} break;
	
			//Felddaten anzeigen
			case (3) :
			{
				char Felddatenanzeigen(int Feldbesetzen());
			} break;

			//Spielfeld loechen
			case (4) :
			{
				cout << "löschen" << endl;
			} break;

			//Programmm beenden
			case (5) :
			{

			} break;

			//Falsche Eingabe
			default:
			{
			cout << "Falsche Eingabe" << endl;
			}

		}

	} while (Auswahl != 5);  //Spiel beenden


	return 0;

} //main



//Felder besetzen

int Feldbesetzen()
{
	//Strukuren

	struct S_Spieler
	{
		char Name[30];
	};

	//Variablen

	S_Spieler Spielerplatz[Breite][Hoehe];
	int x;
	int y;

	//Position abfragen
	cout << "gewuenschte Position: " << endl;
	cout << "X: ";
	cin >> x;
	cout << "Y: ";
	cin >> y;

	//Name abfragen

	cout << "Name eingeben: " << endl;
	cin >> Spielerplatz[x - 1][y - 1].Name;

	cout << "Ihr Name ist: " << Spielerplatz[x - 1][y - 1].Name <<"\n" << endl;


		return 0;

} //Feldbesetzern


//Felddaten anzeigen

char Felddatenanzeigen(int Feldbesetzen())
{
	//Position abfragen
	cout << "gewuenschte Position: " << endl;
	cout << "X: ";
	cin >> x;
	cout << "Y: ";
	cin >> y;

	cout << "Der Name ist: " << Spielerplatz[x - 1][y - 1].Name << "\n" << endl;

	return 0;

} //Feldaten anzeigen

Ich will den in "Feld besetzen" gesetzten Namen durch "Felddaten anzeigen" aufrufen. Alos muss der Name, der in "Feld besetzen" festgelegt wurde, der Funktion "Felddaten anzeigen" übergeben werden.
(Das Programm geht noch weiter, ist nur ein Ausschnitt)

Was muss ich also ändern? Ich hoffe ihr könnt damit was anfangen xD.
 
Zuletzt bearbeitet:
Zuerst mal vorweg: Es ist immer gut den eigenen Code (bzw. eine vereinfachte/bereinigte Version dessen) mitzuposten. Wenn es noch keinen gibt dann deine Idee in Pseudocode. So ist es schwer und langwierig konkret zu Antworten.

Und ja, du kannst einer Funktion eine Funktion übergeben. Früher hat man das mit Funktionspointern gemacht. Heute würde man sich als neu lernender wohl direkt das Lambda-Kalkül zu Nutze machen.

Das brauchst du aber noch gar nicht, weil du anscheinend noch nicht objektorientiert denkst.

Du möchtest vermutlich eine Klasse programmieren, die die Werte Leben, Gesundheit und Stärke beinhaltet und verwaltet sowie Funktionen programmieren, die auf diesen Werten arbeiten. Dafür ist es interessant den Unterschied zwischen Member- und Non-Member-Funktionen zu kennen.

Das nennt sich "Higher Order Procedure" und C++ kann das meines Wissens nicht richtig, weil es keine Closures gibt. Aber bin nun auch nicht der Experte.

Falsch: C++ kann hier sehr genau Unterscheiden, wie oben beschrieben Lambda-Funktionen oder abstrakter: Functoren.

Nach dem Codeschnipsel folgende Ratschläge:
Behalt das oben und schreib es neu.
Beginne mit einer Class die als private (Keyword private) Variablen deine Attribute enthält. Schreibe in die public-Sektion dieser Class get- und set- Methoden für deine Attribute. Schreibe dann entweder als Member- oder Non-Member-Funktionen (was das impliziert findest du später, viel später heraus, ist hier auch erstmal egal, hauptsache du machst zunächst mal eins) die gewünschten Funktionen die auf den Attributen arbeiten. Und bitte benutz google. Wenn du nicht weiter weißt erstmal da suchen und dann mit nem Codeschnipsel, wenn auch nicht lauffähig, hier nachfragen.
 
Zuletzt bearbeitet:
Kann ich einer Funktion auch eine ganze Funktion übergeben?
Japp per Pointer, Suchbegriff hier wären zum Beispiel Funktionen die CallBack-Funktionen übergeben bekommen (was ziemlicher Standard bei z.B. asynchronen Windows APIs sind wie Sound abspielen etc.)

Deine Kapselung ist äußerst ungeschickt
char Felddatenanzeigen(int Feldbesetzen())
Damit musst Du ja IMMER ein Feld setzen um eins anzuzeigen, das sieht mir eher nach Ablaufsteuerung
aus, das gehört in die Game-Loop aber nicht in die Funktion Felddatenanzeigen.

Lass Dir doch von Felddatensetzen einfach das Feld oder die Feldnummer zurückgeben, die gesetzt wurde statt return 0;
Dann kann Du mit dem Rückgabewert dein Felddatenanzeigen aufrufen.
 
Zuletzt bearbeitet:
Japp per Pointer, Suchbegriff hier wären zum Beispiel Funktionen die CallBack-Funktionen übergeben bekommen (was ziemlicher Standard bei z.B. asynchronen Windows APIs sind wie Sound abspielen etc.)

Hier bitte gleich mit Lambda-Funktionen bzw. echten Funktoren arbeiten. Funktionspointer sind zwar grundsätzlich nicht falsch aber nicht mehr das aktuellste Sprachmittel. Wenn man neu lernt dann gleich mit den aktuellen Freatures. Lambda-Funktionen haben noch deutlich mehr Vorteile als nur ein Ersatz für Funktionspointer zu sein. Auch das wirst du dann später nach und nach heraus finden. Hier sollte es reichen sie benutzen zu lernen.
 
sdwaroc schrieb:
Falsch: C++ kann hier sehr genau Unterscheiden, wie oben beschrieben Lambda-Funktionen oder abstrakter: Functoren.
Ich dachte mir gleich, dass es dumm ist, soetwas zu posten, wenn ich eigentlich nicht weiß, was ich sage. Habe natürlich massiv daneben gelegen. :/

Ich kann mir dennoch nicht verkneifen, zu meckern, dass du OP mangelndes "Objektorientiertes Denken" ankreidest, aber deine eigene Terminologie üble Klassenscheuklappen aufhat.
Ein Lambda-Ausdruck ist ein Werkzeug zur Erzeugung einer Closure (eines Funktionsobjektes) und du triffst keinerlei Unterscheidung zwischen Lambda und Closure.
Nicht nur Klasseninstanzen sind Objekte. Und das Konzept der Closures (und des Lambdakalküls) sind viel älter als Klassen.
 
Zuletzt bearbeitet: (diesunddas)
Zwei kleine Anmerkungen die mMn wichtig sind:
- schreibe quellcode nur in Englisch. Das ist wichtig für Projekte mit mehreren Personen. Außerdem ist die IT community größtenteils englischsprachig, wenn du also hier keine Hilfe findest musst du nicht deinen Code übersetzen.
- Das hier stimmt so nicht:
Funktionen bestehen ja aus Rückgabetyp, Funktionsname und Parameterliste.
Was du beschreibst ist die Funktionssignatur. die Funktion hat zusätzlich noch ihren body (Körper) der beschreibt was sie tut.
 
Zurück
Oben