ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Μάθημα 8ο Τμήμα Διοίκησης Επιχειρήσεων Παλαιό ΕΠΔΟ α εξάμηνο Β. Φερεντίνος
ΔΟΜΕΣ (STRUCTURES) 161 Οι δομές ομαδοποιούν ένα σύνολο μεταβλητών (πιθανόν διαφορετικών τύπων) κάτω από ένα ενιαίο όνομα. Τα στοιχεία φοιτητών όπως όνομα, διεύθυνση, email, βαθμολογία κτλ, μπορούν να ομαδοποιηθούν σε μία δομή. Οι βασικές διαφορές των δομών από τους πίνακες: Ενώ όλα τα στοιχεία ενός πίνακα είναι του ίδιου τύπου, τα στοιχεία μιας δομής μπορούν να είναι διαφόρων τύπων τα στοιχεία ενός πίνακα προσδιορίζονται από τη θέση τους στον πίνακα, ενώ κάθε μέλος μιας δομής μπορεί να έχει το δικό του όνομα και να προσδιορίζεται με αυτό
Ορισμός δομής 162 struct <όνομα_δομής> { <τύπος_1ου_μέλους> <όνομα_1ου_μέλους>; <τύπος_2ου_μέλους> <όνομα_2ου_μέλους>;... <τύπος_v-ου_μέλους> <όνομα_v-ου_μέλους>; Δομή: σύνθετος τύπος μεταβλητής που μπορεί να εμπεριέχει πολλές απλές μεταβλητές, διαφόρων τύπων.
Παράδειγμα δομής (1) 163 Η δομή ενός σημείου στο επίπεδο, που εμπεριέχει δύο πραγματικές μεταβλητές x και y που αντιστοιχούν στις συντεταγμένες του σημείου: struct point { float x; float y;
Παράδειγμα δομής (2) 164 Ο ορισμός της δομής που προαναφέρθηκε αποτελεί τη δημιουργία ενός καλουπιού για τη δημιουργία συγκεκριμένων δομών του συγκεκριμένου τύπου. Η δήλωση struct ορίζει μόνο το περιεχόμενο της δομής και όχι κάποιο χώρο στη μνήμη. Η δημιουργία συγκεκριμένης δομής πραγματοποιείται με την εντολή: struct <όνομα_δομής> <όνομα_μεταβλητής_δομής>; struct point a, b; Η δήλωση αυτή ορίζει τις δομές a και b τύπου point. Είναι μια δήλωση συντακτικά ισοδύναμη με δηλώσεις του τύπου: int a, b;
Αρχικοποίηση και αναφορά σε μέλη δομής 165 Τα μέλη μιας δομής μπορούν να αρχικοποιηθούν κατά τη δήλωσή της. struct point p1 = {5.5, 2.5 Η αναφορά σε κάποιο συγκεκριμένο μέλος μιας δομής γίνεται με τη χρήση του τελεστή. ως εξής: <όνομα_μεταβλητής_δομής>.<όνομα_μέλους> για τη δομή p (δηλαδή, το σημείο p), struct point p; με τον τελεστή. μπορούν να πραγματοποιηθούν: απόδοση τιμών στις συντεταγμένες: p.x = 5.0; p.y = 3.5; εκτύπωση συντεταγμένων: printf("%f, %f", p.x, p.y); απόσταση από το σημείο (0, 0): float dist; dist = sqrt(p.x * p.x + p.y * p.y);
Συσχετίσεις 166 Δεν υπάρχει σύγχυση ονομάτων δομών και μελών, με ονόματα μεταβλητών ή μελών άλλων δομών: struct point { float x; float y; int point, x, y; struct joint { int x; int y; // δομή // μεταβλητές // δομή
Παράδειγμα 167 Μια δομή book για την καταχώρηση βιβλίων σε ένα βιβλιοπωλείο: struct book { char title[60]; char writer[30]; char isbn[17]; float price; // τιμή int code; // τίτλος // συγγραφέας // ISBN // κωδικός προϊόντος Δημιουργία μιας μεταβλητής-δομής τύπου book: struct book book1 = {"Το MATLAB στην Υπολογιστική Επιστήμη", "C.F. Van Loan, K.-Y. D. Fan", "978-960-973-200-0", 40.50, 1);
Σύνθετες (ένθετες) δομές (1) 168 Με δεδομένη τη δομή για σημεία : struct point { float x; float y; Μια δομή για ορθογώνια παραλληλόγραμμα θα μπορούσε να είναι η εξής: struct rect { struct point pt1; struct point pt2;
Σύνθετες (ένθετες) δομές (2) 169 Για ένα συγκεκριμένο ορθογώνιο : struct rect r1; η πρόσβαση στις συντεταγμένες (x,y) του κάθε σημείου του γίνεται ως εξής: r1.pt1.x = 2.5; r1.pt1.y = 3.0; r1.pt2.x = 10.2; r1.pt2.y = 8.5; Φυσικά, η δημιουργία του συγκεκριμένου ορθογωνίου θα μπορούσε να είχε γίνει και με την εντολή: struct rect r1 = {2.5, 3.0, 10.2, 8.5 όπου οι δύο πρώτες τιμές αφορούν τις μεταβλητές x και y της δομής pt1 και οι δύο τελευταίες τις μεταβλητές x και y της δομής pt2.
Δομές και Συναρτήσεις (1) 170 Οι δομές μπορούν να μεταβιβάζονται ως ορίσματα σε συναρτήσεις ή να επιστρέφονται από συναρτήσεις. Συνάρτηση που δημιουργεί δομή (τύπου point) και την επιστρέφει: struct point makepoint(float x, float y) { } struct point temp; temp.x = x; temp.y = y; return temp; Παράδειγμα χρήσης της: struct rect area; struct point middle; struct point makepoint(double, double);... area.pt1 = makepoint(0.0, 0.0); area.pt2 = makepoint(50.0, 50.0); middle = makepoint((area.pt1.x + area.pt2.x)/2, (area.pt1.x + area.pt2.x)/2);
Δομές και Συναρτήσεις (2) 171 Συνάρτηση που δέχεται δύο δομές και επιστρέφει νέα δομή (ουσιαστικά επιστρέφει το άθροισμα δύο δομών point, προσθέτοντας τις συντεταγμένες των δύο σημείων ): struct point addpoint(struct point p1, struct point p2) { p1.x += p2.x; p1.y += p2.y; return p1; } Οι δομές p1 και p2 περνούν με τιμή στη συνάρτηση, όπως όλα τα ορίσματα στη C.
Δομές και Συναρτήσεις (3) 172 Συνάρτηση που δέχεται δύο δομές διαφορετικού τύπου και επιστρέφει ακέραιο (ελέγχει εάν ένα σημείο βρίσκεται στο εσωτερικό ενός ορθογωνίου) int pt_in_rect(struct point p, struct rect r) { } return p.x > r.pt1.x && p.x < r.pt2.x && p.y > r.pt1.y && p.y < r.pt2.y;
Παράδειγμα 173 Ένα ολοκληρωμένο πρόγραμμα που ελέγχει εάν δύο δεδομένα σημεία βρίσκονται στο εσωτερικό ενός δεδομένου ορθογωνίου: include <stdio.h> // Ορισμοί δομών: struct point { float x; float y; struct rect { struct point pt1; struct point pt2; // Δήλωση της συνάρτησης: int pt_in_rect(struct point p, struct rect r); (συνεχίζεται)
174 Παράδειγμα // Η συνάρτηση main: void main() { struct rect r1 = {2, 3, 4, 5 // Η συνάρτηση pt_in_rect: int pt_in_rect(struct point p, struct rect r) { return p.x > r.pt1.x && p.x < r.pt2.x && p.y > r.pt1.y && p.y < r.pt2.y; } // Δημιουργία ενός ορθογωνίου struct point p1 = {3,4 // Δημιουργία του σημείου (3,4) struct point p2 = {0,1 // Δημιουργία του σημείου (0,1) int in1, in2; in1 = pt_in_rect(p1, r1); in2 = pt_in_rect(p2, r1); // Έλεγχος εάν τα σημεία είναι εσωτερικά στο r1 } printf("%d, %d", in1, in2); // Εκτύπωση των αποτελεσμάτων // (το "1" σημαίνει ότι βρίσκεται στο εσωτερικό, το "0" όχι) Το πρόγραμμα θα εκτυπώσει: 1, 0
Πίνακες Δομών (1) 175 Μπορούν να δημιουργηθούν πίνακες τα στοιχεία των οποίων να είναι δομές. Έστω οι δομές grades και student ως εξής: struct grades{ int c, cpp, java; struct student{ int am; char *name; struct grades v; Η δομή grades αναφέρεται στους βαθμούς τριών μαθημάτων (C, C++ και Java), ενώ η δομή student αναφέρεται στα στοιχεία ενός φοιτητή (αριθμό μητρώου, όνομα και βαθμούς στα συγκεκριμένα τρία μαθήματα).
Πίνακες Δομών (2) 176 Πλέον, μπορούμε να δημιουργήσουμε έναν πίνακα π.χ. 10 φοιτητών, ως εξής: struct student std[10]; Τα στοιχεία του πίνακα std είναι δομές τύπου student. Η αναφορά στα στοιχεία του πίνακα γίνεται πάλι με τον τελεστή. ως εξής: std[0].am = 999; std[0].name = "Όνομα 1"; std[0].v.c = 8; std[0].v.cpp = 7; std[0].v.java = 10; Αυτά αφορούν την απόδοση τιμών στα στοιχεία του πρώτου φοιτητή (στοιχείο του πίνακα με δείκτη 0).
Πίνακες Δομών (3) 177 Η δήλωση (ορισμός), δημιουργία και αρχικοποίηση των στοιχείων του πίνακα δομών θα μπορούσε να γίνει πιο σύντομα, σε ένα βήμα, ως εξής: struct student{ int am; char *name; struct grades v; } std[10] = { {999, "Όνομα 1", 8, 7, 10}, {888, "Όνομα 2", 6, 5, 3}...
Πίνακες Δομών (4) 178 Ή, εάν έχει ήδη ορισθεί ο τύπος της δομής student όπως πριν: struct student{ int am; char *name; struct grades v; θα μπορούσε απλά να συντομευθεί η δημιουργία και η αρχικοποίηση του πίνακα std: struct student std[10] = { {999, "Όνομα 1", 8, 7, 10}, {888, "Όνομα 2", 6, 5, 3}...