Skip to content

Εσπευσμένη αποτίμηση λογικών εκφράσεων στη C

Υπάρχει περίπτωση μια σύνθετη λογική έκφραση να μπορεί να αποτιμηθεί χωρίς να εξεταστούν όλοι οι όροι της. Για παράδειγμα αν πολλές λογικές εκφράσεις συνδέονται με τον τελεστή && τότε αν ξεκινώντας από αριστερά εντοπιστεί μια λογική έκφραση που είναι ψευδής, δεν χρειάζεται να αποτιμηθούν οι υπόλοιπες εκφράσεις καθώς γνωρίζουμε ότι η σύνθετη έκφραση θα είναι ψευδής. Ομοίως, αν μια σύνθετη λογική έκφραση αποτελείται από λογικές εκφράσεις που συνδέονται με το || τότε αν κατά την αποτίμηση της σύνθετης έκφρασης εντοπιστεί μια συνθήκη που είναι αληθής, τότε οι συνθήκες που απομένουν δεν αποτιμώνται καθώς η τιμή τους δεν πρόκειται να επηρεάσει την αληθή τιμή της σύνθετης λογικής έκφρασης που θα είναι σε κάθε περίπτωση αληθής. Ο τρόπος αυτός αποτίμησης σύνθετων λογικών εκφράσεων στη C αναφέρεται και ως short circuit (βραχυκύκλωμα) και μερικές φορές μπορεί να έχει μη επιθυμητά αποτελέσματα. Ένα παράδειγμα δίνεται στη συνέχεια, όπου παρά το ότι υπάρχει στη γραμμή 6 πράξη διαίρεσης ακεραίου με μηδέν, που θα δημιουργούσε σφάλμα εκτέλεσης, ο κώδικας ολοκληρώνει την εκτέλεσή του κανονικά καθώς η αποτίμηση της σύνθετης λογικής έκφρασης γίνεται χωρίς να αποτιμάται ποτέ η έκφραση (10/x) > 1 μιας και η έκφραση x == 0 είναι αληθής.

short_circuit1.c
1
2
3
4
5
6
7
8
#include <stdbool.h>
#include <stdio.h>
int main(void) {
  int x = 0;
  bool f = (x == 0 || (10 / x) > 1);
  printf("The logic expression's value is %d\n", f);
  return 0;
}

Η έξοδος της εκτέλεσης του προγράμματος είναι:

The logic expression's value is 1

Ένα επιπλέον παράδειγμα

short_circuit2.c
#include <stdio.h>
#include <time.h>
#include <unistd.h>

void print(char* msg) {
  time_t now;
  struct tm* local;
  char buffer[80];
  time(&now);
  local = localtime(&now);
  strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", local);
  printf("%s printed at %s\n", msg, buffer);
}

int fun1() {
  print("fun1 started");
  sleep(5);
  print("fun1 finished");
  return 0;
}

int fun2() {
  print("fun2 started");
  sleep(5);
  print("fun2 finished");
  return 0;
}

int main() {
  print("scenario 1");
  int b1 = fun1();
  int b2 = fun2();
  if (b1 && b2) {
    print("hello");
  }

  print("\nscenario 2 (short circuit activated!)");
  if (fun1() && fun2()) {
    print("hello");
  }
}

Ένα παράδειγμα εξόδου της εκτέλεσης του προγράμματος είναι:

scenario 1 printed at 2025-02-17 18:09:55
fun1 started printed at 2025-02-17 18:09:55
fun1 finished printed at 2025-02-17 18:10:00
fun2 started printed at 2025-02-17 18:10:00
fun2 finished printed at 2025-02-17 18:10:05

scenario 2 (short circuit activated!) printed at 2025-02-17 18:10:05
fun1 started printed at 2025-02-17 18:10:05
fun1 finished printed at 2025-02-17 18:10:10