bool isInRange(int zahl, int untereGrenze, int obereGrenze);



  • whaaatz schrieb:

    Ich bin jetzt seit einer Woche C++ am programmieren und mir selber Aufgaben gemacht und zum Teil aus Büchern und Internet.

    Aber der Stil ist schrecklich. Lösch die Bücher am besten sofort.

    #include <iostream>
    #include <cmath>
    //Bis hier war's ok
    
    #define ERR_UNGERADE "Die Zahl ist ungerade"
    #define ERR_GRENZE  "Die Zahl ist ausserhalb der Grenze"
    //KEINE MAKROS NEHMEN!
    
    #define OBEREGRENZE (100)
    #define UNTEREGRENZE (50)
    //KEINE MAKROS NEHMEN! Wozu die nutzlosen Klammern?
    
    #define TEST 1
    //Mach das unten und ohne Makro
    
    #define DEBUG 1
    //Mach das unten und ohne Makro
    
    using namespace std;
    //Eine Zeile ok
    
    bool insideRange (int zahl,int unten, int oben);
    bool isEven (int zahl);
    //Funktionprototypen völlig sinnlos
    
    int main()
    {
    	if(UNTEREGRENZE>OBEREGRENZE)
    	{
    		cout<< "Falsche Konfiguration"<< endl;
    		return EXIT_FAILURE;
    	}
    	//Test eher sinnloc
    
    #if TEST==1
    	cout << "Testfunktion: "<<boolalpha <<  insideRange(50, 0, 100)  << endl;
    	cout << "Testfunktion: "<<boolalpha <<  insideRange(5, 90, 100)  << endl;
    	cout << "Testfunktion: "<<boolalpha << isEven(80)<< endl;
    	cout << "Testfunktion: "<<boolalpha << isEven(85)<< endl;
    #endif
    //Ganz schlecht. Besser wäre zum Beispiel
    //#define TEST(x) cout<<#x<<'='<<(x)<<'\n'
    //TEST(insideRange(50,0,100);
    //TEST(insideRange(50,90,100);
    //...
    
    	int zahl = 1;
    #if DEBUG == 1
    	cout << "zahl: "<< zahl << endl;
    #endif
    //Willste mich veralbern?
    
    	cout << "bitte eingeben: " << endl;
    	cin >> zahl; 
    	cout << "zahl: "<< zahl << endl;
    //Wozu die Ausgabe?
    
    	int error = 0;
    
    		if (insideRange(zahl, UNTEREGRENZE, OBEREGRENZE) )
    		{
    			cout << "Oberegrenze: "  << endl;
    		}
    		else if (insideRange(zahl, -OBEREGRENZE, -UNTEREGRENZE) )
    		{
    			cout << "Unteregrenze: "  << endl;
    		}
    //Hier ist völlig unklar, was berechnet wurde
    		else
    		{   
    			error+=1; 
    		}
    //Bei Fehler rausreturnen, das künstliche Flag ist Pascal
    
    		if (!error)
    		{
    			if(isEven(zahl))
    			{
    				cout << "Zahl ist gerade" << endl;
    			}
    			else
    			{
    				error+=1; //Fall 1: Zahl ist ungerade
    //Hä?
    			}
    		}
    		switch (error)
    		{
    		case 0:
    			cout << "Zahl ist gerade" << endl;
    			break;
    		case 1:
    			cout << "Ist ein Fehler aufgetreten" << endl;
    
    			break;
    		default:
    			break;
    		}
    //Jetzt ein switch, wo ein if sein soll
    		return (error>0 ? EXIT_FAILURE : EXIT_SUCCESS);
    //Nutzlose Klammern, return IST KEINE FUNKTION, 
    //Wozu in aller Welt ?: nehmen? Hättest bei Fehlern einfach 
    //direkt EXIT_FAILURE rausreturnen sollen. 
    }
    
    bool insideRange (int zahl,int unten, int oben)
    {
    	if (zahl>= unten && zahl<= oben)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    
    bool isEven(int zahl)
    {	
    	if (!(zahl%2))
    //Mach das ! dort weg! ! ist logisch. Du willst aber numerisch testen, 
    //also if(zahl%2)==0)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    


  • volkard schrieb:

    whaaatz schrieb:

    Ich bin jetzt seit einer Woche C++ am programmieren und mir selber Aufgaben gemacht und zum Teil aus Büchern und Internet.

    Aber der Stil ist schrecklich. Lösch die Bücher am besten sofort.

    #include <iostream>
    #include <cmath>
    //Bis hier war's ok
    
    #define ERR_UNGERADE "Die Zahl ist ungerade"
    #define ERR_GRENZE  "Die Zahl ist ausserhalb der Grenze"
    //KEINE MAKROS NEHMEN!
    
    #define OBEREGRENZE (100)
    #define UNTEREGRENZE (50)
    //KEINE MAKROS NEHMEN! Wozu die nutzlosen Klammern?
    
    #define TEST 1
    //Mach das unten und ohne Makro
    
    #define DEBUG 1
    //Mach das unten und ohne Makro
    
    using namespace std;
    //Eine Zeile ok
    
    bool insideRange (int zahl,int unten, int oben);
    bool isEven (int zahl);
    //Funktionprototypen völlig sinnlos
    
    int main()
    {
    	if(UNTEREGRENZE>OBEREGRENZE)
    	{
    		cout<< "Falsche Konfiguration"<< endl;
    		return EXIT_FAILURE;
    	}
    	//Test eher sinnloc
    	
    #if TEST==1
    	cout << "Testfunktion: "<<boolalpha <<  insideRange(50, 0, 100)  << endl;
    	cout << "Testfunktion: "<<boolalpha <<  insideRange(5, 90, 100)  << endl;
    	cout << "Testfunktion: "<<boolalpha << isEven(80)<< endl;
    	cout << "Testfunktion: "<<boolalpha << isEven(85)<< endl;
    #endif
    //Ganz schlecht. Besser wäre zum Beispiel
    //#define TEST(x) cout<<#x<<'='<<(x)<<'\n'
    //TEST(insideRange(50,0,100);
    //TEST(insideRange(50,90,100);
    //...
    
    	int zahl = 1;
    #if DEBUG == 1
    	cout << "zahl: "<< zahl << endl;
    #endif
    //Willste mich veralbern?
    	
    	cout << "bitte eingeben: " << endl;
    	cin >> zahl; 
    	cout << "zahl: "<< zahl << endl;
    //Wozu die Ausgabe?
    	
    	int error = 0;
    
    		if (insideRange(zahl, UNTEREGRENZE, OBEREGRENZE) )
    		{
    			cout << "Oberegrenze: "  << endl;
    		}
    		else if (insideRange(zahl, -OBEREGRENZE, -UNTEREGRENZE) )
    		{
    			cout << "Unteregrenze: "  << endl;
    		}
    //Hier ist völlig unklar, was berechnet wurde
    		else
    		{   
    			error+=1; 
    		}
    //Bei Fehler rausreturnen, das künstliche Flag ist Pascal
    		
    		if (!error)
    		{
    			if(isEven(zahl))
    			{
    				cout << "Zahl ist gerade" << endl;
    			}
    			else
    			{
    				error+=1; //Fall 1: Zahl ist ungerade
    //Hä?
    			}
    		}
    		switch (error)
    		{
    		case 0:
    			cout << "Zahl ist gerade" << endl;
    			break;
    		case 1:
    			cout << "Ist ein Fehler aufgetreten" << endl;
    			
    			break;
    		default:
    			break;
    		}
    //Jetzt ein switch, wo ein if sein soll
    		return (error>0 ? EXIT_FAILURE : EXIT_SUCCESS);
    //Nutzlose Klammern, return IST KEINE FUNKTION, 
    //Wozu in aller Welt ?: nehmen? Hättest bei Fehlern einfach 
    //direkt EXIT_FAILURE rausreturnen sollen. 
    }
    
    bool insideRange (int zahl,int unten, int oben)
    {
    	if (zahl>= unten && zahl<= oben)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    
    bool isEven(int zahl)
    {	
    	if (!(zahl%2))
    //Mach das ! dort weg! ! ist logisch. Du willst aber numerisch testen, 
    //also if(zahl%2)==0)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    

    Ich weiss das viele unnützlich ist aber ich wollte nur so viel wie möglich in ein simples Programm linken damit ich besser üben kann...
    aber danke das du dir die mühe gemacht hast.... werde deine Kommentar sicherlich bei meiner nächsten Aufgaben berücksichtigen



  • Dieser Thread wurde von Moderator/in Korbinian aus dem Forum Projekte in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • ich würds sorum machen:

    bool isEven(int zahl) 
    {    
        if (zahl%2)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    

    und mich dann fragen: warum englischer bezeichner und deutscher variablenname?
    und dann würd ichs einfach so machen:

    bool isEven(int number)
    {
      return number%2 == 0;
    }
    

    bb



  • da volkard vergessen hat dir 'ne andere Möglichkeit zu zeigen, hole ich das mal nach

    #define ERR_UNGERADE "Die Zahl ist ungerade" 
    #define ERR_GRENZE  "Die Zahl ist ausserhalb der Grenze" 
    //KEINE MAKROS NEHMEN! 
    
    #define OBEREGRENZE (100) 
    #define UNTEREGRENZE (50) 
    //KEINE MAKROS NEHMEN! Wozu die nutzlosen Klammern?
    
    const std::string ERR_UNGERADE = "Die Zahl ist ungerade";
    const std::string ERR_GRENZE = "Die Zahl ist ausserhalb der Grenze";
    const int OBEREGRENZE=100;
    const int UNTEREGRENZE=50;
    

    1. wegen der Typensicherheit
    2. die Variablen können nicht mal ebent durch unachtsam magisch verändert werden.

    Predeklarationen sind nur bei soetwas notwendig (oder wenn der Compiler jammert):

    void foo();
    void bar(){foo();}
    void foo(){bar();}
    


  • Makros haben auch oft die Probleme, die die dumme Textersetzung mit sich bringt (bei einfachen Konstanen vielleicht weniger). Aber es fehlen zum Beispiel auch Debugsymbole.

    Ich würde dennoch const char* statt const std::string nehmen , dieser ist nämlich für Stringliterale stark übertrieben.

    const char* ERR_UNGERADE = "Die Zahl ist ungerade";
    const char* ERR_GRENZE = "Die Zahl ist ausserhalb der Grenze";
    


  • Nexus schrieb:

    Ich würde dennoch const char* statt const std::string nehmen , dieser ist nämlich für Stringliterale stark übertrieben.

    Hahahahahahahaha ....

    Wir wollten ihm doch modernes C++ beibringen. Da nimmt man den std::string!
    Genauso wie man std::cout verwendet statt printf.



  • nurf schrieb:

    Hahahahahahahaha ....

    Wir wollten ihm doch modernes C++ beibringen. Da nimmt man den std::string!
    Genauso wie man std::cout verwendet statt printf.

    Schade, dass du keine Argumente hast, aber zu den Leuten gehörst, die C++-Mittel prinzipiell besser finden, egal um welches Problem es geht.

    Sieh es ein, es gibt an dieser Stelle keinen Grund für std::string , aber eine Menge Gründe dagegen. Benutzt du auch kein <cmath> , weil es das in C schon gab? 🙄



  • Als Pendant zu const std::string würde ich hier const char* const (statt const char* ) nehmen, wegen unveränderbar und so. Und std::string hat hier auch Vorteile, z.B. string.length, rbegin/rend, die find-Methoden usw. Muss man natürlich schauen, wenn man's nicht braucht (was ja meistens der Fall ist), reicht auch der Zeiger.
    Oh, und vorteilhaft ist es auch bei der Übergabe an Funktionen, die const std::string& nehmen, damit nicht jedesmal eine Kopie erzeugt wird.



  • Nexus schrieb:

    Sieh es ein, es gibt an dieser Stelle keinen Grund für std::string , aber eine Menge Gründe dagegen. Benutzt du auch kein <cmath> , weil es das in C schon gab? 🙄

    Ja dann mal her mit den Gründen, scheint mir eher tief verwurzelter Aberglaube zu sein.



  • nurf schrieb:

    Nexus schrieb:

    Sieh es ein, es gibt an dieser Stelle keinen Grund für std::string , aber eine Menge Gründe dagegen. Benutzt du auch kein <cmath> , weil es das in C schon gab? 🙄

    Ja dann mal her mit den Gründen, scheint mir eher tief verwurzelter Aberglaube zu sein.

    Hmm, das ist ne fixe Meldung, du wirst die jetzt nicht nach irgendwlchen Zeichen durchsuchen wollen, oder sonst was damit anstellen, wofür du die ganze Macht der string-Klasse benötigst. Du willst einfach einen unveränderlichen Text, dafür ist das minimale Mittel ein "const char*". Deshalb spricht einiges dafür. Und das sollte auch reichen.

    Oder hast du jetzt deine "Aussage" auf den Teil mit cmath bezogen? Ich hoffe zutiefst dass du einfach zu faul warst den quote zu bearbeiten...



  • @ Badestrand:
    Hm ja. std::string hat schon an manchen Orten Vorteile, aber ihn grundsätzlich immer zu empfehlen, nur weil er C++ ist, finde ich nicht gut.

    Schlimm finde ich sowas:

    void MyClass::OpenFile(const std::string& FileName)
    {
        FileStream.open(FileName.c_str());
    }
    
    int main()
    {
        MyClass x;
        x.OpenFile("file.txt");
    }
    

    Je nachdem wäre es sogar eine Überlegung wert, eine eigene Klasse für solche unveränderlichen Strings zu erstellen. Geht zwar auch ohne, aber wenns um Optimierung geht, könnte sowas schon praktisch sein.

    nurf schrieb:

    Ja dann mal her mit den Gründen, scheint mir eher tief verwurzelter Aberglaube zu sein.

    Okay, da du scheinbar immer noch keine Argumente dafür hast: Du brauchst die String-Funktionalität in vielen Fällen gar nicht! Ein std::string hat eine dynamische Speicherverwaltung, Wachstumssemantik mit Grösse und Kapazität, oft auch gespeicherte Iteratoren, also einen rechten Overhead. sizeof(std::string) ist bei mir im Release-Modus 28, das ist nicht selten mehr als überhaupt als Text gespeichert wird (in Anwendungsfällen von Stringliteralen).

    Natürlich kann man sich auch grundsätzlich nicht um solche Überlegungen kümmern und alles als Premature Optimization abtun. Am besten dabei ständig nach dem Dogma "C ist grundsätzlich schlecht, man muss in jedem Fall C++ nutzen" handeln und gleichzeitig anderen Aberglaube unterstellen. Naja... 🙄



  • C++ Strings sind grundsätzlich "broken". Man sollte sie trotzdem vielerorts verwenden, weil sie halt Standard sind, und ein schlechter Standard immer noch besser ist als 100 String-Klassen von 100 Libraries in einem Projekt (*kotz*).

    Für Fehlermeldungs-Konstanten finde ich std::string aber auch nicht gerade "nötig".

    const char* const hat sogar einen wichtigen Vorteil, wenn es um statische String Konstanten geht: es benötigt keine Konstruktoren -> kein "static initialization order fiasco".

    nurf schrieb:

    Hahahahahahahaha ....

    Wir wollten ihm doch modernes C++ beibringen. Da nimmt man den std::string!
    Genauso wie man std::cout verwendet statt printf.

    Lachst du dich hier selbst aus, weil du weisst was du gleich für Unsinn ablassen wirst? 😕


Anmelden zum Antworten