Παράδειγµα (2) Πίνακες (Arrays) (2) Πίνακες (Arrays) (1) int num[5];

Σχετικά έγγραφα
Επεξεργασία Αρχείων Κειµένου

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Προγραμματισμός Ι. Είσοδος/Έξοδος. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

ιαφάνειες παρουσίασης #6 (β)

Διάλεξη 18η: Διαχείρηση Αρχείων

ΠΛΗ111. Ανοιξη Μάθηµα 1 ο Ανασκόπηση της Γλώσσας Προγραµµατισµού C. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης

ΕΠΕΞΕΡΓΑΣΙΑ ΑΡΧΕΙΩΝ Λέµε αρχείο

Προγραμματισμός Η/Υ (ΤΛ2007 )

Ι Αρχεία δεδομένων, μέρος δεύτερο: δυαδικά αρχεία ΙΙ Δομές δεδομένων (struct)

Περιεχόµενα. Πρόλογος... 15

Προγραμματισμός Ι (ΗΥ120)

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. (Διάλεξη 15)

Προγραμματισμός Η/Υ (ΤΛ2007 )

Διάλεξη 3η: Τύποι Μεταβλητών, Τελεστές, Είσοδος/Έξοδος

Τύποι Δεδομένων Είσοδος/Έξοδος

Εισαγωγή στον Προγραµµατισµό. Διάλεξη 2 η : Βασικές Έννοιες της γλώσσας προγραµµατισµού C Χειµερινό Εξάµηνο 2011

Κεφάλαιο , 3.2: Συναρτήσεις II. ( ιάλεξη 12) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Ενδεικτική περιγραφή μαθήματος

Προγραμματισμός Η/Υ (ΤΛ2007 )

Η γλώσσα προγραμματισμού C Δυναμική διαχείριση μνήμης

Α. unsigned int Β. double. Γ. int. unsigned char x = 1; x = x + x ; x = x * x ; x = x ^ x ; printf("%u\n", x); Β. unsigned char

Τεχνολογία και Προγραμματισμός Υπολογιστών. Η γλώσσα προγραμματισμού C

Ανάπτυξη και Σχεδίαση Λογισμικού

scanf() scanf() stdin scanf() printf() int float double %lf float

Προγραμματισμός σε C. Αρχεία κειμένου (Text files)

Μεθόδων Επίλυσης Προβλημάτων

Εργαστήριο 9: Αρχεία

Στόχοι και αντικείμενο ενότητας. Τύπος πίνακα. Τύπος πίνακα (συν.) #6. Πίνακες και Δείκτες

Προγραμματισμός σε C. Αρχεία κειμένου (Text files)

Περιεχόμενα. Πρόλογος... 21

H ΓΛΩΣΣΑ C. Μάθηµα 16: Είσοδος/Έξοδος: Συναρτήσεις Eξόδου. ηµήτρης Ψούνης

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Δομημένος Προγραμματισμός (ΤΛ1006)

Συναρτήσεις πρότυπης βιβλιοθήκης 1. Μερικές συνήθεις συναρτήσεις βιβλιοθήκης int atoi(const char *p) int fclose(file *fp)

Η Γλώσσα C Μία Σφαιρική Ανασκόπηση

Δομημένος Προγραμματισμός (ΤΛ1006)

ΑΡ Χ Ε Ι Α Κ Ε Ι Μ Ε Ν Ο Υ (text files)

int a[5]; a[0] a[1] a[2] a[3] a[4] 15/10/2009

Κεφάλαιο VΙ: Προσπέλαση Αρχείων. 5.1 Αρχεία δεδομένων.

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Κεφάλαιο , 3.2: Συναρτήσεις II. (Διάλεξη 12)

Η γλώσσα προγραμματισμού C

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

Εργαστήριο 2ο. Περίγραμμα Εργαστηριακής Άσκησης

Η πρώτη παράμετρος είναι ένα αλφαριθμητικό μορφοποίησης

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. ( ιάλεξη 13) ιδάσκων: ηµήτρης Ζεϊναλιπούρ

Επανάληψη για τις Τελικές εξετάσεις

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Δομημένος Προγραμματισμός (ΤΛ1006)

Βιβλιοθήκη stdio. Προγραμματισμός II 1

Πίνακες: μια σύντομη εισαγωγή. Πίνακες χαρακτήρων: τα "Αλφαριθμητικά"

Δομημένος Προγραμματισμός (ΤΛ1006)

Εισαγωγή στην C. Μορφή Προγράµµατος σε γλώσσα C

Μεθόδων Επίλυσης Προβλημάτων

#define, 70, 575 #elif, 580 #else, 580 #endif, 580 #error, 584 #if, 580 #ifdef, 583 #ifndef, 580, 583 #include, 70, 227, 574 #undef, 579

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

Λύβας Χρήστος Αρχική επιµέλεια Πιτροπάκης Νικόλαος και Υφαντόπουλος Νικόλαος

Κεφάλαιο Αλφαριθμητικές Σειρές Χαρακτήρων (Strings) (Διάλεξη 20) 1) Strings στη C

Προγραμματισμός Ι (ΗΥ120)

Βιβλιοθήκη stdio. Προγραμματισμός II 1

Εισαγωγή στον Προγραμματισμό (με. τη C)

Ανάπτυξη και Σχεδίαση Λογισμικού

C: Από τη Θεωρία στην Εφαρμογή

Μεθόδων Επίλυσης Προβλημάτων

Περιεχόμενα. Πρόλογος... 17

Ανάπτυξη και Σχεδίαση Λογισμικού

