Sauberer C++ Code?

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Sauberer C++ Code?

      Hiho,
      da viel diskutiert wird und in diesem Gebiet noch ziemlich neu bin, wollte ich einfach mal fragen, was ihr von meinem Code haltet.

      C-Quellcode

      1. #include <iostream>
      2. #include <string>
      3. int main() {
      4. /* Definition von Variabeln */
      5. int iInputP, iDivisorP, iModulusP, iInputC, iCacheInputC, iCrossfootC, iInputF[4], iHighestArrayF, iLowestArrayF;
      6. bool bRepeatP, bRepeatC, bPrimeP, bHigherThanF[4], bLowerThanF[4], bRepeatF;
      7. std::string sSelection, sRepeatP, sRepeatC, sRepeatF;
      8. /* Anfangsdialog */
      9. do {
      10. std::cout << "Moechten Sie ueberpruefen, ob eine Zahl eine Primzahl ist (P), moechten Sie eine Quersumme berechnen (C) oder die kleinste und groesste Zahl von 4 Zahlen (F)?" << std::endl;
      11. std::cin >> sSelection;
      12. if (sSelection != "p" && sSelection != "P" && sSelection != "c" && sSelection != "C" && sSelection != "f" && sSelection != "F") {
      13. std::cout << "Sie haben versucht, eine nicht vorhandene Funktion auszuwaehlen." << std::endl;
      14. }
      15. } while (sSelection != "p" && sSelection != "P" && sSelection != "c" && sSelection != "C" && sSelection != "f" && sSelection != "F");
      16. /* Primzahlüberprüfung */
      17. if (sSelection == "p" || sSelection == "P") {
      18. do {
      19. iDivisorP = 2;
      20. iModulusP = 1;
      21. std::cout << "Bitte geben Sie eine Zahl ein." << std::endl;
      22. std::cin >> iInputP;
      23. while (iDivisorP != iInputP) {
      24. iModulusP = iInputP % iDivisorP;
      25. iDivisorP++;
      26. if (iModulusP == 0) {
      27. bPrimeP = false;
      28. break;
      29. } else {
      30. bPrimeP = true;
      31. }
      32. }
      33. if (bPrimeP == false) {
      34. std::cout << iInputP << " ist keine Primzahl." << std::endl;
      35. } else {
      36. std::cout << iInputP << " ist eine Primzahl." << std::endl;
      37. }
      38. std::cout << "Noch eine Zahl ueberpruefen?" << std::endl << "Ja (J) oder Nein (N)" << std::endl;
      39. std::cin >> sRepeatP;
      40. if (sRepeatP == "J" || sRepeatP == "j") {
      41. bRepeatP = true;
      42. } else {
      43. bRepeatP = false;
      44. }
      45. } while (bRepeatP == true);
      46. /* Quersumme */
      47. } else if (sSelection == "c" || sSelection == "C") {
      48. do {
      49. std::cout << "Bitte geben Sie eine Zahl ein." << std::endl;
      50. std::cin >> iInputC;
      51. iCacheInputC = iInputC;
      52. iCrossfootC = 0;
      53. while (iInputC) {
      54. iCrossfootC += iInputC % 10;
      55. iInputC /= 10;
      56. }
      57. std::cout << "Die Quersumme der Zahl " << iCacheInputC << " ist " << iCrossfootC << std::endl << std::endl;
      58. std::cout << "Noch eine Quersumme ausrechnen?" << std::endl << "Ja (J) oder Nein (N)" << std::endl;
      59. std::cin >> sRepeatC;
      60. if (sRepeatC == "J" || sRepeatC == "j") {
      61. bRepeatC = true;
      62. } else {
      63. bRepeatC = false;
      64. }
      65. } while (bRepeatC == true);
      66. /* Größte und kleinste Zahl von 4 Zahlen */
      67. } else if (sSelection == "f" || sSelection == "f") {
      68. do {
      69. std::cout << "Bitte geben Sie vier Zahlen ein." << std::endl;
      70. std::cin >> iInputF[0];
      71. std::cin >> iInputF[1];
      72. std::cin >> iInputF[2];
      73. std::cin >> iInputF[3];
      74. std::cout << "Sie haben folgende Zahlen eingegeben: " << iInputF[0] << ", " << iInputF[1] << ", " << iInputF[2]<< " und " << iInputF[3] << "." << std::endl;
      75. for (int i = 0; i < 4; i++) {
      76. for (int x = 0; x < 4; x++) {
      77. if (iInputF[i] >= iInputF[x]) {
      78. bHigherThanF[x] = true;
      79. } else {
      80. bHigherThanF[x] = false;
      81. }
      82. }
      83. for (int y = 0; y < 4; y++) {
      84. if (iInputF[i] <= iInputF[y]) {
      85. bLowerThanF[y] = true;
      86. } else {
      87. bLowerThanF[y] = false;
      88. }
      89. }
      90. if (bHigherThanF[0] == true && bHigherThanF[1] == true && bHigherThanF[2] == true && bHigherThanF[3] == true) {
      91. iHighestArrayF = i;
      92. }
      93. if (bLowerThanF[0] == true && bLowerThanF[1] == true && bLowerThanF[2] == true && bLowerThanF[3] == true) {
      94. iLowestArrayF = i;
      95. }
      96. }
      97. std::cout << "Groesste Zahl: " << iInputF[iHighestArrayF] << std::endl << "Kleinste Zahl: " << iInputF[iLowestArrayF] << std::endl;
      98. std::cout << "Nochmal?" << std::endl << "Ja (J) oder Nein (N)" << std::endl;
      99. std::cin >> sRepeatF;
      100. if (sRepeatF == "J" || sRepeatF == "j") {
      101. bRepeatF = true;
      102. } else {
      103. bRepeatF = false;
      104. }
      105. } while (bRepeatF == true);
      106. }
      107. /* Damit sich das Programm nicht schließt */
      108. std::cin.sync();
      109. std::cin.get();
      110. }
      Alles anzeigen



      Programm funktioniert, geht mir nur um den Stil. Will mir ja keinen Stuss aneignen.

      Edit: Habs erneuert. (Variabeln verändert und Größe / Kleine Zahl von 4 Zahlen finden hinzugefügt)
      Alte Version im Spoiler.
      [SPOILER2]

      C-Quellcode

      1. #include <iostream>
      2. #include <string>
      3. int main() {
      4. /* Definition von Variabeln */
      5. int inputP, divisorP, modulusP, inputC, cacheInputC, crossfootC;
      6. bool bRepeatP, bRepeatC, primeP;
      7. std::string selection, sRepeatP, sRepeatC;
      8. /* Anfangsdialog */
      9. do {
      10. std::cout << "Moechten Sie ueberpruefen, ob eine Zahl eine Primzahl(P) ist, oder moechten Sie eine Quersumme(C) berechnen?" << std::endl;
      11. std::cin >> selection;
      12. if (selection != "p" && selection != "P" && selection != "c" && selection != "C") {
      13. std::cout << "Sie haben versucht, eine nicht vorhandene Funktion auszuwaehlen." << std::endl;
      14. }
      15. } while (selection != "p" && selection != "P" && selection != "c" && selection != "C");
      16. /* Primzahlüberprüfung */
      17. if (selection == "p" || selection == "P") {
      18. do {
      19. divisorP = 2;
      20. modulusP = 1;
      21. std::cout << "Bitte geben Sie eine Zahl ein." << std::endl;
      22. std::cin >> inputP;
      23. while (modulusP == 0 || inputP - 1 == divisorP) {
      24. modulusP = inputP % divisorP;
      25. divisorP++;
      26. if (modulusP == 0) {
      27. primeP = false;
      28. } else {
      29. primeP = true;
      30. }
      31. }
      32. if (primeP == false) {
      33. std::cout << inputP << " ist eine Primzahl." << std::endl;
      34. } else {
      35. std::cout << inputP << " ist keine Primzahl." << std::endl;
      36. }
      37. std::cout << "Noch eine Zahl ueberpruefen?" << std::endl << "Ja (J) oder Nein (N)" << std::endl;
      38. std::cin >> sRepeatP;
      39. if (sRepeatP == "J" || sRepeatP == "j") {
      40. bRepeatP = true;
      41. } else {
      42. bRepeatP = false;
      43. }
      44. } while (bRepeatP == true);
      45. /* Quersumme */
      46. } else if (selection == "c" || selection == "C") {
      47. do {
      48. std::cout << "Bitte geben Sie eine Zahl ein." << std::endl;
      49. std::cin >> inputC;
      50. cacheInputC = inputC;
      51. crossfootC = 0;
      52. while (inputC) {
      53. crossfootC += inputC % 10;
      54. inputC /= 10;
      55. }
      56. std::cout << "Die Quersumme der Zahl " << cacheInputC << " ist " << crossfootC << std::endl << std::endl;
      57. std::cout << "Noch eine Quersumme ausrechnen?" << std::endl << "Ja (J) oder Nein (N)" << std::endl;
      58. std::cin >> sRepeatC;
      59. if (sRepeatC == "J" || sRepeatC == "j") {
      60. bRepeatC = true;
      61. } else {
      62. bRepeatC = false;
      63. }
      64. } while (bRepeatC == true);
      65. }
      66. /* Damit sich das Programm nicht schließt */
      67. std::cin.sync();
      68. std::cin.get();
      69. }
      Alles anzeigen
      [/SPOILER2]
    • Werbung zur Unterstützung des Forums ( Bitte AddBlocker deaktivieren )

    • Für den Anfang völlig ok, jedoch kannst du dir das ganze std::cout etc. eigentlich sparen indem du am Anfang einfach using namespace std; benutzt.

      Dann weiß er automatisch das du die Standart Library benutzen willst für Eingaben oder Ausgaben etc.

      Und du kannst auch vor den Variablen Namen immer eine Abkürzung benutzen damit du weißt welcher Datentyp deine Variable eigentlich ist.

      zb. int iTest;
    • Delinquenz;315213 schrieb:

      Habe schon gehört, dass das zu Probleme führen könnte, wenn ich mehrere Bibliotheken benutze. Ist da was dran?

      €: Danke erstmal für deine Antwort.


      Es kann zu Problemen führen wenn du mehrere Librarys benutzt und eines Tages die Funktion einer Library erweiterst. Wenn du halt zb. in der neuen geupgradeten Library einen gleichen Funktionsnamen wie in einer anderen Library hast kann es zu Problemen führen, aber da du momentan dann nur using namespace std; benutzen würdest kommt es auch zu keinen Konflikten.

      Ach und wegen den Variablen Namen, gewöhne dir einfach so schnell wie möglich einen bestimmten Syntax an, da es sonst wie Kuddelmuddel aussieht.

      Zb. iTestVariable oder iTestvariable.

      Das musst du dann wissen.
    • Killerooo;315223 schrieb:

      Nutze einfach keine Notation, gibt es zahlreiche Texte drüber warum man es nicht machen sollte.
      kannst nach einer geklammer auch ne leerzeile machen:
      int main()
      {
      foo();
      }

      bei if's oder so gibt es 3 varianten

      if (selection == 1)
      oder
      if( selection == 1 )
      oder if(selection == 1)

      je nachdem wie du's schön findest.


      Nenn mir einen ordentlichen Grund, warum man z.B. nicht die Kamelnotation benutzen sollte.
      Das macht für jeden Entwickler die Variablen wesentlich einfacher zu lesen.
      Was ist einfacher?
      int ichbineineziemlichlangevariablediemannichtgutlesenkannweilnotationunnoetigist
      oder
      int iIchBinEineZiemlichLangeVariableDieManGutLesenKannWeilNotationSehrwohlNoetigIst

      edit: Die Leerzeichen in der Variablen entstehen automatisch, hab sie dort nicht hingemacht
    • Killerooo;315226 schrieb:

      Making Wrong Code Look Wrong - Joel on Software
      compiler haben eine typerkennung ausserdem sollte man als "entwickler" signifikante namen nutzen.

      es ist einfach nicht nötig, man kann es natürlich machen, oder wenn der standard der firma wo du arbeitest eine notation vorraussetzt wenn man selber es gut findet wie auch immer..


      Du kannst ja signifikante Namen benutzen für deine Variablen, jedoch benutze ich auch Notationen da ich es so gelernt habe und ich so einen besseren Überblick habe.

      Da Notationen halt den Code auch in der Perfomance auch nicht beeinflussen, sehe ich es nicht als Problem.

      Aber an dem Punkt muss jeder selber wissen wie gerne arbeiten möchte.
    • Es ist sehr viel Einfacher wenn man den Typ vor einer Variable setzt, hier ein Beispiel:


      int nLevel;
      bool bLevel;
      byte byLevel;
      long lLevel;
      ...


      Somit kann man bereits erkennen wenn man mehr als nur paar Dateien Code hat und die Variable oft braucht das man den und den Typ hat. (Finde ich zumindest)

      Du solltest auch berücksichtigen das zu große Variablen die nicht benötigt werden in dem sinne nur Speicher verhauen ist, das wirst du ab einer bestimmten größe des Programme's merken, hier auch ein Beispiel:


      int nPorno;
      for( int i = 0; i < 5; i++ )
      ...


      Nun kann int nPorno eine viel seitige zahl enthalten bis rauf zu 2.14 (INT_MAX) dennoch speicherst du in nPorno nur zahlen von 0 bis 100 was den rest der 2.14 Mrd nutzlos macht, dadurch verhaust du Speicher, nutz Byte (Max. 255, kein -) und du wirst keine Risiken zwecks Overflow oder sonstiges haben, das selbe bei der For schleife, wenn du eine begrentzte zahl hast wie oben die 5, kannst du auch byte nutzen.

      Bei einfachen If abfragen kannst du die {} weg lassen, hier ein Beispiel:


      if( bTest == true )
      thisthisthis();


      Dies kann nur angewendet werden wenn man nur eine Aufgabe hat sobald bTest true ist, dies funktioniert auch bei For Schleifen o.a.

      Abgekürtzte If/Else Abfragen solltest du dir auch mal ansehen, nehmen wir an du hast bool bTest, diese setzt dein Programm auf true nach einer zeit, du willst das prüfen ob die auf true ist und dann eine meldung ausgeben, wenn sie nach wie vor auf false ist dann eine andere meldung, dann kannst du es wie folt machen:


      bTest ? MessageBox( NULL, "True", "True", NULL ); : MessageBox( NULL, "False", "False", NULL );


      Ist anstat Normal 4 Zeile eine.

      Wie du siehst gibt es sehr sehr sehr viele sachen wo man abkürzen kann, aber jeder muss selbst wissen worin er übersicht hat oder nicht.

      Ps: Setz dich mal etwas mit "atoi()" auseinander, damit kannst du Zahlen aus einem String heraus holen, somit brauchst du nur ein Token und nicht x Variablen. =)

      Mfg. Crasy
    • Abgekürtzte If/Else Abfragen solltest du dir auch mal ansehen, nehmen wir an du hast bool bTest, diese setzt dein Programm auf true nach einer zeit, du willst das prüfen ob die auf true ist und dann eine meldung ausgeben, wenn sie nach wie vor auf false ist dann eine andere meldung, dann kannst du es wie folt machen:

      bTest ? MessageBox( NULL, "True", "True", NULL ); : MessageBox( NULL, "False", "False", NULL );
      Ist anstat Normal 4 Zeile eine.


      Das halte ich aber für einen Anfänger nicht ratsam, weder beim kompilieren ( da sogar bei einigen Compilern langsamer )
      noch beim Programmablauf ist diese Schreibweise schneller, das nimmt sich dann nämlich nix mehr und
      ist für einen Anfänger doch ein wenig unübersichtlich.
    • Es ist sehr viel Einfacher wenn man den Typ vor einer Variable setzt, hier ein Beispiel:

      Du meinst die ungarische Notation?!

      Na ja, ich finde das nicht wirklich einfacher. Wenn du so eine Variable nutzt, musst du auch wissen, was sie überhaupt speichert; und dann weißt du in der Regel auch, von welchem Typ sie ist. Zudem kennt auch jede gute IDE den Datentyp einer Variable.

      Du solltest auch berücksichtigen das zu große Variablen die nicht benötigt werden in dem sinne nur Speicher verhauen ist, das wirst du ab einer bestimmten größe des Programme's merken, hier auch ein Beispiel:

      Okay ... Auf dem PC spielt das sicher keine Rolle. Damit speicherst du genau drei Bytes ... Erst wenn man 350 000 Mal drei Bytes einspart kommt man auf ein Megabyte. Das ist daher doch sch**** egal. Irgendwelche Resourcen wie Bilder, Videos, Models, ... nehmen da doch ein Vielfaches an Speicher in Anspruch.

      Bei einfachen If abfragen kannst du die {} weg lassen, hier ein Beispiel:

      Du machst deinen Code unleserlicher und anfälliger für Bugs, nur, um zwei Klammern einzusparen? Netbeans gibt mir sogar eine Warnung aus, wenn ich die {} weg lasse.
    • Du machst deinen Code unleserlicher und anfälliger für Bugs, nur, um zwei Klammern einzusparen? Netbeans gibt mir sogar eine Warnung aus, wenn ich die {} weg lasse.


      Anfälliger? naja, weniger? es kommt auch darauf an was für ein Compiler man nutzt.

      Ich Persönlich nutze den Intel Compiler, dies in VS2012 inkl. vAssistX und das bringt schon einiges an Leistung raus und gibt dir meist sogar den Rat das so zu machen anstat anders.

      Pers. ist das meine weiße etwas zu machen, wie ihr das seht muss euch überlassen sein.

      Noch ein Rat: Installier dir vAssistX bringt einiges in sachen übersicht und du kannst Variablen im ganzen Source abfragen etc, sehr nützliches Tool.
    • Anfälliger? naja, weniger? es kommt auch darauf an was für ein Compiler man nutzt.

      Ich Persönlich nutze den Intel Compiler, dies in VS2012 inkl. vAssistX und das bringt schon einiges an Leistung raus und gibt dir meist sogar den Rat das so zu machen anstat anders.

      Mit anfälliger meinte ich, dass es bei dieser Notation durch spätere Modifikation des Quelltextes eher zu Bugs führt, da man schnell das Fehlen der Klammern übersehen kann. Erst recht wenn zwei solcher Blöcke verschachtelt sind.

      Ich kann mir beim besten Willen nicht vorstellen, dass dir diese Notation einen Geschwindigkeitsvorteil gibt (erst recht keinen spür- bzw. messbaren). Moderne Compiler optimieren den Quelltext so stark, dass der Unterschied zwischen if(foo) { bar(); } und if(foo) bar(); im Produkt sicher nicht mehr zu erkennen ist (und entsprechend wird es auch keinen Unterschied machen).
    • Danke für eure zahlreichen Antworten =)

      Die gekürzten If-Schleifen (auch die ohne Klammern) gefallen mir irgendwie nicht so ganz.

      Ansonsten haben mir hier einige Tipps schon sehr geholfen. Fand jedoch Schade, dass Killeroo kaum Argumente gegen die Notation gebracht hat (Eine englische Wall of Text posten ist für mich leider kein Argument, sorry)
    • If ist keine Schleife (nenn es lieber If-Konstruktion, If-Statement, Fallunterscheidung, ... - aber nicht If-Schleife, denn das ist falsch).

      Argumente gegen die Ungarische Notation:

      * Überflüssig: Jede gute IDE kennt die Typen der deklarierten Variablen.
      * Hinderlich: Die Autovervollständigung der IDE schlägt in manchen Fällen erst nach mehr eingebenen Zeichen die richtige Variable vor (bspw. wenn die Variablen foo und bar deklariert wurden: ohne Ungarische Notation kann die Autovervollständigung nach einem bzw. zwei Zeichen unterscheiden, wenn die Variablen hingegen die Bezeichnungen m_arrIFoo und m_arrIBar tragen erst nach sieben Zeichen (die Präfixe sind willkürlich gewählt; ich kenne die Notation nicht wirklich)).