Schulaufgabe und ein bisschen Objektorientierte Programmierung



  • Hallo liebe Gemeinde.
    Wir haben die Schulaufgabe nun geschrieben. Dank euch und dem Forum war es zwar kein Kinderspiel, aber ein gutes Unterfangen.
    Gott sei Dank habe ich so viel bzgl. Strings (also Datentyp String in C++) getan.
    Eine der Fragen war wie folgt:
    Nennen Sie zwei Unterschiede zwischen dem Datentyp char und dem Datentyp string.
    Darauf habe ich geschrieben:
     char muss mit einem Zahlenwert deklariert werden, string jedoch nicht.
    Bsp. für char: char Text [1000];
    Bsp. für string: string Satz,
     Eine als string deklarierte Variable ist von Haus aus 32 Byte groß, char jedoch so groß, welchen Zahlenwert man ihm zufügt.
    Eine andere Frage war wie folgt:
    Wie lautet der Befehl, um eine als string deklarierte Variable einzulesen?
    Ich habe darauf geschrieben:
    string Text;
    getline(cin, Text);
    Dann kam folgende Frage:
    Schreiben Sie ein Programm, dass das Alphabet in Kleinbuchstaben ausgibt. Verwenden Sie die Funktion putchar().
    Darauf habe ich geschrieben:

    #include<iostream>
    #include<cstdio>
    
    int main()
    {
    	char c;
    
    	for (c = 'a'; c<='z'; c++) 
    		putchar(c);
    
    	return 0;
    }
    

    Dann kam folgende Frage:
    Schreiben Sie ein Programm, das erst die eine Hälfte eines Wortes einliest, dann die zweite Hälfte eines Wortes und als Ausgabe das zusammengefügte Wort ausgibt. Verwenden Sie den Datentyp string.
    Darauf habe ich geschrieben:

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main()
    {
    	string str_1, str_2, str_3;
    
    	cout << "Geben Sie das erste Wort ein!\n";
    	getline(cin, str_1);
    
    	cout << "Geben Sie das zweite Wort ein!\n";
    	getline(cin, str_2);
    
    	str_3 = str_1 + str_2;
    
    	cout << "Zusammengefuegt heisst das Wort:\n";
    	cout << str_3 << "\n";
    
    	return 0;
    }
    

    Dann kam noch die Frage, welche string Funktionen zu ostream gehören und welche zu istream. Die war auch einfach.
    Als nächstes kamen dann Pointer dran.
    Eine Aufgabe darin bestand darin einen Taschenrechner über Pointer zu programmieren.
    Das habe ich geschrieben:

    #include <iostream>
    #include "Addition.h"
    #include "Subtraktion.h"
    #include "Multiplikation.h"
    #include "Division.h"
    using namespace std;
    
    int main()
    {
    	int number;
    
    	do
    	{
    		float x, y,z;
    		float *px = &x;
    		float *py = &y;
    		float *pz = &z;
    
    		cout << "Welche Rechenoperation wollen Sie durchfuehren?\n";
    		cout << "(1) Addition \n";
    		cout << "(2) Subtraktion \n";
    		cout << "(3) Multiplikation \n ";
    		cout << "(4) Division \n";
    		cout << "(0) Exit! \n";
    		cin  >> number;
    
    		switch(number)
    		{
    			case 1:
    				cout << "Addition!\n";
    				cout << "Geben Sie dazu zwei Zahlen ein!\n";
    				cin  >> *px >> *py;
    
    				*pz = *px + *py;
    
    				cout << *px << " + " << *py << " = " << *pz << "\n";
    
    				break;
    
    			case 2:
    				cout << "Subtraktion!\n";
    				cout << "Geben Sie dazu zwei Zahlen ein!\n";
    				cin  >> *px >> *py;
    
    				*pz = *px - *py;
    
    				cout << *px << " - " << *py << " = " << *pz << "\n";
    
    				break;
    
    			case 3:
    				cout << "Multiplikation!\n";
    				cout << "Geben Sie dazu zwei Zahlen ein!\n";
    				cin  >> *px >> *py;
    
    				*pz = (*px) * (*py);
    
    				cout << *px << " * " << *py << " = " << *pz << "\n";
    
    				break;
    
    			case 4:
    				cout << "Division!\n";
    				cout << "Geben Sie dazu zwei Zahlen ein!\n";
    				cin  >> *px >> *py;
    
    				*pz = (*px) / (*py);
    
    				cout << *px << " / " << *py << " = " << *pz << "\n";
    
    				break;
    
    			case 0:
    				cout << "Exit durch Abbruch!\n";
    				break;
    
    		}
    	}while(number!=0);
    
    	return 0;
    }
    

    Dann hätte man über Pointer die Uhrzeit, das Datum und den Wochentag ausgeben sollen.
    Das habe ich geschrieben:

    #include <iostream>
    #include <ctime>
    #include <ctime>
    #include <cassert>
    using namespace std;
    
    const char* wochentag_name(int index)
    			{
    				assert (0<=index && index<7);
    				static const char* namen[] = {
    					"Sonntag",
    					"Montag",
    					"Dienstag",
    					"Mittwoch",
    					"Donnerstag",
    					"Freitag", 
    					"Samstag"
    				};
    				return namen[index];
    			};
    
    int main()
    {
    	time_t Uhrzeit;
    	tm *pUhrzeit;
    	Uhrzeit = time(0);
    	pUhrzeit = localtime (&Uhrzeit);
    
    	cout << wochentag_name(pUhrzeit->tm_wday) << endl; //Wochentag
    	cout << pUhrzeit -> tm_mday << '.' << pUhrzeit -> tm_mon+1 << '.' << pUhrzeit -> tm_year + 1900 << endl; //Datum
    	cout << pUhrzeit -> tm_hour << ':' << pUhrzeit -> tm_min   << ':' << pUhrzeit -> tm_sec << endl; //Uhrzeit
    	cout << endl;
    
    	return 0;
    }
    

    Wo ich wohl bisschen abgeloost habe, war bei der Erklärung von Zeigerarithmetik
    Aber mei … eine 5 oder 6 wird es nicht mehr … mit einer 4 bin ich schon zufrieden.
    Aber euch an der Stelle mal ein Danke… ohne euch hätte ich es glaube ich nicht so gut hinbekommen.
    So als nächstes ist jetzt Objektorientierung dran.
    Bei meiner Recherche bin ich auf www.wikibooks.org/wiki/C++-Programmierung:_Klassen gestoßen, wo man sich meiner Meinung nach gut in das Thema einlesen kann und vorab einen Kleinen Überblick bekommt. Ich weiß jetzt nicht, ob das Folgende stimmt, da wäre es nett von euch Experten, wenn ihr vielleicht kurz drüber schauen könntet.
    Eine Klasse besteht in C++ auf zwei Quellcodedateien:
    Der Deklaration und der Implentierung.
    Die Deklaration erfolgt üblicherweise in einer Header – Datei. Bei der Deklaration einer Klasse werden ihre Elemente (members, das umfass Daten und Funktionen) festgelegt.
    Die Syntax einer Klassendeklaration erfolgt wie folgt:

    class EineKlasse
    {
    public:					//öffentlich
    	EineKlasse();				//der Default - Konstruktor
    	EineKlasse(int a=0);			//weiterer Konstruktor mit Parameter und Defaultwert
    	EineKlasse(const EineKlasse &a);  //Copy Konstruktor
    	~EineKlasse();			//der Destruktor
    
    	int eineFunktion(int x=42);		//eine Funktion mit einem (Default-) Parameter
    
    private:
    	int m_eineVariable;			//privat
    
    };
    

    Die erste Zeile gibt der Klasse den Namen.
    Im Klassenrumpf werden die Elemente deklariert. Die Reihenfolge der Member – Deklaration ist beliebig; es empfiehlt sich aber, nach einem gewissen System vorzugehen, z. B. mit dem Konstruktor und Destruktor zu beginnen. Abschließend folgt eine schließende geschweifte Klammer und ein Semikolon.
    Implementierung
    Die Implementierung, d. h. der Code für die jeweiligen Memberfunktionen, erfolgt in einer C++ - Datei. Um die Funktion int eineFunktion(int x=42); zu implementieren, schreibt man

    int eineFunktion::eineFunktion(int x = 42)
    {
    	//Anweisungen
    }
    

    Dabei wird vor den Funktionsname eineFunktion noch der Name der Klasse EineKlasse, gefolgt von zwei Doppelpunkten, gestellt. Dies qualifiziert die Funktion, so dass der Compiler weiß, zu welcher Klasse die Funktionsdefinition gehört. Zu beachten ist, dass die Default – Initialisierung des Parameters nicht wiederholt wird.
    Teile einer Klasse
    Eine Klasse setzt sich aus verschiedenen Teilen zusammen:
     Konstruktor
     Destruktor
     Memberfunktion
     Membervariable
    Der Konstruktor
    Konstruktoren werden bei der Erschaffung einer Instanz einer Klasse aufgerufen und dienen dazu, Initialisierungen auszuführen, etwa Membervariablen Standartwerte zuzuweisen.
    Die Funktionsdefinition beginnt mit dem Namen der Klasse und dem Bereichsopterator ::
    Der Konstruktor hat immer denselben Namen wie die Klasse. Er hat keinen Rückgabewert, kann aber einen oder mehrere Parameter besitzen.
    Bsp. 1:

    EineKlasse::EineKlasse()
    	:m_eineVariable
    {
    	//weitere Initialisierungen des Objektes
    }
    

    Bsp. 2:

    EineKlasse::EineKlasse(int a)
    	:m_eineVariable(a)
    {
    	//weitere Initialisierungen
    }
    

    Der Destruktor
    Der Destruktor trägt ebenfalls denselben Namen wie die Klasse, aber mit einer vorgestellten Tilde ~. Er hat keinen Rückgabewert und keinen Prameter. Der Destruktor wird aufgerufen, wenn eine Instanz der Klasse zerstört wird. Das passiert, wenn der Bereich (z. B. ein Funktionsrumpf), in dem die Klasse lokal instanziert wird, endet oder der Operator delete für die Instanz aufgerufen wird.
    Im Destruktor können also abschließende Aktionen unternommen werden, z. B. reservierter Speicherplatz freigegeben werden, oder andere Objekte davon unterrichtet werden, dass es die Instanz ab jetzt nicht mehr gibt. Oft bleibt der Destruktorrumpf aber auch leer.
    Bsp.:

    EineKlasse::~EineKlasse()
    {
    
    }
    

    Memberfunktionen
    Memberfunktionen sind innerhalb einer Klasse deklarierte Funktionen. Die Implementierung geschieht wie auch beim Konstruktor und Destruktor in der Quelldatei EineKlasse.cpp

    Bsp.:

    int EineKlasse::eineFunktion(int a)
    {
    	int ergebnis = m_eineVariable*a;
    	cout << "Ergebnis:" << ergebnis << endl;
    	return ergebnis;
    }
    

    In diesem Beispiel wird der Parameter mit der Membervariable multipliziert und auch als Funktionswert zurückgegeben.
    Membervariablen
    Für Membervariablen gilt wie für Memberfunktionen, dass sie innerhalb der Klasse nur mit ihrem Namen angesprochen werde, von außerhalb mit dem Namen der Instanz qualifiziert werden müssen.
    Zugriffskontrolle
    Ein grundlegendes Konzept in der OPP ist die Datenkapselung, die in C++ mit den Schlüsselwörtern private, protected und public gesteuert wird. Wenn kein Schlüsselwort angegeben wird, ist die definierte Variable bzw. Methode automatisch private. Um ein Element öffentlich zugänglich zu machen, deklariert man es als public.

    Die Unterscheidung, welche Members welchen Zugriffsschutz bekommen, nimmt man in der Deklaration der Klasse vor:

    class EineKlasse
    {
    public:
    	int liesGeheimnis () const;
    protected:
    	void bestimmeGeheimnis(int Wert);
    private:
    	int geheimnis;
    };
    

    public: Auf diese Elemente ist aus jeder Codepassage heraus Zugriff erlaubt.

    protected: Auf Elemente dieser Zugriffsschutz – Stufe besteht Zugriff von Codeteilen, die

    entweder die Klasse implementieren

    oder

    für solche, die Klassen implementieren, die direkt oder indirekt von der Klasse erben

    private: Diese Elemente sind nur aus Codeteilen heraus zugreifbar, die der
    Implementierung dieser Klasse dienen, üblicherweise als Methoden –Implementierung.

    Ich weiß jetzt nicht, ob das genannte alles stimmt?? Ich bin offen für Ratschläge, Tipps und Kritik…
    Ich werde mich nun im Buch „Der C++ Programmierer“ in die OPP einlesen.



  • silent_max schrieb:

    Dank euch und dem Forum war es zwar kein Kinderspiel

    Wurdest du hier so sehr abgelenkt?

    Wegen der ersten Frage... Die Frage ist natürlich schon etwas komisch formuliert und deine Antworten erst recht.
    Wegen dem Rest. Sorry, das ist viel zu viel. Warum sollte sich das jemand durchlesen? Du wirst schon sehen, was dein Lehrer von deinen Antworten hält 😉



  • Ich hab mir auch nicht alles durchgelesen, aber ich finds gut.
    Es ist zwar noch sehr ausbaufähig, aber allein den Fortschritt von max in den 2-3 Monaten jetzt, den finde ich toll.

    Mach weiter so und gib Gas dann hast du in 2 weiteren Monaten deinen Lehrer vom Wissensstand überholt.



  • Ist mir auch zuviel auf alles einzugehen.
    Was mir beim überfliegen nicht passt, ist

    Oft bleibt der Destruktorrumpf aber auch leer.

    Der Rumpf bleibt eigntlich nur leer, wenn der D'tor virtual sein muss und nix zu tun hat, sonst lässt man ihn besser ganz weg.



  • silent_max schrieb:

    Nennen Sie zwei Unterschiede zwischen dem Datentyp char und dem Datentyp string.
    Darauf habe ich geschrieben:
     char muss mit einem Zahlenwert deklariert werden, string jedoch nicht.
    Bsp. für char: char Text [1000];
    Bsp. für string: string Satz,
     Eine als string deklarierte Variable ist von Haus aus 32 Byte groß, char jedoch so groß, welchen Zahlenwert man ihm zufügt.

    silent_max schrieb:

     char muss mit einem Zahlenwert deklariert werden, string jedoch nicht.

    😮

    Wieso MUSS o_O? Nix muss! Aber kann ...

    silent_max schrieb:

     Eine als string deklarierte Variable ist von Haus aus 32 Byte groß, char jedoch so groß, welchen Zahlenwert man ihm zufügt.

    32?
    Also bei mir ist ein string 24 Byte breit und ein char 1 Byte ...

    string e;
    cout<<sizeof(e); // 24 Byte
    
    string e="OLOLOLO";
    cout<<sizeof(e);  // Ebenfalls 24 Byte
    
    char c;
    cout<<sizeof(c); // 1 Byte
    
    char c='A';
    cout<<sizeof(c); // 1 Byte
    
    char *c="lol";  // C-String also kein char  
    cout<<sizeof(c); // 3 Byte
    

    Weiter hab ich nicht gelesen ...



  • Oops verschrieben^^

    So is richtig:

    char *c="lol";  // C-String also kein char  
    cout<<sizeof(c); // 4 Byte
    
    Um jedoch die länge im "C Style" herausfinden benutzt man die Funktion:
    
    strlen(const Char* var);
    


  • silent_max schrieb:

    Schreiben Sie ein Programm, das erst die eine Hälfte eines Wortes einliest, dann die zweite Hälfte eines Wortes und als Ausgabe das zusammengefügte Wort ausgibt. Verwenden Sie den Datentyp string.

    Mmh!?
    was ist falsch an folgender Lösung:

    #include <iostream>
    #include <string>
    
    int main()
    {
        using namespace std;
        string wort;
        cout << "Geben Sie bitte das komplette Wort ein:";
        cin >> wort;
        cout << " ... die erste Haelfte wurde vor der zweite gelesen!" << endl;
        cout << "Die erste Haelfte ist: " << wort.substr(0, wort.length()/2) << endl;
        cout << "Die zweite Haelfte ist: " << wort.substr(wort.length()/2) << endl;
        cout << "das ganze Wort lautet: " << wort << endl;
    }
    

    nichts - oder?



  • silent_max schrieb:

    Nennen Sie zwei Unterschiede zwischen dem Datentyp char und dem Datentyp string.
    Darauf habe ich geschrieben:
     char muss mit einem Zahlenwert deklariert werden, string jedoch nicht.
    Bsp. für char: char Text [1000];
    Bsp. für string: string Satz,
     Eine als string deklarierte Variable ist von Haus aus 32 Byte groß, char jedoch so groß, welchen Zahlenwert man ihm zufügt.

    Thema verfehlt.
    Du solltest char und string vergleichen. Nicht char[] und string.
    Der Rest sieht mir ok aus.



  • Besserwessi schrieb:

    ... Kokolores ...

    Ich wär gern dabei, wie Du das später dem Dozenten zu erklären versuchst ...



  • Volkard schrieb:

    Der Rest sieht mir ok aus.

    silent_max schrieb:

    Eine als string deklarierte Variable ist von Haus aus 32 Byte groß

    😮

    string = 24 Byte



  • Quak schrieb:

    string = 24 Byte

    Quatsch!
    Das ist vom System (OS + Compiler) abhängig.
    Auf meinem 32bit XP benutzt VS 2010 28 Byte, g++ nur 4.



  • volkard schrieb:

    Thema verfehlt.
    Du solltest char und string vergleichen. Nicht char[] und string.
    Der Rest sieht mir ok aus.

    ich bin mir da nicht ganz sicher, was er wirklich vergleichen sollte. Ich könnte mir auch sehr gut vorstellen, dass sich der Lehrer da ungenau ausgedrückt hat.



  • Oh, das wusste ich nicht, wieder was gelernt danke.



  • Quak schrieb:

    Oh, das wusste ich nicht, wieder was gelernt danke.

    Naja, string ist ja kein nativer Datentyp, sondern eine Klasse. Wie genau die realisiert wird, kann ja jeder Hersteller selbst entscheiden.
    Wichtig ist letztendlich, dass sie die vom Standard vorgeschriebene Schnittstelle und Funktionalität anbietet.



  • wenn ich so eine aufgabe schon sehe wo der lehrer keinen plan hat, auf präzise aufgaben sch*** und char mit string gleichsetzt. selbst keinen plan haben aber lehren. tolle wurst.



  • we don't need no educatio schrieb:

    wenn ich so eine aufgabe schon sehe wo der lehrer ... und char mit string gleichsetzt.

    Wo tut er das denn?



  • Das wird sich zeigen, was ich in der Schulaufgabe haben werde. Also eine 5 oder 6 wird es bestimmt nicht...

    Zumindest ist bei meinem Betriebssystem string 32 Byte groß.

    Zur Objektorientierung...

    Ich werde mir jetzt das Buch "Der C++ Programmierer" zu Gemüte führen. Vielleicht kommen da noch Fragen....

    Also schnallt euch an ... 😉



  • Belli schrieb:

    we don't need no educatio schrieb:

    wenn ich so eine aufgabe schon sehe wo der lehrer ... und char mit string gleichsetzt.

    Wo tut er das denn?

    die aufgabe zielt offenbar auf char[] vs. std::string ab. leider ist der lehrer zu unwissend, um dies entsprechend präzise zu formulieren. es wäre sehr überraschend, wenn er tatsächlich char gemeint hat.



  • Angenommen, er würde char vs string meinen. Wie hätte er das Deiner Meinung nach formulieren sollen?

    Wieso ist es eigentlich so 'offenbar', dass er was anderes meint, als er fragt? Für mich ist das auf jeden Fall nicht 'offenbar', sondern reinspekuliert.


Anmelden zum Antworten