Sök…


if () Uttalanden

Ett av de enklaste sätten att kontrollera programflödet är genom att använda if val-uttalanden. Huruvida ett kodblock ska köras eller inte ska köras kan avgöras av detta uttalande.

Syntaxen för if markeringssats i C kan vara följande:

if(cond) 
{
  statement(s);  /*to be executed, on condition being true*/
}

Till exempel,

if (a > 1) {
    puts("a is larger than 1");
}

Där a > 1 är ett villkor som måste utvärderas till true för att utföra påståenden inuti if blocket. I detta exempel skrivs "a är större än 1" endast om a > 1 är sant.

if urvalssatser kan utelämna lindringarna { och } om det bara finns ett uttalande i blocket. Exemplet ovan kan skrivas om till

if (a > 1)
    puts("a is larger than 1");

Men för att utföra flera uttalanden inom block måste hängslen användas.

Villkoret för if kan inkludera flera uttryck. if kommer bara att utföra handlingen om slutresultatet av uttrycket är sant.

Till exempel

if ((a > 1) && (b > 1)) {
    puts("a is larger than 1");
    a++;
}

kör endast printf och a++ om både a och b är större än 1 .

if () ... annat uttalanden och syntax

Medan if utför en åtgärd när dess villkor utvärderas till true , if / else kan du ange de olika åtgärderna när villkoret är true och när villkoret är false .

Exempel:

if (a > 1)
    puts("a is larger than 1");
else 
    puts("a is not larger than 1");

Precis som if uttalandet, när blocket inom if eller else är bestående av endast ett uttalande, då hängslen kan utelämnas (men detta rekommenderas inte eftersom det lätt kan införa problem ofrivilligt). Men om det finns mer än ett uttalande i if eller else blocket, måste hängslen användas på det specifika blocket.

if (a > 1) 
{
    puts("a is larger than 1");
    a--;
}
else 
{
    puts("a is not larger than 1");
    a++;
}

switch () Uttalanden

switch uttalanden är användbara när du vill att ditt program ska göra många olika saker beroende på värdet på en viss testvariabel.

Ett exempel på användning av switch uttalande är så här:

int a = 1;

switch (a) {
case 1:
    puts("a is 1");
    break;
case 2:
    puts("a is 2");
    break;
default:
    puts("a is neither 1 nor 2");
    break;
}

Detta exempel motsvarar

int a = 1;

if (a == 1) {
    puts("a is 1");
} else if (a == 2) {
    puts("a is 2");
} else {
    puts("a is neither 1 nor 2");
}

Om värdet på a är en, då switch uttalande används a is 1 kommer att skrivas ut. Om värdet på a är 2 kommer a is 2 skrivas ut. Annars skrivs a is neither 1 nor 2 ut.

case n: används för att beskriva var exekveringsflödet hoppar in när värdet som skickas för att switch uttalande är n . n måste vara kompileringstidskonstant och samma n kan existera högst en gång i ett switch uttalande.

default: används för att beskriva det när värdet inte matchade något av valen för case n: Det är en bra praxis att inkludera ett default i varje switch-uttalande för att fånga oväntat beteende.

En break; uttalande krävs för att hoppa ut ur switch .

Obs: Om du av misstag glömmer att lägga till en break efter att ett case , kommer kompilatorn att anta att du tänker "falla igenom" och alla efterföljande ärendeuttalanden, om några, kommer att köras (såvida inte ett brytande uttalande finns i något av de efterföljande fallen), oavsett om den eller de efterföljande ärendeklarationerna matchar eller inte. Den här egenskapen används för att implementera Duff's Device . Detta beteende anses ofta vara en brist i specifikationen för C-språket.

Nedan är ett exempel som visar effekter av frånvaro av break; :

int a = 1;

switch (a) {
case 1:
case 2:
    puts("a is 1 or 2");
case 3:
    puts("a is 1, 2 or 3");
    break;
default:
    puts("a is neither 1, 2 nor 3");
    break;
}

När värdet på a är 1 eller 2, a is 1 or 2 och a is 1, 2 or 3 kommer båda att skrivas ut. När a är 3, skrivs endast a is 1, 2 or 3 . Annars skrivs a is neither 1, 2 nor 3 ut.

