Ich habe ein paar Schleifen, die ich in meinem Programm brauche. Ich kann den Pseudocode ausschreiben, bin mir aber nicht ganz sicher, wie ich sie logisch schreiben soll.
Ich brauche -
if (num is a multiple of 10) { do this }
if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this }
else { do this } //this part is for 1-10, 21-30, 41-50, 61-70, 81-90
Dies ist für ein Brettspiel mit Schlangen und Leitern, wenn es für meine Frage sinnvoller ist.
Ich stelle mir die erste if-Anweisung vor, die ich verwenden muss, um den Modul zu verwenden if (num == 100%10)
das richtig?
Den zweiten habe ich keine Ahnung. Ich kann es if (num > 10 && num is < 21 || etc)
so ausschreiben, aber es muss etwas Klügeres geben.
c++
comparison
conditional-statements
integer-arithmetic
user3419168
quelle
quelle
Antworten:
Überprüfen Sie beim ersten Mal, ob eine Zahl ein Vielfaches der Verwendung ist:
Für den zweiten:
Aber das ist ziemlich dicht, und Sie sollten die Optionen besser explizit auflisten.
Nachdem Sie eine bessere Vorstellung davon haben, was Sie tun, würde ich die zweite schreiben als:
Es ist die gleiche Logik, aber durch die Verwendung der Funktion erhalten wir eine klarere Vorstellung davon, was dies bedeutet.
quelle
if((num - 1) / 10) % 2 == 1 && num < 100)
- Ich würde weinen, wenn ich das sehen würde.num >= 11
, dass (1) die Untergrenze verboten ist und (2)%
bei einer negativen Zahl ebenfalls eine negative Zahl zurückgegeben wird. (Ich muss zugeben, dass die Verwendung& 1
hier "sicherer" ist, setzt aber auch zusätzliches Wissen voraus.)getRow(num) % 2 == 0
in eine Funktion zu wickeln , um kristallklar zu machen, was die Absicht ist.bool inEvenRow(int num){ return getRow(num) % 2 ==0;}
Der Trick dabei ist, nach einer Art Gemeinsamkeit zwischen den Bereichen zu suchen. Natürlich können Sie immer die "Brute Force" -Methode verwenden:
Aber Sie können feststellen , dass, wenn Sie subtrahieren
1
ausnum
, Sie werden die Bereiche haben:Mit anderen Worten, alle zweistelligen Zahlen, deren erste Ziffer ungerade ist. Als nächstes müssen Sie eine Formel entwickeln, die dies ausdrückt. Sie können die erste Ziffer erhalten, indem Sie durch 10 teilen, und Sie können testen, ob sie ungerade ist, indem Sie beim Teilen durch 2 nach einem Rest von 1 suchen. Alles zusammen:
Angesichts des Kompromisses zwischen längerem, aber wartbarem Code und kürzerem "cleverem" Code würde ich jedes Mal länger und klarer wählen. Wenn Sie versuchen, klug zu sein, fügen Sie bitte einen Kommentar hinzu, der genau erklärt, was Sie erreichen möchten.
Es ist hilfreich anzunehmen, dass der nächste Entwickler, der an dem Code arbeitet, scharf ist und weiß, wo Sie leben. :-)
quelle
&& isTensDigitOdd(num)
, vielleicht mit einem Kommentar vor der Funktionsdefinition, der erklärt, was es tut. Wenn ein solches Muster existiert, ist ein Kommentar, der die Gründe für das Muster erklärt, für die Wartbarkeit imo aufschlussreich.Wenn Sie GCC oder einen anderen Compiler verwenden, der dies unterstützt Fall Bereiche können Sie dies tun, aber Ihr Code nicht tragbar sein .
quelle
Dies ist für zukünftige Besucher mehr als für Anfänger. Für eine allgemeinere, algorithmische Lösung können Sie eine Liste von Start- und Endwerten erstellen und prüfen, ob sich ein übergebener Wert in einem von ihnen befindet:
Der Einfachheit halber habe ich anstelle eines expliziten
pair
Arguments ein polymorphes Lambda (C ++ 14) verwendet . Dies sollte wahrscheinlich auch bei der Verwendung bleiben<
und==
mit den Standardalgorithmen übereinstimmen, aber es funktioniert so, solangeElem
es dafür<=
definiert wurde. Wie auch immer, es kann so verwendet werden:Es gibt ein anschauliches Beispiel hier .
quelle
Der erste ist einfach. Sie müssen nur den Modulo-Operator auf Ihren num-Wert anwenden:
Da C ++ jede Zahl, die nicht 0 ist, als wahr auswertet, können Sie auch schreiben:
Für den zweiten denke ich, dass dies sauberer zu verstehen ist:
Das Muster wird alle 20 wiederholt, sodass Sie Modulo 20 berechnen können. Alle gewünschten Elemente befinden sich in einer Reihe, mit Ausnahme derjenigen, die durch 20 teilbar sind.
Um diese auch zu erhalten, verwenden Sie einfach num-1 oder besser num + 19, um den Umgang mit negativen Zahlen zu vermeiden.
Dies setzt voraus, dass sich das Muster für immer wiederholt, sodass es für 111-120 erneut gilt und so weiter. Andernfalls müssen Sie die Anzahl auf 100 beschränken:
quelle
Mit ein paar guten Kommentaren im Code kann es sehr präzise und lesbar geschrieben werden.
quelle
num % 10 == 0
dasselbe ist wienum
ein Vielfaches von 10.if (num % 10 == 0)
bedeutet dasselbe,// Check if it's a multiple of 10
sollte Ihren Code nicht pflegen . Dies ist ein bekanntes Anti-Muster.%
ein Anti-Muster ist; offensichtlich ist es nicht. Unter der Annahme, dass viele der Leser dieses Beitrags Anfänger sein werden, trägt das Unterrichten dieser Art des Schreibens von Kommentaren einen negativen Beitrag zu ihrer Entwicklung als Programmierer bei.Sie haben die Antwort im Grunde selbst erklärt, aber hier ist der Code für alle Fälle.
quelle
x < 41 x > 50
und setzen Sie Klammern.operator&&
eine höhere Priorität alsoperator||
, also ist es in Ordnung, aber ich bin mir ziemlich sicher, dass GCC trotzdem davor warnt.10 < x < 21
als10 < x && x < 21
eher alsx > 10 && x < 21
. Es ist einfacher, die Ungleichung zu lesen, wenn sie in derselben Reihenfolge vorliegt, in der Sie sie mathematisch schreiben würden.Sie könnten dies überdenken.
Die erste Zeile
if (x % 10)
funktioniert, weil (a) ein Wert, der ein Vielfaches von 10 ist, als '0' berechnet wird, andere Zahlen zu ihrem Rest führen, (b) ein Wert von 0 in aif
berücksichtigt wirdfalse
, jeder andere Wert isttrue
.Bearbeiten:
Verwenden Sie den gleichen Trick, um in den zwanziger Jahren hin und her zu wechseln. Diesmal lautet die zentrale Nummer
10
:x/10
Gibt eine beliebige Zahl von 0 bis 9 als0
, 10 bis 19 als1
usw. zurück.& 1
Wenn Sie auf gerade oder ungerade testen, erfahren Sie, ob es gerade oder ungerade ist. Da Ihre Bereiche tatsächlich "11 bis 20" sind, subtrahieren Sie 1 vor dem Testen.quelle
Ein Plädoyer für Lesbarkeit
Obwohl Sie bereits einige gute Antworten haben, möchte ich eine Programmiertechnik empfehlen, die Ihren Code für zukünftige Leser besser lesbar macht - das können Sie in sechs Monaten sein, ein Kollege, der gebeten wurde, eine Codeüberprüfung durchzuführen, Ihr Nachfolger, .. .
Dies dient dazu, alle "cleveren" Anweisungen in eine Funktion zu packen, die genau (mit ihrem Namen) zeigt, was sie tut. Während es einen winzigen Einfluss auf die Leistung gibt (von "Funktionsaufruf-Overhead"), ist dies in einer Spielsituation wie dieser wirklich vernachlässigbar.
Unterwegs können Sie Ihre Eingaben bereinigen - beispielsweise auf "illegale" Werte testen. So könnte es sein, dass Sie Code wie diesen erhalten - sehen Sie, wie viel besser lesbar er ist? Die "Hilfsfunktionen" können irgendwo versteckt sein (sie müssen nicht im Hauptmodul sein: aus ihrem Namen geht hervor, was sie tun):
quelle
YES
und zu weit zu schieben?NO
?TRUE
,True
odertrue
? Und welche Header-Dateien müsste ich, wenn überhaupt, in normales C aufnehmen? Also habe ich meine eigenen gerollt. Ich frage mich, ob das eine Ablehnung war ...Für den ersten:
gilt für:
Für den zweiten:
wird beantragen für:
Wir tun
x-1
im Grunde zuerst, um zu bekommen:Dann teilen wir sie durch
10
, um zu erhalten:Wir prüfen also, ob dieses Ergebnis ungerade ist.
quelle
Sie können Folgendes versuchen:
quelle
Ich weiß, dass diese Frage so viele Antworten hat, aber ich werde meine trotzdem hierher werfen ...
Entnommen aus Steve McConnells Code Complete , 2. Auflage: "Stair-Step Access Tables:
Eine weitere Art des Tischzugangs ist die Treppenstufenmethode. Diese Zugriffsmethode ist nicht so direkt wie eine Indexstruktur, verschwendet jedoch nicht so viel Datenraum. Die in Abbildung 18-5 dargestellte allgemeine Idee von Treppenstufenstrukturen besteht darin, dass Einträge in einer Tabelle eher für Datenbereiche als für bestimmte Datenpunkte gültig sind.
Abbildung 18-5 Der Treppenstufenansatz kategorisiert jeden Eintrag, indem er die Ebene bestimmt, auf der er auf eine „Treppe“ trifft. Der „Schritt“, den es trifft, bestimmt seine Kategorie.
Wenn Sie beispielsweise ein Benotungsprogramm schreiben, kann der Eingabebereich „B“ zwischen 75 und 90 Prozent liegen. Hier ist eine Reihe von Noten, die Sie möglicherweise eines Tages programmieren müssen:
Um die Treppenstufenmethode zu verwenden, fügen Sie das obere Ende jedes Bereichs in eine Tabelle ein und schreiben dann eine Schleife, um eine Punktzahl gegen das obere Ende jedes Bereichs zu überprüfen. Wenn Sie den Punkt finden, an dem die Punktzahl zum ersten Mal die Spitze eines Bereichs überschreitet, wissen Sie, wie hoch die Note ist. Bei der Treppenstufentechnik müssen Sie darauf achten, die Endpunkte der Bereiche richtig zu handhaben. Hier ist der Code in Visual Basic, der einer Gruppe von Schülern anhand dieses Beispiels Noten zuweist:
Obwohl dies ein einfaches Beispiel ist, können Sie es leicht verallgemeinern, um mehrere Schüler, mehrere Bewertungsschemata (z. B. unterschiedliche Noten für unterschiedliche Punktebenen bei unterschiedlichen Aufgaben) und Änderungen im Bewertungsschema zu behandeln. "
Code Complete , 2. Auflage, Seiten 426 - 428 (Kapitel 18).
quelle
Wie andere bereits betont haben, beschleunigt eine präzisere Gestaltung der Bedingungen weder die Kompilierung noch die Ausführung, und dies trägt auch nicht unbedingt zur Lesbarkeit bei.
Dies kann Ihnen dabei helfen, Ihr Programm flexibler zu gestalten, falls Sie später entscheiden, dass Sie eine Kleinkindversion des Spiels auf einem 6 x 6-Brett oder eine erweiterte Version (die Sie die ganze Nacht spielen können) auf einem 40 x 50-Brett wünschen .
Also würde ich es wie folgt codieren:
Ja, es ist ausführlich, aber es macht deutlich, was genau auf dem Spielbrett passiert.
Wenn ich dieses Spiel für die Anzeige auf einem Telefon oder Tablet entwickeln würde, würde ich anstelle von Konstanten ROWS- und COLUMNS-Variablen erstellen, damit sie dynamisch (zu Beginn eines Spiels) an die Bildschirmgröße und -ausrichtung angepasst werden können.
Ich würde auch zulassen, dass die Bildschirmausrichtung jederzeit während des Spiels geändert wird - alles, was Sie tun müssen, ist, die Werte von ROWS und COLUMNS zu ändern, während Sie alles andere belassen (die aktuelle quadratische Zahl, auf der jeder Spieler ist, und die Start- / Endquadrate aller Schlangen und Leitern) unverändert. Dann müssen Sie "nur" die Tafel schön zeichnen und Code für Ihre Animationen schreiben (ich nehme an, das war der Zweck von Ihnen
if
Aussagen) ...quelle
#define
#define
Anweisungen verwenden, um die Argumente in Klammern zu setzen, wo sie in der Erweiterung erscheinen. Also statt#define finished(num) (num == lastSquare)
du solltest schreiben#define finished(num) ((num) == lastSquare)
. Der Grund dafür ist, dass Sie nicht die erwartete Antwort erhalten, wenn Sie eine solche Anweisung mit einem Ausdruck verwenden, der einen Operator mit einer ausreichend niedrigen Priorität enthält. In diesem Fall, wenn Sie nicht über die zusätzlichen Klammern verwenden, dannfinished(a & b)
dehnt sich in(a & b == lastSquare)
die mit ziemlicher Sicherheit nicht das, was Sie wollen.