Wstęp do programowania w języku C/Instrukcja if

From Studia Informatyczne

Wstęp

Z instrukcją warunkową if (po polsku czytaj "jeśli") mieliśmy już do czynienia podczas rozwiązywania równania kwadratowego. W języku C instrukcja 'if występuje w dwóch postaciach:

  1. if ( wyrażenie ) instrukcja
  2. if ( wyrażenie ) instrukcja1 else instrukcja2

Oto kilka przykładów wykorzystania instrukcji if.

1. Zamiana wartości zmiennych całkowitych a, b tak, żeby wartość a była nie większa od wartości b.

if ( a > b ){
  int c;
  c = a; a = b; b = c;
}

Ciąg instrukcji ujęty w nawiasy klamrowe {, } nazywamy instrukcją złożoną

2. Zamiana wartości x na |x|.

if ( x < 0 ) x = -x;

3. Obliczanie podatku dochodowego.

#include <stdio.h>
 
main()
{
  long int podstawa;
  double podatek;
 
  printf("Podstawa obliczenia podatku w zl < ");
  scanf("%d", &podstawa);
 
  if ( podstawa <= 20868 ){
    podatek = 0.2 * podstawa - 278.20;
    if ( podatek < 0 ) podatek = 0;
  }
 
  if ( (podstawa > 20868) && (podstawa <= 41736) )
    podatek = 3895.40 + 0.32 * (podstawa - 20868);
 
  if ( podstawa > 41736 )
    podatek = 10573.16 + 0.44 * (podstawa - 41736);
 
  printf("Podatek = %10.2f\n", podatek);
 
  return 0;
}

Wykorzystanie else

Następny program robi to samo, ale został zapisany z wykorzystaniem else.

#include <stdio.h>
 
main()
{
  long int podstawa;
  double podatek;
 
  printf("Podstawa obliczenia podatku w zl < ");
  scanf("%d", &podstawa);
 
  if ( podstawa <= 20868 ){
    podatek = 0.2 * podstawa - 278.20;
    if ( podatek < 0 ) podatek = 0;
  }
  else if (podstawa <= 41736)
    podatek = 3895.40 + 0.32 * (podstawa - 20868);
  else
    podatek = 10573.16 + 0.44 * (podstawa - 41736);
 
  printf("Podatek = %10.2f\n", podatek);
 
  return 0;
}

W ostatnim przykładzie zastosowaliśmy tzw. kaskadową instrukcję if, która ogólnie ma postać:

if (warunek) instrukcja
else if (warunek) instrukcja
...
else if (warunek) instrukcja
else (warunek) instrukcja

Używając "zagnieżdzonej" instrukcji if trzeba pamiętać, że else odnosi się zawsze do najbliższego if. W poniższym przykładzie wypisywanie informacji o błędzie znajduje się nie tam, gdzie powinno.

if ( x != 0 )
  if ( y != 0 )
    wynik = y/x;
else printf("Blad: x = 0\n");

Prawidłowy zapis tego fragmentu programu powinien wyglądać następująco:

if ( x != 0 ){
  if ( y != 0 )
    wynik = y/x;
}
else printf("Blad: x = 0\n");

Przykładowe zadanie

Rozważmy następujące zadanie:

W kartezjańskim układzie współrzędnych dane są dwa prostokąty A, B o bokach równoległych do osi układu. Sprawdź, czy przecięcie tych prostokątów jest prostokątem, a jeśli odpowiedź jest pozytywna znajdź ten prostokąt.

Żeby powyższe zadanie rozwiązać na komputerze musimy podać pełną jego specyfikację. W szczególności odpowiedzieć, co to znaczy dany jest prostokąt. Przyjmiemy, że prostokąt jest reprezentowany przez współrzędne jego dwóch wierzchołków: dolnego-lewego i górnego-prawego. Dla prostokąta R będziemy je oznaczali, odpowiednio, L_R=(a_R,b_R) i P_R=(c_R,d_R). Zauważmy, że liczby a_R, b_R, c_R, d_R muszą spełniać nierówności a_R < c_R i b_R < d_R. Oto pełna specyfikacja naszego zadania:

Wejście

Pierwszy wiersz: cztery liczby rzeczywiste (z zakresu double) oddzielone pojedynczymi odstępami - dwie pierwsze z nich to współrzędne dolnego-lewego rogu prostokąta A, natomiast dwie ostatnie, to współrzędne górnego-prawego rogu tego prostokąta.

Drugi wiersz: cztery liczby rzeczywiste (z zakresu double) oddzielone pojedynczymi odstępami - dwie pierwsze z nich to współrzędne dolnego-lewego rogu prostokąta B, natomiast dwie ostatnie to współrzędne górnego-prawego rogu tego prostokąta.

Wyjście Jedno słowo "BRAK", jeżeli przecięcie A i B nie jest prostokątem, i cztery liczby rzeczywiste oddzielone pojedynczymi odstępami - współrzędne wierzchołków wynikowego prostokąta, odpowiednio, dolnego-lewego i górnego-prawego.

Oto program rozwiązujący powyższe zadanie zgodnie ze specyfikacją.