Κεφάλαιο Αλφαριθµητικές Σειρές Χαρακτήρων (Strings)

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

Διαδικαστικός Προγραμματισμός

Η γλώσσα προγραμματισμού C

Εισαγωγή στον Προγραμματισμό

Προγραμματισμός Ι (ΗΥ120)

Προγραμματισμό για ΗΜΥ

Διαδικασιακός Προγραμματισμός

Δομημένος Προγραμματισμός

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

Προγραμματισμός Ι. Προχωρημένα Θέματα. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

C: Από τη Θεωρία στην Εφαρµογή 2 ο Κεφάλαιο

ΣΥΝΟΠΤΙΚΟΣ ΟΔΗΓΟΣ ΓΛΩΣΣΑΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ C

Προγραμματισμός Υπολογιστών με C++

Εισαγωγή στον Προγραμματισμό

ΑΡΧΕΙΑ ΚΕΙΜΕΝΟΥ ΣΤΗΝ C

ΑΡΧΕΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Διαδικασιακός Προγραμματισμός

Διάλεξη 2: Επανάληψη Προγραμματισμού Συμβολοσειρές (strings) Διδάσκων: Παναγιώτης Ανδρέου

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Π. Σταθοπούλου ή Οµάδα Α (Φοιτητές µε µονό αριθµό Μητρώου ) ιδασκαλία : Παρασκευή 11πµ-13µµ ΗΛ7

Υπολογισμός - Συλλογή Δεδομένων - Πίνακες

Προγραμματισμός Η/Υ (ΤΛ2007 )

Η γλώσσα προγραμματισμού C

Προγραμματισμό για ΗΜΥ

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Διάλεξη 9: Δυναμική Δέσμευση Μνήμης

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 3 Επανάληψη Γ μέρος

Προγραμματισμός Η/Υ (ΤΛ2007 )

Εισαγωγή στην γλώσσα προγραμματισμού C

Τμήμα Πληροφορικής & Επικοινωνιών Δρ. Θεόδωρος Γ. Λάντζος

Προγραμματισμός Η/Υ (ΤΛ2007 )

είκτες και Πίνακες (2)

Transcript:

Πίνακες (Arrays) (1) Πίνακας: Σειρά διαδοχικών θέσεων µνήµης µε περιεχόµενα ίδιου τύπου και κοινό όνοµα. Ορισµός µεταβλητής πίνακα: τύπος όνοµα_πίνακα[ακέραια σταθ. έκφρ.]; Π.χ. #define MAX_N 100 int num[5]; float x[max_n + 1]; Πίνακες (Arrays) (2) Κάθε στοιχείο του πίνακα παίζει το ρόλο µεταβλητής, µε όνοµα όνοµα_πίνακα[δείκτης] Τα στοιχεία του πίνακα αριθµούνται ξεκινώντας πάντα από το µηδέν. Π.χ. Το 3ο στοιχείοτουπίνακαnum είναι num[2] 306 307 Παράδειγµα (1) int num[5]; num αρχή του πίνακα Παράδειγµα (2) register int i; for (i = 0; i < 5; i++) num[i]=0; 0 0 0 0 0 num[0] num[1] num[2] num[3] num[4] num[0] num[1] num[2] num[3] num[4] Περιοχή εκτός πίνακα. Περιοχή εκτός πίνακα. 308 309

Παράδειγµα (3) num[2]=12; num[4]=num[2]/5+3; num[0]++; printf( %d\n, num[5]); /* ΛΑΘΟΣ! */ Μετατροπή σε υαδική Αναπαράσταση void toabinary(unsigned m) unsigned q; char r[sizeof(unsigned int) * 8]; /* π.χ. char r[16]; */ register int i = 0; /* αρχικοποίηση */ Περιοχή εκτός πίνακα. 1 0 12 0 5 num[0] num[1] num[2] num[3] num[4] 310 do q = m >> 1; r[i] = m - 2 * q; m= q; i++; while (q!= 0); while (i) printf("%d", r[--i]); /* όχι r[i--] */ 311

ιδιάστατοι Πίνακες (1) ιδιάστατος πίνακας: Μονοδιάστατος πίνακας µε στοιχεία πίνακες Ορισµός: τύπος όνοµα_πίνακα[αριθµός γραµµών][αριθµών στηλών]; int num[5][4]; /* πίνακας 5 στοιχείων καθένα από τα οποία είναι πίνακας 4 ακεραίων */ ιδιάστατοι Πίνακες (2) num αρχή πίνακα num[0][0] num[0][1] num[0][2] num[0][3] num[1][0] num[1][1] num[1][2] num[1][3] num[2][0] num[2][1] num[2][2] num[2][3] num[3][0] num[3][1] num[3][2] num[3][3] num[4][0] num[4][1] num[4][2] num[4][3] 312 313 ιδιάστατοι Πίνακες (3): Εσωτερική Αναπαράσταση num αρχή πίνακα num[0][0] num[0][1] num[0][2] num[0][3] num[1][0] num[1][1] 1η γραµµή 2η γραµµή Πολυδιάστατοι Πίνακες (1) n-διάστατος πίνακας: πίνακας n-1 διαστάσεων µε στοιχεία µονοδιάστατους πίνακες Ορισµός: τύπος όνοµα[1η διάστ.][2η διάστ.]...[n-στή διάστ.]; int num[5][4][2]; /* 5x4 πίνακας µε στοιχεία πίνακες 2 ακεραίων */ 314 315

