Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

Η παρουσίαση φορτώνεται. Παρακαλείστε να περιμένετε

Δομές στην C (επανάληψη)

Παρόμοιες παρουσιάσεις


Παρουσίαση με θέμα: "Δομές στην C (επανάληψη)"— Μεταγράφημα παρουσίασης:

1 Δομές στην C (επανάληψη)
Γλώσσα C & Unix Τμήμα Πληροφορικής, ΑΠΘ B’ εξάμηνο lpis.csd.auth.gr/curriculum/C+Unix/UNCL202.html

2 Σύνθετοι Τύποι Δεδομένων
structure (δομή): ομαδοποίηση πολλών μεταβλητών κάτω από ένα κοινό όνομα Π.χ. εγγραφή αρχείου Π.χ. γραμμή σε βάση δεδομένων union (ένωση): επιτρέπει το ίδιο μέρος της μνήμης να οριστεί ως δύο ή παραπάνω διαφορετικούς τύπους μεταβλητών enumeration (απαρίθμηση): λίστα συμβόλων typedef: δημιουργία νέων ονομάτων τύπων δεδομένων

3 Δομή (structure) Ομαδοποίηση πολλών μεταβλητών κάτω από ένα κοινό όνομα Κρατιούνται μαζί τα δεδομένα που σχετίζονται μεταξύ τους Η δήλωση μιας δομής ορίζει ένα πρότυπο Μπορεί να χρησιμοποιηθεί για τη δημιουργία μεταβλητών αυτού του προτύπου Οι μεταβλητές που απαρτίζουν μια δομή λέγονται στοιχεία ή μέλη (members) της δομής Όλα τα στοιχεία μιας δομής πρέπει να σχετίζονται λογικά μεταξύ τους Π.χ. όνομα, επώνυμο και διεύθυνση ενός ατόμου

4 Δήλωση Δομής Δομή για την αναπαράσταση των στοιχείων ενός μαθητή
struct mathitis { char onoma[15]; char eponymo[25]; short int apousies; short int vathmos; }; Όνομα της δομής Δηλώσεις στοιχείων Πληροφορεί τον μεταγλωττιστή της C ότι ξεκινά η δήλωση μιας δομής (ή μιας μεταβλητής δομής).

5 Χρήση Δομής Ακόμα δεν έχει δημιουργηθεί καμία μεταβλητή
Το mathitis είναι ένας καινούριος τύπος δεδομένων Μπορεί να χρησιμοποιηθεί για τη δήλωση μεταβλητών αυτού του τύπου struct mathitis x1;

6 Ταυτόχρονη Δήλωση και Χρήση Δομής
Μπορούμε να δηλώσουμε μεταβλητές ταυτόχρονα με τη δήλωση μιας δομής struct mathitis { char onoma[15]; char eponymo[25]; unsigned short int apousies; unsigned short int vathmos; } x1, x2, x3;

7 Ανώνυμες Δομές Όταν δηλώνουμε μεταβλητές μαζί με τη δομή μπορούμε να μη δώσουμε όνομα στη δομή Όταν δεν πρόκειται να δηλώσουμε επιπλέον μεταβλητές αυτού του τύπου struct { char onoma[15]; char eponymo[25]; unsigned short int apousies; unsigned short int vathmos; } x1, x2, x3;

8 Προσπέλαση Στοιχείων Δομής
Τα στοιχεία μιας μεταβλητής δομής, μπορούν να προσπελαστούν με τον τελεστή τελεία “.” Γενική μορφή: struct_var_name.member_name Παράδειγμα: x1.apousies = 2; printf("%d", x1.apousies);

9 Σύνθετες Δομές struct mathitis { char onoma[15]; ...
struct date birthday; } x1; struct date { int day; int month; int year; }; Πρόσβαση στοιχείων «εσωτερικής» δομής x1.birthday.year;

10 Πίνακες από Δομές Η πιο συνηθισμένη χρήση των δομών, είναι σε πίνακες πολλών μεταβλητών δομής Για να δηλωθεί ένας πίνακας από δομές, πρέπει να δηλωθούν: η δομή, και μετά ένας πίνακας από αυτές τις δομές Παράδειγμα: struct mathitis m[100];

11 Πίνακες από Δομές – Προσπέλαση Στοιχείων
Για να προσπελαστεί ένα στοιχείο μέσα στον πίνακα πρέπει να χρησιμοποιηθεί ο αύξων αριθμός του στοιχείου στον πίνακα Π.χ. εκτύπωση ονόματος του τρίτου μαθητή: printf("%s", m[2].onoma);

