In vielen Sprachen sind Aufträge unter bestimmten Bedingungen legal. Ich habe den Grund dafür nie verstanden. Warum würdest du schreiben:
if (var1 = var2) {
...
}
anstatt:
var1 = var2;
if (var1) {
...
}
In vielen Sprachen sind Aufträge unter bestimmten Bedingungen legal. Ich habe den Grund dafür nie verstanden. Warum würdest du schreiben:
if (var1 = var2) {
...
}
anstatt:
var1 = var2;
if (var1) {
...
}
Antworten:
Es ist für Schleifen nützlicher als für if-Anweisungen.
while( var = GetNext() )
{
...do something with var
}
Was sonst geschrieben werden müsste
var = GetNext();
while( var )
{
...do something
var = GetNext();
}
Ich finde es am nützlichsten in Aktionsketten, die häufig eine Fehlererkennung usw. beinhalten.
if ((rc = first_check(arg1, arg2)) != 0)
{
report error based on rc
}
else if ((rc = second_check(arg2, arg3)) != 0)
{
report error based on new rc
}
else if ((rc = third_check(arg3, arg4)) != 0)
{
report error based on new rc
}
else
{
do what you really wanted to do
}
Die Alternative (ohne Verwendung der Zuordnung in der Bedingung) ist:
rc = first_check(arg1, arg2);
if (rc != 0)
{
report error based on rc
}
else
{
rc = second_check(arg2, arg3);
if (rc != 0)
{
report error based on new rc
}
else
{
rc = third_check(arg3, arg4);
if (rc != 0)
{
report error based on new rc
}
else
{
do what you really wanted to do
}
}
}
Bei langwieriger Fehlerprüfung kann die Alternative von der rechten Seite der Seite ausgeführt werden, während die Version mit bedingter Zuweisung dies nicht tut.
Die Kontrollen Fehler könnte auch sein , ‚Aktionen‘ - first_action()
, second_action()
, third_action()
- natürlich nicht nur überprüft. Das heißt, sie könnten Schritte in dem Prozess sein, den die Funktion verwaltet. (Meistens befinden sich die Funktionen in dem Code, mit dem ich arbeite, im Sinne von Vorbedingungsprüfungen oder Speicherzuweisungen, die für die Funktion der Funktion erforderlich sind, oder in ähnlicher Weise).
Es ist nützlicher, wenn Sie eine Funktion aufrufen:
if (n = foo())
{
/* foo returned a non-zero value, do something with the return value */
} else {
/* foo returned zero, do something else */
}
Sicher, Sie können einfach n = foo () setzen; auf einer separaten Aussage dann wenn (n), aber ich denke, das obige ist eine ziemlich lesbare Redewendung.
Dies kann nützlich sein, wenn Sie eine Funktion aufrufen, die entweder Daten zur Bearbeitung oder ein Flag zurückgibt, um einen Fehler anzuzeigen (oder wenn Sie fertig sind).
Etwas wie:
while ((c = getchar()) != EOF) {
// process the character
}
// end of file reached...
Persönlich ist es eine Redewendung, die ich nicht besonders mag, aber manchmal ist die Alternative hässlicher.
GCC kann Ihnen helfen, (mit -Wall) zu erkennen, ob Sie unbeabsichtigt versuchen, eine Zuweisung als Wahrheitswert zu verwenden, falls empfohlen wird, dass Sie schreiben
if ((n = foo())) {
...
}
Verwenden Sie zusätzliche Klammern, um anzuzeigen, dass dies wirklich das ist, was Sie wollen.
Die Redewendung ist nützlicher, wenn Sie eine while
Schleife anstelle einer if
Anweisung schreiben . Für eine if
Aussage können Sie sie wie beschrieben aufteilen. Aber ohne dieses Konstrukt müssten Sie sich entweder wiederholen:
c = getchar();
while (c != EOF) {
// ...
c = getchar();
}
oder verwenden Sie eine anderthalb-Schleifen-Struktur:
while (true) {
c = getchar();
if (c == EOF) break;
// ...
}
Normalerweise würde ich die eineinhalb Loop-Form bevorzugen.
while
Verwenden Sie für eine Schleife lieber:do { c = getchar(); ... } while (c != EOF);
for
Schleifen können stattdessen verwendet werden: for (char c = getchar(); c != EOF; c= getchar()) { /* do something with c */ }
- das ist die prägnanteste, und for
sagt immer ‚Loop‘ mir, stilistisch. Ein kleiner Nachteil ist, dass Sie die Funktion angeben müssen, die c
zweimal zurückgibt.
Die kurze Antwort lautet, dass ausdrucksorientierte Programmiersprachen prägnanteren Code ermöglichen. Sie zwingen Sie nicht, Befehle von Abfragen zu trennen .
In PHP ist es beispielsweise nützlich, um SQL-Datenbankergebnisse zu durchlaufen:
while ($row = mysql_fetch_assoc($result)) {
// Display row
}
Das sieht viel besser aus als:
$row = mysql_fetch_assoc($result);
while ($row) {
// Display row
$row = mysql_fetch_assoc($result);
}
Der andere Vorteil ergibt sich aus der Verwendung von gdb. Im folgenden Code ist der Fehlercode nicht bekannt, wenn es sich um einen einzelnen Schritt handelt.
while (checkstatus() != -1) {
// process
}
Lieber
while (true) {
int error = checkstatus();
if (error != -1)
// process
else
//fail
}
Jetzt können wir im Einzelschritt anhand von checkstatus () den Rückgabefehlercode ermitteln.
Ich finde es sehr nützlich bei Funktionen, die Optionen zurückgeben ( boost::optional
oder std::optional
in C ++ 17):
std::optional<int> maybe_int(); // function maybe returns an int
if (auto i = maybe_int()) {
use_int(*i);
}
Dies reduziert den Umfang meiner Variablen, macht den Code kompakter und beeinträchtigt nicht die Lesbarkeit (finde ich).
Gleiches gilt für Zeiger:
int* ptr_int();
if (int* i = ptr_int()) {
use_int(*i);
}
Der Grund ist:
Leistungsverbesserung (manchmal)
Weniger Code (immer)
Nehmen Sie ein Beispiel: Es gibt eine Methode someMethod()
und in einer if
Bedingung möchten Sie überprüfen, ob der Rückgabewert der Methode ist null
. Wenn nicht, werden Sie den Rückgabewert erneut verwenden.
If(null != someMethod()){
String s = someMethod();
......
//Use s
}
Dies beeinträchtigt die Leistung, da Sie dieselbe Methode zweimal aufrufen. Verwenden Sie stattdessen:
String s;
If(null != (s = someMethod())) {
......
//Use s
}