Πολυδιάστατοι Πίνακες (2) Πολυδιάστατοι Πίνακες (3): Εσωτερική Αναπαράσταση num αρχή πίνακα num[0][0][0]num[0][1][0] num[0][2][0] num[0][3][0] num[0][3][1] num num[1][0][0] num[1][1][0] num[1][2][0] num[1][3][0] num[1][3][1] αρχή πίνακα num[2][0][0]num[2][1][0] num[2][2][0] num[2][3][0] num[2][3][1] num[3][0][0] num[3][1][0] num[3][2][0] num[3][3][0] num[3][3][1] num[0][0][0] num[0][0][1] num[0][1][0] num[0][1][1] num[0][2][0] num[0][2][1] num[4][2][0] num[4][2][1] num[4][3][0] num[4][3][1] num[4][0][0]num[4][1][0] num[4][2][0] num[4][3][0] num[4][3][1] 316 317 Αρχικοποίηση Πίνακα (1) Με χρήση εντολής επανάληψης: register int i, j, k = 0; for (i = 0; i < 5; i++) for (j = 0; j < 4; j++) num[i][j] = ++k; Κατά τον ορισµό: int num[5][4]=1,2,3,4,5,6,7,8,9,10,11,12,13,14, 15,16,17,18,19,20; ή int num[5][4]=1,2,3,4,5,6,7,8,9,10,11,12, 13,14,15,16,17,18,19,20; Αρχικοποίηση Πίνακα (2) Ελλιπής αρχικοποίηση συµπληρώνεται µε µηδενικά: int num[5][4]=1,2,3; /* 1 2 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 */ Ένας εύκολος τρόπος αρχικοποίησης στο µηδενικό πίνακα: int num[5][4] = 0; 318 319

Παράδειγµα: Άθροιση διανυσµάτων #include <stdio.h> #define MAX_N 100 main() int N; float a[max_n], b[max_n], c[max_n]; register int i; void addvec(float [], float [], float [], int); /* δήλωση συνάρτησης */ /* ορισµός συνάρτησης */ void addvec(float x[ ], float y[ ], float z[ ], int M) register int i; for (i = 0; i < M; i++) /* ΛΑΘΟΣ: z = x + y */ z[i] = x[i] + y[i]; printf( ώστε το µέγεθος των διανυσµάτων (το πολύ %d):, MAX_N); scanf( %d, &N); printf( ώστε το πρώτο διάνυσµα: ); for (i = 0; i < N; i++) scanf( %f, &a[i]); printf( ώστε το δεύτερο διάνυσµα: ); for (i = 0; i < N; i++) scanf( %f, &b[i]); addvec(a, b, c, N); printf( Το άθροισµα είναι:\n ); for (i = 0; i < N; i++) printf( %f, c[i]); printf( \n ); return(0); 321 320 Πέρασµα Ορισµάτων σε Συναρτήσεις (1) Με τιµή (call by value): Καταχώρηση της τιµής του ορίσµατος στην αντίστοιχη παράµετρο. Οποιαδήποτε περαιτέρω αλλαγή στην παράµετρο δεν επηρεάζει το όρισµα. Παράδειγµα (1) float addsub(float, float, float); float x = 1.0, y = 2.3, s = 0, d = 0; s = addsub(x, y, d); printf( sum=%f difference=%f\n, s, d); /* 3.3 0 */... float addsub(float a, float b, float diff) float sum; 322 sum = a + b; diff = a b; return(sum); 323

Παράδειγµα (2) Πριν την κλήση της addsub Κατά την κλήση x: 1.0 y: 2.3 a: 1.0 b: 2.3 Μέσα στο σώµα τηςaddsub a: 1.0 b: 2.3 sum: 3.3 s: 0 d: 0 diff: diff: 0-1.3 Πέρασµα Ορισµάτων σε Συναρτήσεις (2) Εκτός αν η παράµετρος παριστάνει διεύθυνση θέσης στη µνήµη, π.χ. όνοµα πίνακα! float c[max_n]; c: διεύθυνση του πρώτου στοιχείου του πίνακα Επιστροφή από την addsub x: 1.0 y: 2.3 s: 3.3 d: 0 c[0] c[1] c[2] c[99] 324 325 Παράδειγµα: Άθροιση ιανυσµάτων Πριν την κλήση της addvec N: 3 a: b: c: 2.0 3.1-1.0? 4.3-1.1 1.0????? a[0] a[1] a[2] a[99] b[0] b[1] b[2] b[99] c[0] c[1] c[2] c[99] Κλήση: addvec(a,b,c,n); N: 3 a: b: c: x: y: z: M: 3 2.0 3.1-1.0? 4.3-1.1 1.0????? x[0] x[1] x[2] x[99] y[0] y[1] y[2] y[99] z[0] z[1] z[2] z[99] Επιστροφή a: b: c: N: 3 είκτες (Pointers): Ένα ισχυρό ατού της C είκτης: Μεταβλητή που περιέχει τη διεύθυνση (του πρώτου byte) στη µνήµη µιας άλλης µεταβλητής Παράδειγµα: float a[max_n]; Το όνοµα τουπίνακα, a, είναι δείκτης, µε περιεχόµενο τη διεύθυνση στη µνήµη τηςµεταβλητής a[0]. 2.0 3.1-1.0? 4.3-1.1 1.0? 6.3 2.0 0.0? a[0] a[1] a[2] a[99] b[0] b[1] b[2] b[99] c[0] c[1] c[2] c[99] 326 327

Ορισµός (και ήλωση) είκτη τύπος *όνοµα_δείκτη; Τύπος της µεταβλητής στην οποία δείχνει. ηλαδή, το *όνοµα_δείκτη είναι αυτού του τύπου. int *ip; /* δείκτης σε int */ float *q; /* δείκτης σε float */ char *cp; /* δείκτης σε char */ Οι Τελεστές & και * &όνοµα_µεταβλητής είναι η διεύθυνση του πρώτου byte της µεταβλητής *όνοµα_δείκτη είναι το περιεχόµενο της µεταβλητής στην οποία δείχνει 329 328 Παράδειγµα int x = 1, *p; p = &x; /* p = 1128 */ printf( %d, *p); /* 1 */ *p = *p + 2; /* το *p χρησιµοποιείται όπως και η x*/ printf( %d, *p); /* 3 */ ιευθύνσεις: p: x: 1024 1128 0 1 1128 1129 1130 1131 330 Προτεραιότητα (10) Unary + -! ++ -- ~ (τύπος) * & * / % + - << >> < <= > >= ==!= & ^ &&?: = += -= *= /= %= &= = ^= <<= >>= Υψηλή Χαµηλή 331

Παράδειγµα float addsub(float, float, float *); float x = 1.0, y = 2.3, s = 0, d = 0; s = addsub(x, y, &d); /* o diff «δείχνει» στην d */ printf( sum=%f difference=%f\n, s, d); /* 3.3-1.3 */... float addsub(float a, float b, float *diff) float sum; sum = a + b; *diff = a b; /* ισοδυναµεί µε d = a b */ return(sum); Κλήση µε Αναφορά(Call by Reference) Η χρήση δεικτών σε παραµέτρους συνάρτησης επιτρέπει την αλλαγή της τιµής των αντίστοιχων ορισµάτων. Χρήσιµη για αποτελέσµατα που δεν µπορούν να επιστραφούν µε return (π.χ. για περισσότερα του ενός αποτελέσµατα). Εναλλακτικός τρόπος: Χρήση εξωτερικών µεταβλητών (λιγότερο κοµψός και εύχρηστος) 332 333 Ένα γνώριµο παράδειγµα scanf( %d, &N); /* ανάγνωση τιµής για τη µεταβλητή N */ Η scanf απαιτεί τη διεύθυνση της µεταβλητής ώστε να είναι σε θέση ν αλλάξει την τιµή της. 334

Αριθµητική ιευθύνσεων (1) Το όνοµα ενόςπίνακαείναιδείκτηςστο πρώτο στοιχείο του. int num[5]; num == &num[0] /* αληθής */ Αριθµητική ιευθύνσεων (2) Ηαύξηση(µείωση) ενός δείκτη που δείχνει σε θέση ενός πίνακα τον κάνει να δείχνει σε επόµενη (προηγούµενη) θέση. int *p; p = num; /* p = &num[0] */ p += 2; /* p = &num[2] */ p--; /* p = &num[1] */ num++; /* εν επιτρέπεται. Ηδιεύθυνσηαρχήςτου πίνακα είναι σταθερή. */ 335 336 Αριθµητική ιευθύνσεων (3) Οσυµβολισµός όνοµα_δείκτη[αριθµός] ισοδυναµεί µε *(όνοµα_δείκτη + αριθµός). p = num + 1; /* p = &num[1] */ p[2] = 10; /* num[1 + 2] = 10 */ p--; /* p = &num[0] */ *p = *(num + 3) + 1; /* num[0] = num[3] + 1 */ Αριθµητική ιευθύνσεων (4) p + 1 p + 2 p = num *p *(p + 1) *(p + 2) num[0] num[1] num[2] num[3] num[4] 337 338

Αριθµητική ιευθύνσεων (5) Αν οι δείκτες p, q δείχνουν σε στοιχεία του ίδιου πίνακα, µπορούν να συγκριθούν και ν αφαιρεθούν: p = num; q = &num[3]; if (p < q) /* αληθής */ d = q p + 1; /* 3 + 1 = 4 */ Αριθµητική ιευθύνσεων (6) p = num q = &num[4] = p + 4 num[0] num[1] num[2] num[3] num[4] Πλήθος στοιχείων µεταξύ p και q: q p + 1 339 340 Αριθµητική ιευθύνσεων (7) Μη επιτρεπτές πράξεις µε δείκτες: int *p, *q, x = 1, y = 2; register float z = 3.2; float *r; p = &x; *q = 5; /* πού δείχνει ο q; */ q = &y; p = p + q; /* όχι πρόσθεση δεικτών */ if (p == q) /* όχι σύγκριση δεικτών που δεν δείχνουν σε θέσεις του ίδιου πίνακα */ r = &z; /* δεν υπάρχει διεύθυνση (&) register µεταβλητής */ p += z; /* όχι πρόσθεση ή αφαίρεση µη-ακέραιου σε δείκτη */ q *= 2; /* ούτε πράξεις µεταξύ δεικτών πλην της αφαίρεσης */ y = q p; /* όχι αφαίρεση δεικτών που δεν δείχνουν σε θέσεις του ίδιου πίνακα */ p = r; /* δεν είναι δείκτες σε θέσεις ίδιου τύπου */ 341 Αριθµητική ιευθύνσεων (8) Προσοχή στην προτεραιότητα των τελεστών! int x = 2, *p; p = &x; /* ο p δείχνει στη x */ ++*p; /* αύξησε τη x κατά 1 */ *p++; /* Πάρε το περιεχόµενο της θέσης στην οποία δείχνει ο p και κατόπιν αύξησέ τον */ (*p)++; /* Αύξησε κατά 1 το περιεχόµενο της θέσης στην οποία δείχνει ο p */ 342

είκτες σε είκτες (1) Αν p είναι δείκτης, τότε &p είναι η διεύθυνσή του. int x = 2, *p, **q; p = &x; q = &p; **q = 3; /* x = 3 */ είκτες σε είκτες (2) ιδιάστατος πίνακας: Πίνακας µε στοιχεία πίνακες: είκτης σε δείκτες void addvec(float **x, float **y, float **z, int M) ιαφορά πίνακα και δείκτη: float a[max_n]; /* δεσµεύονται MAX_N θέσεις float στη µνήµη */ a[2] = 3.45; float *a; /* δεσµεύεται µόνο µια θέση δείκτη a[2] = 3.45; σε float */ /* δεν επιτρέπεται. Ο a + 2 δεν δείχνει σε δεσµευµένη θέση */ 343 344 Αλφαριθµητικά (Strings) Πίνακας χαρακτήρων: Πίνακας µε στοιχεία χαρακτήρες char message[ ] = H, e, l, l, o ; H e l l o? Αλφαριθµητικό (ή συµβολοσειρά): Πίνακας χαρακτήρων που τελειώνει σε \0 char message[ ] = Hello ; H e l l o \0 Παράδειγµα: Αντιγραφή αλφαριθµητικών (1) void strcpy(char s[ ], char t[ ]) register int i = 0; while ((s[i] = t[i])!= \0 ) i++; 345 346

Παράδειγµα: Αντιγραφή αλφαριθµητικών (2) void strcpy(char *s, char *t) while ((*s = *t)!= \0 ) s++; t++; Παράδειγµα: Αντιγραφή αλφαριθµητικών (3) void strcpy(char *s, char *t) while ((*s++ = *t++)!= \0 ) ; 347 348 Παράδειγµα: Αντιγραφή αλφαριθµητικών (4) Παράδειγµα: Ανάγνωση και Εκτύπωση Αλφαριθµητικών void strcpy(char *s, char *t) while (*s++ = *t++) ; lines[0] lines[1] lines[2] F i r s t S char lines[10][80]; \0 e c o n d 349 350

#include <stdio.h> /* NULL, printf, gets, puts */ #include <string.h> /* πρωτότυπο της strcpy */ #define MAXLINES 10 #define MAXLENGTH 80 main() int nlines; register int i = 0; char lines[maxlines][maxlength], s[maxlength]; /* #define NULL 0 */ while (gets(s)!= NULL) /* διάβασε την επόµενη γραµµή */ strcpy(lines[i++], s); /* και αντέγραψέ την στη γραµµή i */ nlines = i; printf( ώσατε %d γραµµές:\n, nlines); for (i = 0; i < nlines; i++) puts(lines[i]); /* εµφάνισε τη γραµµή i */ return(0); Πώς θα µπορούσαµε να εξοικονοµήσουµε χώρο; char *lines[10]; lines[0] F i r s t \0 lines[1] S e c o n d L i n e \0 lines[2] lines[3] lines[9] T h i r d \0 351 352 υναµική έσµευση και Απελευθέρωση Μνήµης (1) υναµική δέσµευση µνήµης: void *malloc(size_t no_bytes); Π.χ. αντί του ορισµού int num[5]; int *num; num = (int *)malloc(5 * sizeof(int)); υναµική απελευθέρωση µνήµης: void free(void *); Π.χ. free(num); /* ο num τώρα δεν δείχνει πουθενά */ 353 υναµική έσµευση και Απελευθέρωση Μνήµης (2) int *p;? *p p = (int *)malloc(sizeof(int));? *p = 3; 3 free(p);? p = NULL; NULL p 354

#include <stdio.h> /* NULL, printf, gets, puts */ #include <string.h> /* πρωτότυπα των strcpy, strlen */ #include <stdlib.h> /* malloc, free */ #define MAXLINES 10 #define MAXLENGTH 80 main() int nlines; register int i = 0; char *lines[maxlines], s[maxlength]; while (gets(s)!= NULL) if ((lines[i] = (char *)malloc(strlen(s))) == NULL) fprintf(stderr, Ανεπάρκεια µνήµης!\n ); return(1); strcpy(lines[i++], s); 355 nlines = i; printf( ώσατε %d γραµµές:\n, nlines); for (i = 0; i < nlines; i++) puts(lines[i]); /* εµφάνισε τη γραµµή i */ free(lines[i]); /* απελευθέρωσε τον αντίστοιχο χώρο */ return(0); 356

Ορίσµατα Γραµµής ιαταγών (Command Line Arguments) main(int argc, char *argv[ ]) argc: πλήθος ορισµάτων στην κλήση του προγράµµατος (συµπεριλαµβανοµένου του ονόµατος της διαταγής) argv: πίνακας των argc αλφαριθµητικών που παριστάνουν τα ορίσµατα της διαταγής argv[0]: το όνοµα του προγράµµατος Παράδειγµα: Αθροιστής Εκτελέσιµο πρόγραµµα: add.exe Π.χ. add 1.2 2.3 0.18-0.92 argv a d d \0 1. 2 \0-2. 3 0. 1 \0 8 \0 argc = 4 0 357 358 #include <stdio.h> #include <stdlib.h> /* πρωτότυπο της atof */ main(int argc, char *argv[]) float sum = 0.0; register int i; if (argc <= 2) fprintf(stderr, "%s: Απαιτούνται τουλάχιστον δύο αριθµοί!\n", argv[0]); return(1); for (i = 1; i <= argc - 1; i++) sum += atof(argv[i]); /* atof: string σε float αριθµό */ printf("%.3f\n", sum); return(0); 359

οµές (Structures) (1) οµή: Συλλογή µιας ή περισσοτέρων µεταβλητών οµαδοποιηµένων µ ένα όνοµα για εύκολο χειρισµό. Τα µέλη της δοµής µπορούν να είναι διαφορετικού τύπου (σε αντίθεση µε τα στοιχεία ενός πίνακα). οµές (Structures) (2) Παραδείγµατα: Σηµείο στην οθόνη: Ζεύγος ακέραιων συντεταγµένων x, y Σηµείο στον τρισδιάστατο χώρο: Τριάδα πραγµατικών αριθµών Εγγραφή (record) φοιτητή: Επώνυµο Όνοµα Εξάµηνο Έτος εισαγωγής ιεύθυνση Τηλέφωνο 360 361 οµές (Structures) (3) Ορισµός δοµής: struct ετικέτα τύπος1 µέλος1; τύπος2 µέλος2;... ; οµές (Structures) (4) Ορισµός µεταβλητής τύπου δοµής: struct ετικέτα όνοµα_µεταβλητής; ή struct ετικέτα τύπος1 µέλος1; τύπος2 µέλος2;... όνοµα_µεταβλητής; 362 363

Παραδείγµατα (1) Σηµείο στην οθόνη struct point int x; int y; ; struct point pt1, pt2; Παραδείγµατα (2) Σηµείο στον τριδιάστατο χώρο struct point3d float x, y, z; ; struct point3d p1, p2, p3, p4; 364 365 Παραδείγµατα (3) Εγγραφή φοιτητή struct student char fname[10]; char lname[20]; short semester; short entry_yr; char address[40]; char phone[10]; stdt1, stdt2; Τελεστής Μέλους οµής (.) Αναφορά σε µέλος µιας µεταβλητής δοµής: όνοµα_δοµής.όνοµα_µέλους struct point pt1, pt2; pt1.x = 50; pt1.y = 100; pt2.x = pt1.x; pt2.y = pt2.y + 30; printf( Point1=(%d,%d), Point2=(%d,%d)\n, pt1.x, pt1.y, pt2.x, pt2.y); 366 367

οµή: Συλλογή Μεταβλητών pt1 pt2 pt1.x pt1.y pt2.x pt2.y Παράδειγµα: Ορθογώνιο ( οµή µε µέλη δοµές) (1) Ορθογώνιο: Καθορίζονται η κάτω αριστερά και η πάνω δεξιά γωνία του struct rect struct point left; struct point right; ; struct rect r; right left 368 369 Παράδειγµα: Ορθογώνιο ( οµή µε µέλη δοµές) (2) Παράδειγµα: Ορθογώνιο ( οµή µε µέλη δοµές) (3) r r.left.x r.left.y r.right.x r.left /* εµβαδόν ορθογωνίου */ int area(struct rect r) int width, height; r.right.y r.right width = r.right.x r.left.x; /* πλάτος */ height = r.left.y r.right.y; /* ύψος */ return(width * height); 370 371

Λειτουργίες µε οµές (1) Αντιγραφή struct point pt1, pt2; pt1 = pt2; /* pt1.x = pt2.x; pt1.y = pt2.y */ Αρχικοποίηση struct point pt1 = 50, 100; /* pt1.x = 50; pt1.y = 100 */ Λειτουργίες µε οµές (2) Εξαγωγή διεύθυνσης struct point pt, *pt_pointer; pt_pointer = &pt; (*pt_pointer).x = 50; Εξαγωγή και χειρισµός µελών width = r.right.x r.left.x; Υπολογισµός µεγέθους (σε bytes) sizeof(struct point) sizeof(pt1) 372 373 Λειτουργίες µε οµές (3) Πέρασµα ορίσµατος σε συνάρτηση printf( Εµβαδό = %d\n, area( r )); Επιστροφή από συνάρτηση struct point makepoint(int x, int y) struct point pt; pt.x = x; pt.y = y; return(pt); 374

είκτες σε οµές Κλήση µε αναφοράµε όρισµα δοµή: Πέρασµα της διεύθυνσης της δοµής (αντί της αντιγραφής της τιµής της) Χρήσιµη γιαδοµές µεγάλου µεγέθους Ο τελεστής -> struct point pt, *pt_pointer; pt_pointer = &pt; pt_pointer->x = 50; /* (*pt_pointer).x = 50; */ pt_pointer->y = 100; /* (*pt_pointer).y = 100; */ Παράδειγµα area (struct rect *pr) int width, height; width = pr->right.x pr->left.x; height = pr->left.y pr->right.y; return(width * height); 375 376 Προτεραιότητα (11) ( ) [ ] ->. Unary + -! ++ -- ~ (τύπος) * & sizeof * / % + - << >> < <= > >= ==!= & ^ &&?: = += -= *= /= %= &= = ^= <<= >>=, Υψηλή Χαµηλή 377

Πίνακες οµών (1) Παράδειγµα: Πίνακας φοιτητών Πίνακες οµών (2) struct stud *p; struct stud char name[30]; /* ονοµατεπώνυµο */ short id; /* ΑΜ */ ; struct stud students[220]; p = students; /* p = &students[0]; */ strcpy(p->name, ΓΕΩΡΓΙΟΥ Ν. ); /* strcpy(students[0].name, ΓΕΩΡΓΙΟΥ Ν. ); */ p->id = 5; /* students[0].id = 5; */ p++; /* p = &students[1]; */ 378 379 Παράδειγµα #include <stdio.h> #define MAX_N 10 struct stud char name[30]; short mark; ; main() float average(struct stud [ ], int); struct stud students[max_n], *p; int N; register int i; printf("how many students? (at most %d)", MAX_N); scanf("%d", &N); 380 for (p = students, i = 0; i < N; p++, i++) τελεστής κόµµα printf("student no. %d:\n", i + 1); (, ) printf("name: "); scanf("%s", p->name); printf("mark: "); scanf("%d", p->mark); printf("average mark: %f\n", average(students, N)); return(0); float average(struct stud list[], int M) 381