12 Δομές και Συναρτήσεις Πέρασμα μεμονωμένου στοιχείου δομής ως παράμετρο σε συνάρτηση Πέρασμα ολόκληρης δομής Κλήση με τιμή Πέρασμα διεύθυνσης μνήμης δομής Κλήση με αναφορά

13 Στοιχεία Δομής ως Παράμετροι Συναρτήσεων
Οι μεταβλητές που αποτελούν τα στοιχεία μιας δομής μπορούν να δοθούν σε μια συνάρτηση ως τιμές ως δείκτες προς τη διεύθυνση τους Παράδειγμα δομής: struct paradeigma { char c; int i; float f; char s[10]; } x;

14 Παραδείγματα Κλήσης με Τιμή
struct paradeigma { char c; int i; float f; char s[10]; } x; func_v1(x.c); func_v2(x.i); func_v3(x.f); func_v4(x.s[2]);

15 Παραδείγματα Κλήσης με Αναφορά
ο τελεστής διεύθυνσης & τοποθετείται πριν από το όνομα της μεταβλητής δομής όχι πριν από την μεταβλητή του στοιχείου της δομής func_r1(&x.c); func_r2(&x.i); func_r3(&x.f); struct paradeigma { char c; int i; float f; char s[10]; } x;

16 Παραδείγματα Κλήσης με Αναφορά
Επειδή το όνομα ενός πίνακα χαρακτήρων είναι η διεύθυνση του πρώτου στοιχείου του πίνακα, παραλείπουμε τελείως τον τελεστή & func_r4(x.s); struct paradeigma { char c; int i; float f; char s[10]; } x;

17 Παραδείγματα Κλήσης με Αναφορά
Όταν θέλουμε να δώσουμε τη διεύθυνση κάποιου συγκεκριμένου στοιχείου του πίνακα (εκτός του πρώτου) τότε πρέπει να χρησιμοποιήσουμε τον τελεστή & func_r5(&x.s[2]); struct paradeigma { char c; int i; float f; char s[10]; } x;

18 Παραδείγματα Κλήσης με Αναφορά
func_r5((x.s)+2); Εναλλακτικά θα μπορούσε να είχε χρησιμοποιηθεί αριθμητική δεικτών struct paradeigma { char c; int i; float f; char s[10]; } x;

19 Κλήση Συνάρτησης με Τιμή μιας Ολόκληρης Δομής
Όταν μια μεταβλητή δομής δίνεται ως παράμετρος σε μια συνάρτηση, τότε γίνεται μια τυπική κλήση της συνάρτησης με τιμή. Οποιεσδήποτε αλλαγές γίνουν στα στοιχεία της μεταβλητής δομής μέσα στην συνάρτηση, δεν θα είναι μόνιμες.

20 Κλήση Συνάρτησης με Τιμή μιας Ολόκληρης Δομής
Ο τύπος της τυπικής παραμέτρου της συνάρτησης πρέπει να είναι ίδιος με τον τύπο της μεταβλητής-παραμέτρου Η δομή πρέπει να δηλωθεί ως καθολικός τύπος δεδομένων Το όνομα της δομής πρέπει να χρησιμοποιηθεί για τη δήλωση των τοπικών μεταβλητών δομής τυπικών παραμέτρων των συναρτήσεων

21 Κλήση Συνάρτησης με Τιμή μιας Ολόκληρης Δομής - Παράδειγμα
#include <stdio.h> struct test { int a, b; char ch; }; void main(void) { struct test x1; x1.a = 1000; f1(x1); } Καθολικός τύπος δεδομένων void f1(struct test p) { printf("%d", p.a); }

22 Κλήση Συνάρτησης με Αναφορά σε μία Ολόκληρη Δομή
Μπορούμε να περνάμε τη διεύθυνση μνήμης μιας μεταβλητής δομής ως παράμετρο σε συνάρτηση Μπορούμε να κάνουμε μόνιμες αλλαγές στα στοιχεία της μεταβλητής δομής μέσα στη συνάρτηση Δίνοντας τη διεύθυνση της μεταβλητής δομής στη μνήμη έχουμε κλήση της συνάρτησης με αναφορά Πλεονέκτημα

23 Κλήση Συνάρτησης με Αναφορά σε μία Ολόκληρη Δομή
Η εκτέλεση της συνάρτησης επιταχύνεται δραστικά Δεν δημιουργείται αντίγραφο της μεταβλητής δομής στη μνήμη για χρήση μόνο μέσα στην συνάρτηση Έχουμε απευθείας προσπέλαση στη μνήμη Πλεονέκτημα

24 struct onoma_domis *onoma_deikti
Δήλωση Δείκτη σε Δομή Γενική μορφή: struct onoma_domis *onoma_deikti Θα πρέπει να έχει προηγηθεί η δήλωση του structure με όνομα onoma_domis Υπάρχουν κάποια σημεία διαφοροποίησης από τους υπόλοιπους δείκτες

