Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'Kontrolstrukturer
6.  Logiske udtryk

Logiske udtryk bruges til at styre udvælgelse og gentagelse. Derfor er det vigtigt at vi har god styr på logiske udtryk. Dette vil vi få i dette afsnit.

6.1 Logiske udtryk6.3 Short Circuit evaluering
6.2 Sandhedstabeller6.4 Short Circuit evaluering: eksempler
 

6.1.  Logiske udtryk
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Logiske udtryk kan naturligt sammenlignes med aritmetiske udtryk. Aritmetiske udtryk beregnes til talværdier. Logiske udtryk beregnes til sandhedsværdier, enten sand eller falsk (true eller false på engelsk). På samme måde som vi har set aritmetiske operatorer vil i dette afsnit studere logiske operatorer, som returnerer sandhedsværdier.

Vi skal vænne os til at håndtere sandhedsværdier på samme måde som vi håndterer tal, tegn, mv. Vi kan putte sandhedsværdier i variable, vi kan sammenligne dem mv. For en del af jer tager det måske lidt tid inden I finder den rette og naturlige melodi for håndteringen af sandhedsværdier.

Et logisk udtryk beregnes til en værdi i datatypen boolean.

Datatypen boolean indeholder værdierne true og false.

Her følger en række eksempler på logiske udtryk, som alle anvender heltalsvariablen n. Eksemplerne er vist inden for rammerne af et komplet C program i program 6.2.

1
2
3
4
5
6
7
8
  int n = 6;
  
  n == 5
  n >= 5
  n != 5
  n >= 5 && n < 10
  !(n >= 5 && n < 10)
  n < 5 || n >= 10
Program 6.1    Et uddrag af et C program med logiske udtryk.

Først tester vi om n er lig med 5. == er altså en lighedoperator, som her returnerer false, idet n har værdien 6. Bemærk den afgørende forskel på assignment operatoren = og lighedsoperatoren ==. I anden linie tester vi om n er større end eller lig med 5. Dette er sandt. I tredje linie tester vi om n er forskellig fra 5. Dette er også sandt. I fjerde line tester vi om n er større eller lig med 5 og mindre end 10. Bemærk && svarer til 'logisk and'. (Se afsnit 6.2). Værdien er true igen. Udråbstegnet foran det tilsvarende udtryk betyder 'not', og det negerer altså værdien true til false. Det sidste logiske udtryk fortæller hvorvidt n er mindre end 5 eller større eller lig med 10. Når n stadig er 6 er dette naturligvis falsk. || betyder altså 'logisk eller'.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

int main(void) {

  int n = 6, b;

  printf("%d\n", n == 5);

  if (n >= 5) printf("stor\n"); else printf("lille\n");

  b = n != 5; printf("%d\n", b);

  while (n >= 5 && n < 10) n++;
  printf("%d\n", n);

  if ( !(n >= 5 && n < 10) == (n < 5 || n >= 10))
    printf("OK\n"); 
  else printf("Problems\n");
  
  return 0;
}
Program 6.2    De boolske udtryk vist i realistiske sammenhænge i et C program.

Nedenstående er en vigtig detalje i C. Nul står for false, og ikke-nulværdier står alle for true.

I C repræsenteres false af en nulværdi, og true af en vilkårlig ikke-nulværdi

 

6.2.  Sandhedstabeller
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Nu hvor vi er igang med at diskutere logiske udtryk benytter vi lejligheden til præcise definitioner af negering (not), konjunktion (and) og disjunktion (or) via sandhedstabellerne i hhv. tabel 6.1, tabel 6.2 og tabel 6.3. Negering håndteres af ! operatoren i C. Tilsvarende hedder and operatoren && i C, og or operatoren hedder ||.

Da der kun findes to forskellige sandhedsværdier er det let at tabellægge alle forskellige muligheder for input og output af de nævnte operatorer. Bemærk her forskellen til heltal. Da der findes uendelig mange forskellige heltalsværdier vil tilsvarende definitioner af +, -, * og / være umulig.

A !A
true false
false true
Tabel 6.1    Sandhedstabel for not operatoren

A B A && B A || B
true true true true
true false false true
false true false true
false false false false
Tabel 6.2    Sandhedstabel for and operatoren

A B !(A && B) !A || !B
true true false false
true false true true
false true true true
false false true true
Tabel 6.3    Sandhedstabel for or operatoren