Observera att default inte är nödvändigt, särskilt när den uppsättning värden som du får i switch är klar och känd vid kompileringstiden.

Det bästa exemplet är att använda en switchenum .

enum msg_type { ACK, PING, ERROR };
void f(enum msg_type t)
{
  switch (t) {
  case ACK:
    // do nothing
    break;
  case PING:
    // do something
    break;
  case ERROR:
    // do something else
    break;
  }
}

Det finns flera fördelar med att göra detta:

  • de flesta kompilatorer kommer att rapportera en varning om du inte hanterar ett värde (detta skulle inte rapporteras om ett default var närvarande)
  • av samma anledning, om du lägger till ett nytt värde i enum , kommer du att meddelas alla platser där du har glömt att hantera det nya värdet (med ett default måste du manuellt utforska din kod som söker efter sådana fall)
  • Läsaren behöver inte ta reda på "vad som är doldt som default: ", vare sig det finns andra enum eller om det är ett skydd för "bara i fall". Och om det finns andra enum , använde kodaren avsiktligt default för dem eller finns det ett fel som introducerades när han lade till värdet?
  • hantering av varje enum gör koden självförklarande eftersom du inte kan gömma sig bakom ett vildkort, du måste uttryckligen hantera var och en av dem.

Ändå kan du inte hindra någon att skriva ond kod som:

enum msg_type t = (enum msg_type)666; // I'm evil

Således kan du lägga till en extra kontroll innan du växlar för att upptäcka den, om du verkligen behöver det.

void f(enum msg_type t)
{
   if (!is_msg_type_valid(t)) {
      // Handle this unlikely error
   }

   switch(t) { 
    // Same code than before
   }
}

om () ... annars Stege Kedja två eller fler om () ... annars uttalanden

Medan if ()... else uttalandet tillåter att bara definiera ett (standard) beteende som uppstår när villkoret inom if () inte är uppfylld, kedjar två eller fler if () ... else uttalanden gör det möjligt att definiera ett par mer beteende innan du går till den sista else grenen som fungerar som en "standard", om någon.

Exempel:

int a = ... /* initialise to some value. */

if (a >= 1) 
{
    printf("a is greater than or equals 1.\n");
} 
else if (a == 0) //we already know that a is smaller than 1
{
    printf("a equals 0.\n");
}
else /* a is smaller than 1 and not equals 0, hence: */
{ 
    printf("a is negative.\n");
}

Häckt om () ... annars VS om () .. annars Stege

Kapslade if()...else uttalanden tar mer körningstid (de är långsammare) i jämförelse med en if()...else stege eftersom de kapslade if()...else säger alla inre villkorliga uttalanden en gång de yttre villkorad if() -säkringen är uppfylld, medan if()..else stegen kommer att stoppa tillståndstestning när någon av if() eller else if() villkorliga uttalanden är sanna.

En if()...else stege:

#include <stdio.h>

int main(int argc, char *argv[])
{
  int a, b, c;
  printf("\nEnter Three numbers = ");
  scanf("%d%d%d", &a, &b, &c);
  if ((a < b) && (a < c))
  {
    printf("\na = %d is the smallest.", a);
  }
  else if ((b < a) && (b < c))
  {
    printf("\nb = %d is the smallest.", b);
  }
  else if ((c < a) && (c < b))
  {
    printf("\nc = %d is the smallest.", c);
  }
  else
  {
    printf("\nImprove your coding logic");
  }
  return 0;
}

Anses i allmänhet vara bättre än motsvarande kapslade if()...else :

#include <stdio.h>

int main(int argc, char *argv[])
{
  int a, b, c;
  printf("\nEnter Three numbers = ");
  scanf("%d%d%d", &a, &b, &c);
  if (a < b)
  {
    if (a < c)
      {
        printf("\na = %d is the smallest.", a);
      }
    else
      {
        printf("\nc = %d is the smallest.", c);
      }
  }
  else
  {
    if(b < c)
    {
      printf("\nb = %d is the smallest.", b);
    }
    else
    {
      printf("\nc = %d is the smallest.", c);
    }
  }
  return 0;  
}


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow