Waarom zou je een opdracht in een conditie gebruiken?

In veel talen zijn opdrachten onder voorwaarden legaal. Ik heb de reden hierachter nooit begrepen. Waarom zou je schrijven:

if (var1 = var2) {
  ...
}

in plaats van:

var1 = var2;
if (var1) {
  ...
}

Antwoord 1, autoriteit 100%

Het is nuttiger voor loops dan if-statements.

while( var = GetNext() )
{
  ...do something with var 
}

Wat anders zou moeten worden geschreven

var = GetNext();
while( var )
{
 ...do something
 var = GetNext();
}

Antwoord 2, autoriteit 29%

Ik vind het het handigst in reeksen acties waarbij vaak fouten worden gedetecteerd, enz.

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
}

Het alternatief (de opdracht niet gebruiken in de voorwaarde) is:

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
        }
    }
}

Bij langdurige foutcontrole kan het alternatief van de RHS van de pagina aflopen, terwijl de toewijzing-in-voorwaardelijke versie dat niet doet.

De foutcontroles kunnen ook ‘actions’ zijn — first_action(), second_action(), third_action()— natuurlijk liever dan alleen cheques. Dat wil zeggen, het kunnen gecontroleerde stappen zijn in het proces dat de functie beheert. (Meestal in de code waar ik mee werk, zijn de functies in de trant van pre-condition checks, of geheugentoewijzingen die nodig zijn om de functie te laten werken, of in soortgelijke lijnen).


Antwoord 3, autoriteit 25%

Het is handiger als je een functie aanroept:

if (n = foo())
{
    /* foo returned a non-zero value, do something with the return value */
} else {
    /* foo returned zero, do something else */
}

Natuurlijk, je kunt gewoon de n = foo(); op een aparte verklaring dan if (n), maar ik denk dat het bovenstaande een redelijk leesbaar idioom is.


Antwoord 4, autoriteit 20%

Het kan handig zijn als je een functie aanroept die ofwel data teruggeeft om aan te werken of een vlag om een ​​fout aan te geven (of dat je klaar bent).

Zoiets als:

while ((c = getchar()) != EOF) {
    // process the character
}
// end of file reached...

Persoonlijk is het een idioom waar ik niet zo dol op ben, maar soms is het alternatief lelijker.


Antwoord 5, autoriteit 12%

GCC kan u helpen detecteren (met -Wall) als u onbedoeld een opdracht als waarheidswaarde probeert te gebruiken, voor het geval het u aanbeveelt om te schrijven

if ((n = foo())) {
   ...
}

D.w.z. gebruik extra haakjes om aan te geven dat dit echt is wat je wilt.


Antwoord 6, autoriteit 7%

Het idioom is handiger wanneer u een while-lus schrijft in plaats van een if-instructie. Voor een if-statement kun je het opsplitsen zoals je beschrijft. Maar zonder deze constructie zou je ofwel jezelf moeten herhalen:

c = getchar();
while (c != EOF) {
    // ...
    c = getchar();
}

of gebruik een anderhalve lus-structuur:

while (true) {
    c = getchar();
    if (c == EOF) break;
    // ...
}

Normaal gesproken zou ik de voorkeur geven aan de vorm van anderhalve lus.


Antwoord 7, autoriteit 3%

Het korte antwoord is dat Expression-georiënteerdeprogrammeertalen beknoptere code mogelijk maken. Ze dwingen je niet om commando’s van zoekopdrachten te scheiden.


Antwoord 8, autoriteit 2%

In PHP is het bijvoorbeeld handig om door SQL-databaseresultaten te bladeren:

while ($row = mysql_fetch_assoc($result)) {
    // Display row
}

Dit ziet er veel beter uit dan:

$row = mysql_fetch_assoc($result);
while ($row) {
    // Display row
    $row = mysql_fetch_assoc($result);
}

Antwoord 9, autoriteit 2%

Het andere voordeel komt tijdens het gebruik van gdb.
In de volgende code is de foutcode niet bekend als we een enkele stap zouden zetten.

while (checkstatus() != -1) {
    // process
}

Liever

while (true) {
    int error = checkstatus();
    if (error != -1)
        // process
    else
        //fail
}

Nu kunnen we tijdens een enkele stap weten wat de retourfoutcode was van de checkstatus().


Antwoord 10

Ik vind het erg handig met functies die optionals retourneren (boost::optionalof std::optionalin C++17):

std::optional<int> maybe_int(); // function maybe returns an int
if (auto i = maybe_int()) {
    use_int(*i);
}

Dit verkleint de reikwijdte van mijn variabele, maakt de code compacter en belemmert de leesbaarheid niet (vind ik).

Hetzelfde met verwijzingen:

int* ptr_int();
if (int* i = ptr_int()) {
    use_int(*i);
}

Antwoord 11

Ik heb het vandaag gebruikt tijdens het programmeren in Arduino (C-taal).

Geval

Ik heb een zender en een ontvanger.
De zender wil de gegevens verzenden totdat deze zijn ontvangen. Ik wil een vlag instellen wanneer het proces is voltooid.

while (!(newtork_joined = transmitter.send(data))) {
Serial.println("Not Joined");
}

Hier:

  • “transmitter.send” – retourneert true wanneer de verzending is gelukt
  • “newtork_joined ” – is de vlag die ik instel als het lukt

Resultaat

  1. Als de verzending niet succesvol is, wordt de vlag niet gezet, terwijl de lus waar is, blijft het uitvoeren

  2. Als dit lukt, wordt de vlag ingesteld, terwijl de lus onwaar is, sluiten we af

Is niet mooi?


Antwoord 12

De reden is:

  1. Prestatieverbetering (soms)

  2. Minder code (altijd)

Neem een ​​voorbeeld: er is een methode someMethod()en in een ifvoorwaarde wil je controleren of de retourwaarde van de methode null. Zo niet, dan ga je de retourwaarde opnieuw gebruiken.

If(null != someMethod()){
    String s = someMethod();
    ......
    //Use s
}

Het zal de prestaties belemmeren omdat je dezelfde methode twee keer aanroept. Gebruik in plaats daarvan:

String s;
If(null != (s = someMethod())) {
    ......
    //Use s
}

Other episodes