#include <stdio.h>
 
main()
{
  double a_A, b_A, c_A, d_A, /* prostokat A */
         a_B, b_B, c_B, d_B, /* prostokat B */
         a_C, b_C, c_C, d_C; /* prostokat A && B */
 
 
  printf("Prostokat A : ");
  scanf("%lf %lf %lf %lf", &a_A, &b_A, &c_A, &d_A);
 
  printf("Prostokat B : ");
  scanf("%lf %lf %lf %lf", &a_B, &b_B, &c_B, &d_B);
 
  /* Obliczanie wspolrzednych
     dolnego-lewego rogu prostokata C
     a_C = Max(a_A, a_B); b_C = Max(b_A, b_B); */
  if ( a_A >= a_B )
    a_C = a_A;
  else
    a_C = a_B;
  if ( b_A >= b_B )
    b_C = b_A;
  else
    b_C = b_B;
 
  /* Obliczanie wspolrzednych gornego-prawego
     rogu prostokata C:
     c_C = Min(c_A, c_B); d_C = Max(d_A, d_B); */
  if ( c_A <= c_B )
    c_C = c_A;
  else
    c_C = c_B;
  if ( d_A <= d_B )
    d_C = d_A;
  else
    d_C = d_B;
 
  /* Wynik. */
  if ( (a_C < c_C) && (b_C < d_C) ){
    printf("Wspolrzedne rogow prostokata ");
    printf(Ą && B: %.2f %.2f %.2f %.2f\n",
                     a_C, b_C, c_C, d_C);
  }
  else
    printf("BRAK.\n");
 
  return 0;
 
}

Powyższy program można zapisać za pomocą wyrażeń warunkowych postaci:

wyr1 ? wyr2 : wyr3

Wyrażenie takie przyjmuje wartość wyr3 jeśli wyr1 == 0, a wyr2 w przeciwnym przypadku.

#include <stdio.h>
 
main()
{
  double a_A, b_A, c_A, d_A, /* prostokat A */
         a_B, b_B, c_B, d_B, /* prostokat B */
         a_C, b_C, c_C, d_C; /* prostokat A && B */
 
 
  printf("Prostokat A : ");
  scanf("%lf %lf %lf %lf", &a_A, &b_A, &c_A, &d_A);
 
  printf("Prostokat B : ");
  scanf("%lf %lf %lf %lf", &a_B, &b_B, &c_B, &d_B);
 
  /* Obliczanie współrzędnych
     dolnego-lewego rogu prostokata C
     a_C = Max(a_A, a_B); b_C = Max(b_A, b_B); */
  a_C = ( a_A >= a_B ? a_A : a_B );
  b_C = ( b_A >= b_B ? b_A : b_B );
 
  /* Obliczanie współrzędnych gornego-prawego
     rogu prostokata C:
     c_C = Min(c_A, c_B); d_C = Max(d_A, d_B); */
  c_C = ( c_A <= c_B ? c_A : c_B );
  d_C = ( d_A <= d_B ? d_A : d_B );
 
  /* Wynik. */
  if ( (a_C < c_C) && (b_C < d_C) ){
    printf("Wspolrzedne rogow prostokata ");
    printf(Ą && B: %.2f %.2f %.2f %.2f\n",
                     a_C, b_C, c_C, d_C);
  }
  else
    printf("BRAK.\n");
 
  return 0;
 
}

Najbardziej czytelny i samodokumentujący się program uzyskamy używając makrodefinicji.

#include <stdio.h>
 
#define Max(x,y) ( ( x ) >= ( y ) ? ( x ) : ( y ) )
#define Min(x,y) ( ( x ) <= ( y ) ? ( x ) : ( y ) )
 
 
main()
{
  double a_A, b_A, c_A, d_A, /* prostokat A */
         a_B, b_B, c_B, d_B, /* prostokat B */
         a_C, b_C, c_C, d_C; /* prostokat A && B */
 
 
  printf("Prostokat A : ");
  scanf("%lf %lf %lf %lf", &a_A, &b_A, &c_A, &d_A);
 
  printf("Prostokat B : ");
  scanf("%lf %lf %lf %lf", &a_B, &b_B, &c_B, &d_B);
 
  /* Obliczanie współrzędnych
     dolnego-lewego rogu prostokata C
     a_C = Max(a_A, a_B); b_C = Max(b_A, b_B); */
  a_C = Max(a_A, a_B);
  b_C = Max(b_A, b_B);
 
  /* Obliczanie współrzędnych gornego-prawego
     rogu prostokata C:
     c_C = Min(c_A, c_B); d_C = Max(d_A, d_B); */
  c_C = Min(c_A, c_B);
  d_C = Min(d_A, d_B);
 
  /* Wynik. */
  if ( (a_C < c_C) && (b_C < d_C) ){
    printf("Wspolrzedne rogow prostokata ");
    printf(Ą && B: %.2f %.2f %.2f %.2f\n",
                     a_C, b_C, c_C, d_C);
  }
  else
    printf("BRAK.\n");
 
  return 0;
 
}