25 Χρήση Δείκτη σε Δομή struct mathitis { char onoma[15]; char eponymo[25]; unsigned short int apousies; unsigned short int vathmos; }; void main(void){ struct mathitis x, *p; p = &x; }

26 Τελεστής Βέλος (->)
Δεν μπορεί να χρησιμοποιηθεί ο τελεστής τελεία (.) για προσπέλαση των στοιχείων της δομής Πρέπει να χρησιμοποιηθεί ένας καινούργιος τελεστής, ο τελεστής βέλος (->) Π.χ. για προσπέλαση του στοιχείου apousies μέσω του δείκτη p: p->apousies = 2;

27 Εναλλακτική Προσπέλαση Στοιχείου Δομής από Δείκτη
Ένας πιο δύσχρηστος τρόπος για προσπέλαση ενός στοιχείου μιας δομής, μέσω του τελεστή τελεία: (*p).apousies = 2; p->apousies = 2; Η χρήση των παρενθέσεων είναι απαραίτητη λόγω χαμηλότερης προτεραιότητας του τελεστή *

28 Συναρτήσεις που Επιστρέφουν Δομές
struct mathitis make_student( char *first, char *last) { struct mathitis temp; strcpy(temp.onoma,first); strcpy(temp.eponymo,last); temp.apousies=0; temp.vathmos=0; return temp; }

29 Συναρτήσεις που Επιστρέφουν Δομές
void main(void){ struct mathitis x; char first[]=“John”; char last[]=“Smith”; x = make_student(first,last); } Επιτρέπεται η ανάθεση τιμής σε ολόκληρη τη δομή (αντιγραφή) Δεν επιτρέπεται σύγκριση δομών

30 Εφαρμογή – Μέτρηση Συχνότητας Εμφάνισης Λέξεων σε Κείμενο
Έχουμε ένα μεγάλο κείμενο και ψάχνουμε μέσα σε αυτό να βρούμε πόσες φορές εμφανίζονται συγκεκριμένες λέξεις-κλειδιά Χρειαζόμαστε 2 πίνακες Για την αποθήκευση των λέξεων-κλειδιών char *keyword[NKEYS]; Για την αποθήκευση της συχνότητας εμφάνισης της κάθε λέξης int keycount[NKEYS];

31 Χρήση Πίνακα Δομών Υπάρχει 1-1 αντιστοιχία μεταξύ των 2 πινάκων, το πιο «κομψό» θα ήταν να χρησιμοποιηθεί 1 πίνακας δομών struct key { char *word; int count; }; struct key keytab[NKEYS];

32 Αρχικοποίηση Πίνακα Δομών
Ο πίνακας θα χρησιμοποιείται σε πολλά σημεία του προγράμματος Ορίζεται ως εξωτερική (global) μεταβλητή struct key keytab[] = { {"account",0}, ... {"programming",0}, {"unix",0} }; Κάθε ζεύγος αντι-στοιχεί στα στοι-χεία μιας δομής Τα εσωτερικά άγκιστρα δεν είναι υποχρε-ωτικά

33 Δομή Προγράμματος Η συνάρτηση main καλεί συνεχώς τη συνάρτηση getword
Διαβάζει από την είσοδο μία λέξη τη φορά Κάθε λέξη αναζητείται μέσα στον πίνακα keytab χρησιμοποιώντας «δυαδική αναζήτηση» (binary search) Η λίστα των λέξεων-κλειδιών πρέπει να είναι ταξινομημένη σε αύξουσα σειρά

