#include<iostream>
using namespace std;

typedef int Datentyp;
// weist den Compiler an, unter "Datentyp" den Datentyp int zu verstehen
// allgemeiner Aufbau des typedef:
// typedef <bekannteTypdefinition> <neuerBezeichnerDafuer>;

// wünschenswert wäre hier eine Funktionssignatur der Art
// void addToSet(const Datentyp value, Mengentyp & set)

// Einschub: Definition zusammengesetzter Datentypen:
// Allgemeiner Aufbau:
// struct <BezeichnerFürZusammengesetztenDatentyp>
// {
// <DefinitionenDerBestandteile>
// };

struct Mengentyp
{
	Datentyp content[100];
	int nrOfValues;
};
// Dieses ist nur die Definition des Datentyps Mengentyp
// Deklaration von Variablen des Typs Mengentyp wie bei allen anderen Variablen auch:
// <Typname> <Variablenname>

// Zugriff auf content und nrOfValues:
// siehe Funktionen weiter unten

//void addToSet(const Datentyp value, Datentyp set[], int & nrOfValues) // fügt den Wert value zu der Menge set hinzu
void addToSet(const Datentyp value, Mengentyp & set)
// es wird davon ausgegangen, dass value noch nicht in set vorhanden ist
// ein vor den Datentyp gestelltes const weist den Compiler an, die Variable nicht zu verändern
// ein zwischen dem Datentyp und dem Variablennamen eingefügtes & weist den Compiler an,
// dass die übergebene Variable und der Parameter miteinander verändert werden
// (solche Parameter nennt man Referenzparameter)
// genaugenommen: der Compiler verwendet dieselbe Speicherstelle
// ohne Angabe von const oder & erhalten wir eine lokale Variable, die mit dem Wert
// des übergebenen Parameters initialisiert wird
// Ausnahme: bei Arrays: const Array darf nicht verändert werden, ohne const: Array
// verändert auch den Wert des übergebenen Parameters
{
	set.content[set.nrOfValues]=value;
	set.nrOfValues++; // erhöht den Wert der Variablen nrOfValues um 1
	// Problematik, dass das set nur 100 Werte umfassen darf, wird hier zunächst ausgeblendet
}

//bool isInSet(const Datentyp value, const Datentyp set[], const int nrOfValues) // testet, ob Wert value in der Menge set ist
bool isInSet(const Datentyp value, const Mengentyp set) // testet, ob Wert value in der Menge set ist
{
	int index = 0;
	for ( ; index < set.nrOfValues; index = index+1)
	{
		if (value == set.content[index])
		{
			return true;
		}
	}
	return false;
}

//void printSet(const Datentyp set[], const int nrOfValues) // gibt die Werte der Menge set aus
void printSet(const Mengentyp set) // gibt die Werte der Menge set aus
// Parameter, auf die nur lesend zugegriffen werden sollen, werden mit
// dem Schlüsselwort const gekennzeichnet
// (ist aus Sicht des Compilers nicht notwendig, aber erhöht die Lesbarkeit
// und etwaige Tippfehler als syntaktische Fehler erkannt werden können)
{
	if (set.nrOfValues == 0)
	{
		cout << "Die Menge ist leer" << endl;
	}
	else
	{
		cout << "Die Menge umfasst die Werte " << set.content[0];
		int index;
		for (index=1; index < set.nrOfValues; index = index+1)
		{
			cout << ", " << set.content[index];
		}
		cout << endl;
	}
}

int main(void)
{
	Datentyp value; // einzulesener Wert
	Mengentyp set; // Menge mit maximal 100 Zahlen
	set.nrOfValues = 0; // zu Beginn 0 Werte in der Menge set

	//set[0] = 42;
	//set[1] = 21;
	//nrOfValues = 2;

	//if (isInSet(421,set,nrOfValues))
	//{
	//	cout << "421 ist drin" << endl;
	//}
	//else
	//{
	//	cout << "421 ist nicht drin" << endl;
	//}

	cout << "Gib einen ersten Wert ein (Abbruch mit 0): ";
	cin >> value;

	while (value != 0) // hier "könnte" ein Compiler sich beschweren, wenn Datentyp von value nicht int ist 
	{
		if (!(isInSet(value, set)))
		{
			addToSet(value, set);
			printSet(set);
		}
		else
		{
			cout << value << " ist bereits in der Menge vorhanden" << endl;
		}

		cout << "Gib naechsten Wert ein (Abbruch mit 0): ";
		cin >> value;
	}

	return 0;
}