typedef Παράδειγµα ηµιουργία νέων ονοµάτων τύπων typedef τύπος όνοµα_τύπου; typedef struct point Point; typedef struct Point left; Point right; Rectangle; typedef float Real; typedef struct point Point; typedef struct point *PointPtr; area(rectangle r) int width, height; 383 382 Είσοδος και Έξοδος (Input/Output (I/O)) Πρότυπη Είσοδος/Έξοδος (Standard Input/Output) Πληκτρολόγιο Εκτυπωτής Οθόνη Πρόγραµµα Αρχεία δίσκου Πρότυπη είσοδος: (Σχεδόν πάντα) το πληκτρολόγιο Πρότυπη έξοδος: (Σχεδόν πάντα) η οθόνη Γιατί «σχεδόν πάντα»; υνατότητα επανακατεύθυνσης (redirection) της πρότυπης εισόδου ή/και εξόδου 384 385

Πρότυπη Βιβλιοθήκη Συναρτήσεων Εισόδου/Εξόδου Η C δεν έχει εντολές για είσοδο/έξοδο. I/O επιτελείται µε συναρτήσεις. Πρότυπη βιβλιοθήκη εισόδου/εξόδου: Συλλογή έτοιµων συναρτήσεων (ή και µακροεντολών) για λειτουργίες εισόδου/εξόδου Πρωτότυπα συναρτήσεων I/O στο αρχείο επικεφαλίδα <stdio.h> 386 Είσοδος και Έξοδος Χαρακτήρων (1) getchar( ) Επιστρέφει τον ακέραιο κωδικό του επόµενου χαρακτήρα από την πρότυπη είσοδο, και EOF για τέλος αρχείου (τέλος εισόδου, συνήθως Ctrl+Z). int ch; /* int, όχι char */ while ((ch = getchar())!= EOF) /* ιαβάζει τον επόµενο χαρακτήρα, έως ότου τελειώσει η είσοδος */... 387 Είσοδος και Έξοδος Χαρακτήρων (2) putchar(ch) Γράφει το χαρακτήρα ch στην πρότυπη έξοδο. Επιστρέφει το χαρακτήρα ή EOF αν κάτι δεν πήγε καλά. int ch; /* int, όχι char */ while ((ch = getchar())!= EOF) /* Αντιγράφει την είσοδο στην έξοδο, αλλάζοντας τα κεφαλαία γράµµατα σε πεζά */ ch = tolower(ch); putchar(ch); 388 Μορφοποιηµένη Πρότυπη Έξοδος: printf (1) printf(char *format, ορ1, ορ2, ); Αλφαριθµητικό φόρµας (format string) Μεταβλητό πλήθος ορισµάτων Το format string καθορίζει πώς θα γραφτούν τα ορίσµατα. Προδιαγραφές µετατροπής: Καθορίζουν τον τύπο του ορίσµατος, το πλάτος του στην οθόνη, και την ακρίβεια αναπαράστασης. printf( Variance = %.2f\n, sigma2); 389

Μορφοποιηµένη Πρότυπη Έξοδος: printf (2) Μορφοποιηµένη Πρότυπη Έξοδος: printf (3) Οι συνηθέστερες προδιαγραφές µετατροπής: d δεκαδικός ακέραιος u απρόσηµος δεκαδικός ακέραιος f πραγµατικός αριθµός e πραγµατικός σε επιστηµονική γραφή g πραγµατικός σε απλή ή επιστηµονική γραφή c χαρακτήρας s αλφαριθµητικό hd short δεκαδικός ακέραιος ld long δεκαδικός ακέραιος lf double 390 Παράδειγµα: float x = -3.45; int y = 2; printf( %s: x is %.3f and y is %d, Answer1, x, y); printf( \n%.4s: x is %6.0f and y is %3d\n, Answer2,x,y); Answer1: x is 3.450 and y is 2 Answ: x is -3 and y is 2 391 Μορφοποιηµένη Πρότυπη Είσοδος: scanf (1) scanf(char *format, ορ1, ορ2, ); Αλφαριθµητικό φόρµας (format string) Μεταβλητό πλήθος ορισµάτων Για το format string ισχύουν ανάλογα µ αυτά της printf. Τα ορίσµατα είναι διευθύνσεις στη µνήµη (δείκτες). scanf( %d, &N); Μορφοποιηµένη Πρότυπη Είσοδος: scanf (2) Παράδειγµα: int semester; float mark; char *name; scanf( %s %d %f, name, &semester, &mark); printf( Name: %s, Semester: %d, Mark: %.1f\n, name, semester, mark); ΓΕΩΡΓΙΟΥ 3 8.5 Name: ΓΕΩΡΓΙΟΥ, Semester: 3, Mark: 8.5 392 393