Bemærk her at tabel 6.3 faktisk beviser DeMorgans boolske lov, som på et mere matematisk sprog siger at

I slide materialet viser vi en særlig udgave af operatorprioriteringstabellen i C, hvor de logiske og de sammenlignende operatorer er fremhævet. Se slide siden.

 

6.3.  Short Circuit evaluering
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Vi vil nu beskæftige os med nogle binære, logiske operatorer, som under nogle omstændigheder ikke vil beregne værdien af den højre operand.

Direkte oversat 'kortsluttet beregning'

Short circuit evaluering betegner en beregning hvor visse operander ikke evalueres, idet deres værdi er uden betydning for resultatet

  • x && y

    • y beregnes kun hvis x er true

  • x || y

    • y beregnes kun hvis x er false

 

6.4.  Short Circuit evaluering: eksempler
Indhold   Op Forrige Næste   Slide Aggregerede slides    Stikord Programindeks Opgaveindeks 

Vi ser først på et eksempel, som er ganske kunstig, men dog illustrativ. Dernæst, i program 6.6 følger et 'real life' eksempel.

Vi viser eksempler på C programmer med short circuit evaluering

Herunder ses en række assignment operatorer som indgår i logiske udtryk. Dette kan lade sig gøre i C idet assignment operatorer returnerer en værdi, ligesom alle andre operatorer. Dette diskuterede vi i kapitel 3. En anden essentiel observation for nedenstående er at tallet nul spiller rollen som sandhedsværdien false, og at andre tal spiller rollen som true. Dette blev diskuteret i afsnit 6.1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>

int main(void) {

  int i = 0, j = 0;

  (i = 1) && (j = 2);
  printf("%d %d\n", i, j);

  (i = 0) && (j = 3);
  printf("%d %d\n", i, j);

  i = 0 || (j = 4);     
  printf("%d %d\n", i, j); 

  (i = 2) || (j = 5);
  printf("%d %d\n", i, j);

  return 0;
}
Program 6.3    Short circuit beregning i kombination med assignments.

De to første assignments udføres begge, idet værdien af den første er 1 (true). Af de to næste assignment udføres kun det første. Årsagen er at i assignes til 0, som er false, hvilket forårsager undertrykkelse af beregningen af højre operand af &&. Det næste assignment skal fortolkes som i = (0 || (j = 4)). Husk igen af 0 er false. Højre operand af || skal derfor beregnes, jf. reglerne fra afsnit 6.3. Endelig gennemføres assignmentet til j ikke i sidste røde linie, idet venstre operand beregnes til 2 (true).

Med ovenstående observationer er program 6.4 ækvivalent med program 6.3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>

int main(void) {

  int i = 0, j = 0;

  (i = 1) && (j = 2);
  printf("%d %d\n", i, j);

  (i = 0);
  printf("%d %d\n", i, j);

  i = 0 || (j = 4);     
  printf("%d %d\n", i, j); 

  (i = 2);
  printf("%d %d\n", i, j);

  return 0;
}
Program 6.4    Et ækvivalent program.

Outputtet fra de to ovenstående (ækvivalente) programmer ses her:

1
2
3
4
1 2
0 2
1 4
2 4
Program 6.5    Output fra ovenstående programmer.

Og nu til et mere dagligdagsprogram. I den røde linie ses et logisk udtryk, hvor den venstre operator beskytter den højre. Det skal forstås således at sqrt(x) kun bliver beregnet hvis x er ikke-negativ. Dette er helt essentielt for at undgå en regnefejl i kvadratrodsfunktionen sqrt, som jo kun kan tage ikke-negative parametre.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <math.h>
#include <stdio.h>

double sqrt(double);

int main(void) {

  double x;

  printf("Enter a number: ");
  scanf("%lf", &x);

  if (x >= 0 && sqrt(x) <= 10)
    printf("x is positive, but less than or equal to 100.0\n");
  else printf("x is negative or greater than 100.0\n");

  return 0;
}
Program 6.6    Short circuit beregning som beskyttelse mod fejlberegning.

Prøvekør meget gerne programmet. Bemærk at på nogle C systemer skal der en ekstra option -lm på kompileren for at håndtere kvadratrodsfunktionen.

Genereret: Onsdag 7. Juli 2010, 15:10:23
Thema indholdsfortegnelse -- Tastaturgenvej: 'u'  Forrige tema i denne lektion -- Tastaturgenvej: 'p'  Næste slide i denne lektion -- Tastaturgenvej: 'n'