34 Συνάρτηση main Δυαδική αναζήτηση του string word στον πίνακα keytab
Κάθε κλήση στην getword βρίσκει μια λέξη και την αντιγράφει στον πίνακα word main() { int n; char word[MAXWORD]; while (getword(word, MAXWORD) != EOF) if (isalpha(word[0])) if ((n = binsearch(word,keytab,NKEYS)) >= 0) keytab[n].count++; for (n = 0; n < NKEYS; n++) if (keytab[n].count > 0) printf("%4d %s\n", keytab[n].count, keytab[n].word); getchar(); //Για να προλάβουμε να δούμε τα αποτελέσματα } Αυξάνεται ο αντί-στοιχος counter Εκτύπωση αποτελεσμάτων

35 Επικεφαλίδες #include <stdio.h> #include <ctype.h>
#include <string.h> #define MAXWORD 100 Μέγεθος ολόκλη-ρου του πίνακα Αριθμός λέξεων-κλειδιών #define NKEYS (sizeof keytab / sizeof(struct key)) Τελεστής compile-time Επιστρέφει το μέγεθος μιας δομής δεδομένων Μέγεθος ενός στοιχείου του πίνακα

36 Συνάρτηση binsearch int binsearch(char *word, struct key tab[], int n) { int cond, low, high, mid; low = 0; high = n - 1; while (low <= high) { mid = (low+high) / 2; if ((cond = strcmp(word,tab[mid].word)) < 0) high = mid - 1; else if (cond > 0) low = mid + 1; else return mid; } return -1; Αρχικά πρόκειται για το μέσο του πίνακα Αν το word είναι μικρότερο, η επόμενη αναζήτηση θα γίνει στο μέσο του μισού πίνακα (προς τα κάτω) Αν το word είναι μεγαλύτερο, η επόμενη αναζήτηση θα γίνει στο μέσο του μισού πίνακα (προς τα πάνω) Αλλιώς, βρέθηκε Συγκρίνω το string word με το string στη θέση mid του πίνακα Αν το «κάτω» ξεπεράσει το «πάνω», τότε δεν βρέθηκε

37 Συνάρτηση getword int getword(char *word, int lim) {
int c; char *w = word; while (isspace(c = getchar())) ; if (c != EOF) *w++ = c; if (!isalpha(c)) { *w = '\0'; return c; } for ( ; --lim > 0; w++) if (!isalnum(*w = getchar())) { ungetch(*w); break; return word[0]; Αγνοεί τα αρχικά κενά Διαβάζει χαρακτήρες σε έναν buffer και επιστρέφει τον πρώτο χαρακτήρα του buffer Διαβάστηκε κάποιος «σωστός» χαρακτήρας Επιστρέφει έναν χαρακτήρα πίσω στο buffer Αν δε διαβάστηκε γράμμα σταμάτα Κύριος βρόχος ανάγνωσης, μέχρι να συναντηθεί μη-αλφαριθμητικός χαρακτήρας

38 Εναλλακτικό πρόγραμμα – Χρήση Δεικτών σε Δομές - main
char word[MAXWORD]; struct key *p; while (getword(word, MAXWORD) != EOF) if (isalpha(word[0])) if ((p=binsearch(word,keytab,NKEYS)) != NULL) p->count++; for (p = keytab; p < keytab + NKEYS; p++) if (p->count > 0) printf("%4d %s\n", p->count, p->word); }

39 Εναλλακτικό πρόγραμμα – Χρήση Δεικτών σε Δομές - binsearch
struct key *binsearch(char *word,struct key *tab,int n) { int cond; struct key *low = &tab[0]; struct key *high = &tab[n]; struct key *mid; while (low < high) { mid = low+(high-low)/2; if ((cond = strcmp(word, mid->word)) < 0) high = mid; else if (cond > 0) low = mid + 1; else return mid; } return NULL; Αρχικά εκτός ορίων πίνακα Η αριθμητικές πρά-ξεις δεικτών εξα-σφαλίζουν σωστό αποτέλεσμα Η προσπέλαση στοι-χείων του keytab γίνεται πλέον με δείκτες Η συνάρτηση πλέον επιστρέφει pointers και όχι ακεραίους

40 Ένωση (union) Είναι μια θέση μνήμης που μπορεί να χρησιμοποιηθεί από πολλές μεταβλητές διαφορετικού τύπου Δήλωση παρόμοια με τη δήλωση μιας δομής union paradeigma { int i; char ch; };

41 Μεταβλητές union Μια μεταβλητή union μπορεί να δηλωθεί
Μετά, σαν μια ξεχωριστή δήλωση union paradeigma x1;

42 Μεταβλητές union και Μνήμη
Ο ακέραιος i και ο χαρακτήρας ch μοιράζονται τον ίδιο χώρο μνήμης. Ο i καταλαμβάνει 2 bytes ενώ ο ch 1

43 Μεταβλητές union και Μνήμη
Όταν δηλώνεται ένα union, ο μεταγλωττιστής αυτόματα κρατάει χώρο στη μνήμη για τον μεγαλύτερο τύπο μεταβλητής που υπάρχει μέσα στο union.

44 Προσπέλαση στοιχείων union
Παρόμοια με τις δομές Αν χρησιμοποιούμε απευθείας μεταβλητή union, χρησιμοποιούμε τον τελεστή τελεία Αν χρησιμοποιούμε δείκτη προς union, τότε χρησιμοποιούμε τον τελεστή βέλος Π.χ., για ανάθεση της τιμής 10 στην ακέραια μεταβλητή i: x1.i = 10;


Κατέβασμα ppt "Δομές στην C (επανάληψη)"

Παρόμοιες παρουσιάσεις


Διαφημίσεις Google