Μορφοποιηµένη Πρότυπη Είσοδος: scanf (3) Η scanf επιστρέφει το πλήθος των ορισµάτων που ανέγνωσε σωστά. Έλεγχος για αποδεκτή είσοδο: Με χρήση και της fflush( ) int x, y; printf( ώστε δύο ακέραιους: ); while (scanf( %d %d, &x, &y)!= 2) fflush(stdin); printf( ώστε δύο ακέραιους: \n ); 394 Είσοδος/Έξοδος από/σε Αρχεία Βήµατα διαχείρισης αρχείου: Άνοιγµα αρχείου για ανάγνωση ή εγγραφή Ανάγνωση ή εγγραφή αρχείου Κλείσιµο αρχείου Σύνδεση ονόµατος αρχείου µε το αρχείο: Μέσω δείκτη σε δοµή τύπου FILE 395 Άνοιγµα Αρχείου: fopen (1) FILE *fopen(char *filename, char *mode); Ανοίγει αρχείο µε όνοµα filename γιαναχρησιµοποιηθεί µε τον τρόπο mode: r ανάγνωση (read) w εγγραφή (write) a προσθήκη (append) Επιστρέφει δείκτη στη δοµή FILE που περιέχει τις απαραίτητες πληροφορίες για την προσπέλαση του αρχείου. Επιστρέφει NULL αν κάτι δεν πήγε καλά. Άνοιγµα Αρχείου: fopen (2) Παράδειγµα: Έλεγχος ανοίγµατος αρχείου FILE *fp; /* δείκτης αρχείου (file pointer) */ char filename[10]; scanf( %s, filename); if ((fp = fopen(filename, r )) == NULL) printf( εν ανοίγει το αρχείο %s\n, filename); 396 397

Είσοδος/Έξοδος Χαρακτήρων από/σε Αρχείο getc(fp) Επιστρέφει τον ακέραιο κωδικό του επόµενου χαρακτήρα στο αρχείο που δείχνει ο fp. putc(ch, fp) Γράφει το χαρακτήρα ch στοαρχείοπου δείχνει ο fp. Πρότυπη Είσοδος/Έξοδος (1) Η πρότυπη είσοδος και έξοδος θεωρούνται επίσης αρχεία!! Πρότυπη είσοδος: Αρχείο µε δείκτη stdin Πρότυπη έξοδος: Αρχείο µε δείκτη stdout 398 399 Πρότυπη Είσοδος/Έξοδος (2) #define getchar() getc(stdin) #define putchar(c) putc((c), stdout) Μορφοποιηµένη Έξοδος σε Αρχείο: fprintf fprintf(file *fp, char *format, ορ1, ορ2,...) Παρόµοια µε την printf, αλλά γράφει στο αρχείο fp αντί της πρότυπης εξόδου fprintf(stdout, ) printf( ) 400 401

Μορφοποιηµένη Είσοδος από Αρχείο: fscanf fscanf(file *fp, char *format, ορ1, ορ2,...) Παρόµοια µε την scanf, αλλά διαβάζει από το αρχείο fp αντί της πρότυπης εισόδου fscanf(stdin, ) scanf( ) Κλείσιµο Αρχείου fclose(file *fp) Κλείνει το αρχείο που δείχνει ο fp (πλέον ο fp δεν δείχνει πουθενά). fcloseall() Κλείνει όλα τα ανοιχτά αρχεία. Με τον τερµατισµό του προγράµµατος κλείνουν αυτόµατα όλα τα αρχεία που αυτό έχει ανοίξει. 402 403 stderr και Χειρισµός Λαθών Πρότυπη έξοδος για µηνύµατα λάθους: stderr Εµφάνιση µηνυµάτων στην οθόνη ανεξάρτητα από τυχόν επανακατεύθυνση του stdout if (N < 0 N > MAX_N) fprintf(stderr, Μη αποδεκτή τιµή!\n ); return(1); Τερµατισµός του Προγράµµατος: exit exit (ακέραιος κωδικός) Τερµατίζει το πρόγραµµα, επιστρέφοντας κωδικό σφάλµατος στο λειτουργικό σύστηµα. if (N < 0 N > MAX_N) fprintf(stderr, Μη αποδεκτή τιµή!\n ); exit(1); Ισχυρότερη της return (γιατί;) 404 405

Είσοδος/Έξοδος Γραµµών (1) char *fgets(char *line, int maxline, FILE *fp); ιαβάζει το πολύ maxline χαρακτήρες από την επόµενη γραµµή του αρχείου fp, τους αποθηκεύει στο line και επιστρέφει δείκτη σ αυτό. int fputs(char *line, FILE *fp); Γράφει το αλφαριθµητικό line στο αρχείο fp κι επιστρέφει µηδέν αν όλα πήγαν καλά. Είσοδος/Έξοδος Γραµµών (2) Για πρότυπη είσοδο: gets(file *fp) Για πρότυπη έξοδο: puts(char *string, FILE *fp) 406 407 Παράδειγµα: Συχνότητα εµφάνισης γραµµάτων #include <stdio.h> #include <ctype.h> main() char filename[20]; FILE *fp; int ch, freqs[26] = 0; printf( Αυτό το πρόγραµµα µετράει τις συχνότητες εµφάνισης \ των γραµµάτων σ ένα αρχείο.\n"); printf( ώστε το όνοµα τουαρχείου: "); scanf("%s", filename); if ((fp = fopen(filename, "r")) == NULL) fprintf(stderr, εν ανοίγει το αρχείο!\n"); return(1); while ((ch = getc(fp))!= EOF) if (!isalpha(ch)) continue; ch = tolower(ch); freqs[ch - 'a']++; printf( Οι συχνότητες των γραµµάτων είναι:\n"); for (ch = 0; ch < 26; ch++) printf("%c\t%3d\n", ch + 'a', freqs[ch]); return(0); 408 409