Μετάβαση στο περιεχόμενο
Topos Uranos

Περίληψη

Μια αριθμητική έκφραση δεν υπολογίζεται από αριστερά προς τα δεξιά, όπως διαβάζεται, αλλά σύμφωνα με μια κρυμμένη δομή, το δέντρο της, που καθορίζουν η προτεραιότητα των τελεστών, η προσεταιριστικότητά τους και οι παρενθέσεις· και σε κάθε κόμβο αυτού του δέντρου ο τύπος των τελεσταίων αποφασίζει ποια πράξη γίνεται, ώστε το 7 / 2 κάνει 3 και το 7 / 2.0 κάνει 3.5. Αυτό το μάθημα μελετά τους πέντε αριθμητικούς τελεστές της C++ με ακέραιους και με πραγματικούς· την ακέραια διαίρεση και το υπόλοιπο, που από τη C++11 κάνουν αποκοπή προς το μηδέν, από όπου έπεται ότι το υπόλοιπο παίρνει το πρόσημο του διαιρετέου και διαφέρει από το υπόλοιπο της ευκλείδειας διαίρεσης όταν ο διαιρετέος είναι αρνητικός· τον τρόπο να βρεθεί το ευκλείδειο υπόλοιπο· το δέντρο μιας έκφρασης· τον τύπο του αποτελέσματος όταν οι τελεσταίοι είναι διαφορετικών τύπων, και τους δύο τρόπους με τους οποίους μια ακέραια αριθμητική έκφραση χάνει το νόημά της: τη διαίρεση με το μηδέν και την υπερχείλιση σε έναν ενδιάμεσο υπολογισμό.

Μαθησιακοί στόχοι

  1. Να υπολογίζεται το πηλίκο και το υπόλοιπο της ακέραιας διαίρεσης στη C++, και με αρνητικούς τελεσταίους, και να συνδέονται με το πηλίκο και το υπόλοιπο της ευκλείδειας διαίρεσης.
  2. Να σχεδιάζεται το δέντρο μιας αριθμητικής έκφρασης σύμφωνα με την προτεραιότητα και την προσεταιριστικότητα, και να υπολογίζεται η τιμή της.
  3. Να προβλέπεται ο τύπος του αποτελέσματος μιας πράξης ανάμεσα σε τελεσταίους διαφορετικών τύπων.
  4. Να χρησιμοποιούνται η ακέραια διαίρεση και το υπόλοιπο για την ανάλυση ποσοτήτων: τα ψηφία ενός αριθμού, μια διάρκεια σε ώρες και λεπτά, μια ημέρα της εβδομάδας.

Οι αριθμητικοί τελεστές

Η C++ έχει πέντε δυαδικούς αριθμητικούς τελεστές: την πρόσθεση +, την αφαίρεση -, τον πολλαπλασιασμό *, τη διαίρεση / και το υπόλοιπο %· έχει επιπλέον το μοναδιαίο πλην, που αλλάζει το πρόσημο του μοναδικού τελεσταίου του, όπως στο -x, και ένα μοναδιαίο συν, +x, που τον αφήνει όπως είναι. Οι τέσσερις πρώτοι εφαρμόζονται σε ακέραιους και σε πραγματικούς· το υπόλοιπο, μόνο σε ακέραιους. Ωστόσο, η ίδια γραφή δεν δηλώνει την ίδια πράξη σε όλες τις περιπτώσεις: αν οι δύο τελεσταίοι του / είναι ακέραιοι, η διαίρεση είναι ακέραια και το αποτέλεσμά της είναι ακέραιος, το πηλίκο χωρίς το κλασματικό μέρος· αν κάποιος είναι πραγματικός, η διαίρεση είναι πραγματική. Το μάθημα Χαρακτήρες, λογικές τιμές, μετατροπές και σταθερές έδειξε την πιο ορατή συνέπεια αυτού του κανόνα, ότι το double r{7 / 2}; αποθηκεύει 3: η διαίρεση έγινε ανάμεσα σε ακέραιους πριν το αποτέλεσμα μετατραπεί σε πραγματικό.

ΠαράδειγμαΟι πέντε τελεστές με δύο ακέραιους

Το πρόγραμμα εφαρμόζει τους πέντε τελεστές στο 17 και στο 5, και επαναλαμβάνει τη διαίρεση με πραγματικό διαιρετέο.

Πρόγραμμα σε C++
#include <print>​int main(){    const int a{17};    const int b{5};    std::println("{} + {} = {}", a, b, a + b);    std::println("{} - {} = {}", a, b, a - b);    std::println("{} * {} = {}", a, b, a * b);    std::println("{} / {} = {}", a, b, a / b);    std::println("{} % {} = {}", a, b, a % b);    const double x{17.0};    std::println("{} / {} = {}", x, b, x / b);}
Έξοδος
17 + 5 = 2217 - 5 = 1217 * 5 = 8517 / 5 = 317 % 5 = 217 / 5 = 3.4

Το 17 διά 5 δίνει 3 και περισσεύουν 2: είναι το πηλίκο και το υπόλοιπο όταν μοιράζονται 17 αντικείμενα σε ομάδες των 5. Η τελευταία γραμμή διαιρεί έναν πραγματικό με έναν ακέραιο και παίρνει 3.4. Πρέπει να σημειωθεί ότι η std::println γράφει τον πραγματικό 17.0 ως «17»: η κενή θέση αντικατάστασης γράφει τη συντομότερη αναπαράσταση της τιμής, ώστε αυτό που γράφεται δεν αποκαλύπτει τον τύπο· για να φανεί, ζητούνται δεκαδικά ψηφία με {:.1f}.

Ο τελεστής % δεν δέχεται πραγματικούς. Η γραφή 7.5 % 2 δεν είναι λογικό σφάλμα που το πρόγραμμα ανακαλύπτει όταν εκτελείται, αλλά σφάλμα μεταγλώττισης: ο μεταγλωττιστής λέει ότι οι τελεσταίοι των τύπων double και int δεν είναι έγκυροι για τον τελεστή.

Πρόγραμμα σε C++
#include <print>​int main(){    std::println("{}", 7.5 % 2);}
Μηνύματα σφάλματος του μεταγλωττιστή
main.cpp: In function ‘int main()’:main.cpp:5:28: error: invalid operands of types ‘double’ and ‘int’ to binary ‘operator%’    5 |     std::println("{}", 7.5 % 2);      |                        ~~~ ^ ~

Το υπόλοιπο μιας πραγματικής διαίρεσης υπάρχει, και το υπολογίζει η συνάρτηση std::fmod της κεφαλίδας <cmath>, που θα μελετηθεί στο μάθημα Bit και μαθηματική βιβλιοθήκη, μαζί με τη δύναμη: η C++ δεν έχει τελεστή δύναμης, και το 2 ^ 3 δεν κάνει 8, αλλά κάτι άλλο που θα εξηγηθεί εκεί.