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

Σχετικά έγγραφα
int a[5]; a[0] a[1] a[2] a[3] a[4] 15/10/2009

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

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

Διάλεξη 8η: Αλφαριθμητικά (strings)

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

ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΟΜΗΜΕΝΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ

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

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

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

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

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

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

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

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

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

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

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

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

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

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

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

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

Προγραμματισμός Ι (HY120)

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

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

int abs( int x ), επιστρέφει την απόλυτη τιμή του ακεραίου x Πχ abs( 11) ισούται με 11, abs(34) ισούται με 34 double fb( fabs( double x ), επιστρέφει

ΕΝΤΟΛΕΣ ΕΠΑΝΑΛΗΨΗΣ. for (παράσταση_1; παράσταση_2; παράσταση_3) εντολή επόμενη εντολή

που θα δώσει αποτέλεσµα 48, λόγω της αριστερής προσεταιριστικότητας των τελεστών / και *, ενώ η επιθυµητή αντικατάσταση θα ήταν η

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

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

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

Εισαγωγή στον δομημένο προγραμματισμό

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

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

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

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

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

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

Επεξεργασία Αρχείων Κειµένου

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

Πίνακες. 1 Πίνακες. 30 Μαρτίου 2014

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

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

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

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

Επανάληψη για τις Τελικές εξετάσεις. (Διάλεξη 24) ΕΠΛ 032: ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΕΘΟΔΩΝ ΕΠΙΛΥΣΗΣ ΠΡΟΒΛΗΜΑΤΩΝ

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

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

Αρχές Προγραμματισμού

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

Κεφάλαιο 8.7. Πολυδιάστατοι Πίνακες (Διάλεξη 19)

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

Εισαγωγή στον Προγραµµατισµό. Πανεπιστήµιο Θεσσαλίας Τµήµα Ηλεκτρολόγων Μηχανικών και Μηχανικών Η/Υ

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

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

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

ΤΕΜ-101 Εισαγωγή στους Η/Υ Εξεταστική Ιανουαρίου 2011 Θέματα Β

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

int array[10]; double arr[5]; char pin[20]; Προγραµµατισµός Ι

Συναρτήσεις διαχείρισης αλφαριθμητικών

Προγραµµατισµός Ι Αλφαριθµητικά Πανεπιστήµιο Πελοποννήσου Τµήµα Πληροφορικής & Τηλεπικοινωνιών Προγραµµατισµός Ι 1 Νικόλαος Δ.

Χpήσιµες Βιβλιοθήκες της γλώσσας C

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

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

Βήματα: μνήμη 2. Αλγόριθμος βήματα που περιγράφουν την επεξεργασία των δεδομένων. Δομές Δεδομένων + Αλγόριθμοι = Προγράμματα

ΑΣΚΗΣΗ 7: ΑΛΦΑΡΙΘΜΗΤΙΚΑ

Προγραμματισμός Η/Υ Ι (Χρήση της C) 6 η Θεωρία ΜΟΝΟΔΙΑΣΤΑΤΟΙ ΠΙΝΑΚΕΣ

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

Προγραμματισμός Ι. Χαρακτήρες. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

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

ΔΟΜΗΜΕΝΟΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ

Απλά Προγράμματα. Βήματα: 1. Καθορισμός παράστασης δεδομένων στη μνήμη 2. Αλγόριθμος βήματα που περιγράφουν την επεξεργασία των δεδομένων

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

Προγραμματισμός Η/Υ 1 (Εργαστήριο)

6. ΠΙΝΑΚΕΣ & ΑΛΦΑΡΙΘΜΗΤΙΚΑ

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

2ο σετ σημειώσεων. 1 Εντολές εκτέλεσης υπό συνθήκη. 19 Μαρτίου 2012

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

3ο σετ σημειώσεων - Πίνακες, συμβολοσειρές, συναρτήσεις

Α Β Γ static; printf("%c\n", putchar( A +1)+2); B DB BD. int i = 0; while (++i); printf("*");

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

Συμβολοσειρές Ορίσματα στη main()

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

Επεξεργασία κειμένου και συμβολοσειρών σε C

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

Γλώσσα Προγραμματισμού C

Βαθμός Σχόλια. lab6 PASS PASS. - Πολύ καλή δουλειά, αλλά προσπάθησε να κάνεις την άσκηση χρησιµοποιώντας συναρτήσεις από το string.

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

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

Μεταφερσιμότητα Τα προγράμματα μεταφέρονται εύκολα σε διαφορετικά λειτουργικά συστήματα

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

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

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

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

5. ΒΡΟΧΟΙ ΕΠΑΝΑΛΗΨΗΣ (Β' μέρος: while - do..while)

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

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

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

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

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

Transcript:

Προγραμματισμός Ι (ΗΥ120) Διάλεξη 8: Πίνακες, Αλφαριθμητικά

Πίνακες Ο πίνακας είναι μια ειδική δομή για την αποθήκευση μιας σειράς από δεδομένα του ίδιου τύπου. Η δήλωση ενός πίνακα γίνεται όπως για μια κανονική μεταβλητή, σε συνδυασμό με τον τελεστή [] μέσω του οποίου δηλώνεται το μέγεθος του πίνακα. Το μέγεθος Ν του πίνακα δηλώνει τον αριθμό των στοιχείων του Στην ουσία, το ότι πρέπει να δεσμευτεί μνήμη για να αποθηκευτούν Ν ξεχωριστές τιμές που αντιστοιχούν στον τύπο του. Κάθε στοιχείο ενός πίνακα από δεδομένα τύπου Τ είναι συντακτικά συμβατό με μια μεταβλητή τύπου Τ. Όπως μια συμβατική μεταβλητή, κάθε στοιχείο του πίνακα πρέπει να αρχικοποιηθεί με συγκεκριμένη τιμή. 2

int a[5]; τελεστής [] 2 ο στοιχείο 3 μέγεθος πίνακα a[0] a[1] a[2] a[3] a[4]

Πρόσβαση σε στοιχεία του πίνακα Αν ο πίνακας έχει μέγεθος Ν (αντικείμενα), τότε η θέση 0 αντιστοιχεί στο πρώτο στοιχείο και η θέση Ν-1 στο τελευταίο στοιχείο του πίνακα. Η μνήμη για την αποθήκευση των τιμών που θα δοθούν στα στοιχεία του πίνακα δεσμεύεται (από τον μεταφραστή) συνεχόμενα, δηλαδή η τιμή του στοιχείου στη θέση i αποθηκεύεται στην αμέσως επόμενη διεύθυνση από αυτή του στοιχείου i-1. Η πρόσβαση του πίνακα με τιμή θέσης εκτός ορίων αποτελεί προγραμματιστικό λάθος καθώς αντιστοιχεί σε πρόσβαση μνήμης που δεν ανήκει στον πίνακα. Ο μεταφραστής δεν ελέγχει αν η θέση που δίνει ο προγραμματιστής είναι εντός των ορίων. 4

int a; int b[3]; int c[] = {5,8,2}; a = b[0]; a = c[2]; b[0] = c[1]; c[0]++; b[--a] = 3; a = c[-1]; b[3] = 5; /* ακέραιος */ /* πίνακας 3 ακεραίων */ /* πίνακας 3 ακεραίων, με τιμές 5, 8, 2 */ /* a γίνεται? */ /* a γίνεται 2 */ /* b[0] γίνεται 8 */ /* c[0] γίνεται 6 */ /* a γίνεται 1, b[1] γίνεται 3 */ /*!? */ /*!? */ 5

Δέσμευση μνήμη πίνακα 6 Ο αριθμός των στοιχείων ενός πίνακα δίνεται (άμεσα ή έμμεσα) κατά την δήλωση του. Το μέγεθος του πίνακα πρέπει να είναι γνωστό και να δοθεί την ώρα της συγγραφής του κώδικα. Δεν υποστηρίζονται «ανοιχτοί» πίνακες, το μέγεθος των οποίων μπορεί να (επανα)προσδιοριστεί ή/και να αλλάξει κατά την διάρκεια της εκτέλεσης. Μνήμη για την αποθήκευση των στοιχείων ενός πίνακα μεγέθους Ν από δεδομένα τύπου Τ: Ν*sizeof(T) Δεσμεύεται μονομιάς ανεξάρτητα με το ποια στοιχεία του πίνακα θα χρησιμοποιηθούν τελικά από το πρόγραμμα).

Ασφάλεια προσπέλασης μνήμης Με τις συμβατικές μεταβλητές ένα πρόγραμμα δεν μπορεί να προσπελάσει «λάθος» θέσεις μνήμης. Αυτό δεν ισχύει όταν χρησιμοποιούμε πίνακες. Η πρόσβαση σε θέση που βρίσκεται εκτός των ορίων του πίνακα δεν εντοπίζεται από τον μεταφραστή Ούτε (απαραίτητα) κατά την εκτέλεση. Μπορεί (κατά λάθος) να διαβαστούν / γραφτούν τιμές σε θέσεις μνήμης εκτός της περιοχής του πίνακα με απροσδόκητα (λάθος) αποτελέσματα. Υπάρχει περίπτωση το πρόγραμμα να «καταστρέφει» δεδομένα δικών του μεταβλητών. 7

char a; char b[3]; char c; a b[0] b[1] b[2] c διεύθυνση 1 2 3 4 5 6 περιεχόμενα 0 0 1 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 0 1 0 1 0 1 0 0 0 0 1 0 8 7 0 1 0 1 0 0 0 0 8 0 0 0 1 1 0 0 0 9 0 0 1 0 1 0 1 0...

char a; char b[3]; char c; a διεύθυνση 1 2 περιεχόμενα 0 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1 9 b[0]='a'; b[0] 3 b[1] b[2] 4 5 0 1 1 0 0 0 1 1 6 c 7 8 9...

char a; char b[3]; char c; a διεύθυνση 1 2 περιεχόμενα 0 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1 10 b[0]='a'; b[0] 3 0 1 1 0 0 0 1 0 b[1]='b'; b[1] b[2] 4 5 0 1 1 0 0 0 1 1 6 c 7 8 9...

char a; char b[3]; char c; a διεύθυνση 1 2 περιεχόμενα 0 1 1 0 0 0 0 1 0 1 1 0 0 0 0 1 11 b[0]='a'; b[0] 3 0 1 1 0 0 0 1 0 b[1]='b'; b[2]='c'; b[1] b[2] 4 5 6 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 1 c 7 8 9...

char a; char b[3]; char c; a διεύθυνση 1 2 περιεχόμενα 0 1 1 0 0 1 0 0 0 1 1 0 0 0 0 1 12 b[0]='a'; b[0] 3 0 1 1 0 0 0 1 0 b[1]='b'; b[2]='c'; b[1] b[2] 4 5 6 0 1 1 0 0 0 1 1 0 1 1 0 0 0 1 1 b[-1]='d'; c 7 8 9...

char a; char b[3]; char c; a διεύθυνση 1 2 περιεχόμενα 0 1 1 0 0 1 0 0 0 1 1 0 0 0 0 1 13 b[0]='a'; b[0] 3 0 1 1 0 0 0 1 0 b[1]='b'; b[2]='c'; b[1] b[2] 4 5 6 0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 1 b[-1]='d'; c 7 b[3]='e'; 8 9...

Πρόσβαση μέσω μεταβλητών Ο προσδιορισμός της θέσης των στοιχείου ενός πίνακα μπορεί να γίνει μέσω οποιασδήποτε έκφρασης αποτιμάται σε ακέραια τιμή. Αντί για σταθερές και κυριολεκτικά, μπορεί να χρησιμοποιούνται τιμές από μεταβλητές ακεραίων. Π.χ. μπορεί να παραμετροποιηθεί η πρόσβαση στα στοιχεία ενός πίνακα a μεγέθους Ν μέσω ενός απλού σχήματος επανάληψης: χρησιμοποιούμε μια μεταβλητή «μετρητή» i, που λαμβάνει τιμές από 0 μέχρι Ν-1 στο σώμα της επανάληψης αναφερόμαστε στο «επόμενο» στοιχείο του πίνακα ως a[i] 14

/* ανάγνωση 10 ακεραίων και εκτύπωση αθροίσματος */ #include <stdio.h> #define N 10 /* όπου "Ν" αντικατέστησε με "10" */ int main(int argc, char* argv[]) { int elem[n]; /* πίνακας Ν ακεραίων */ int sum; /* άθροισμα στοιχείων */ int i; /* μετρητής βρόγχου for */ 15 for (i=0; i<n; i++) { printf("enter int: "); scanf("%d", &elem[i]); } sum = 0; for (i=0; i<n; i++) { sum = sum + elem[i]; } } printf("sum is %d\n", sum); return(0);

/* ανάγνωση 10 ακεραίων και εκτύπωση μέγιστης τιμής */ #include <stdio.h> #define N 10 /* όπου "Ν" αντικατέστησε με "10" */ int main(int argc, char* argv[]) { int elem[n]; /* πίνακας Ν ακεραίων */ int maxp; /* θέση μεγαλύτερου στοιχείου */ int i; /* μετρητής βρόγχου for */ 16 for (i=0; i<n; i++) { printf("enter int: "); scanf("%d", &elem[i]); } maxp = 0; for (i=1; i<n; i++) { if (elem[maxp] < elem[i]) { maxp = i; } } } printf("maximum is %d\n", elem[maxp]); return(0);

/* ανάποδη εκτύπωση εισόδου ως 79 χαρακτήρες ή '\n' */ #include <stdio.h> #define N 80 int main(int argc, char *argv[]) { char buf[n]; /* πίνακας χαρακτήρων */ int pos; /* θέση τελευταίου έγκυρου στοιχείου */ char c; /* βοηθητική μεταβλητή */ 17 pos=0; do { c = getchar(); buf[pos] = c; pos++; } while ((pos < N) && (c!= '\n')); } pos--; while (pos >= 0) { putchar(buf[pos]); pos--; } putchar('\n'); return(0);

Πίνακες πολλών διαστάσεων 18 Ένας πίνακας μπορεί να δηλωθεί ως Ν-διάστατος, π.χ. για 2 διαστάσεις a[5][10]. Η προσπέλαση στα στοιχεία του πίνακα γίνεται με αντίστοιχο τρόπο, π.χ. a[0][0] ή a[4][9]. Όπως και στους μονοδιάστατους πίνακες, η μνήμη δεσμεύεται συνεχόμενα για όλα τα στοιχεία. Η αποθήκευση γίνεται «σε σειρές», δηλαδή πρώτα αποθηκεύονται τα στοιχεία ως προς την τελευταία διάσταση, μετά ως προς την προ-τελευταία κλπ. a[n][m] a[i][j] b[ν*μ] b[i*m + j].

char a[2][3]; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] διεύθυνση 1 2 3 4 5 6 7 8 9 περιεχόμενα 0 0 1 1 0 0 0 1... 19

char a[2][3]; a[0][1] a[0][2] διεύθυνση περιεχόμενα 0 0 1 1 0 0 0 1 a[0][0]='a'; 2 0 1 1 0 0 0 0 1 a[0][0] 3 a[1][0] a[1][1] a[1][2] 1 4 5 6 7 8 9 20...

char a[2][3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 21 a[0][0]='a'; a[0][1]='b'; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 9...

char a[2][3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 22 a[0][0]='a'; a[0][1]='b'; a[0][2]='c'; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 9...

char a[2][3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 23 a[0][0]='a'; a[0][1]='b'; a[0][2]='c'; a[1][0]='d'; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 0 9...

char a[2][3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 24 a[0][0]='a'; a[0][1]='b'; a[0][2]='c'; a[1][0]='d'; a[1][1]='e'; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1 9...

char a[2][3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 25 a[0][0]='a'; a[0][1]='b'; a[0][2]='c'; a[1][0]='d'; a[1][1]='e'; a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 a[1][2]='f'; 9...

char a[2*3]; a[0*3+0] a[0*3+1] a[0*3+2] a[1*3+0] a[1*3+1] a[1*3+2] διεύθυνση 1 2 3 4 5 6 7 8 9 περιεχόμενα 0 0 1 1 0 0 0 1... 26

char a[2*3]; διεύθυνση περιεχόμενα 0 0 1 1 0 0 0 1 a[0]='a'; 2 0 1 1 0 0 0 0 1 a[0*3+0] 3 a[0*3+1] a[0*3+2] a[1*3+0] a[1*3+1] a[1*3+2] 1 4 5 6 7 8 9 27...

char a[2*3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 28 a[0]='a'; a[1]='b'; a[0*3+0] a[0*3+1] a[0*3+2] a[1*3+0] a[1*3+1] a[1*3+2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 9...

char a[2*3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 29 a[0]='a'; a[1]='b'; a[2]='c'; a[0*3+0] a[0*3+1] a[0*3+2] a[1*3+0] a[1*3+1] a[1*3+2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 9...

char a[2*3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 30 a[0]='a'; a[1]='b'; a[2]='c'; a[3]='d'; a[0*3+0] a[0*3+1] a[0*3+2] a[1*3+0] a[1*3+1] a[1*3+2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 0 9...

char a[2*3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 31 a[0]='a'; a[1]='b'; a[2]='c'; a[3]='d'; a[4]='e'; a[0*3+0] a[0*3+1] a[0*3+2] a[1*3+0] a[1*3+1] a[1*3+2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1 9...

char a[2*3]; διεύθυνση 1 περιεχόμενα 0 0 1 1 0 0 0 1 32 a[0]='a'; a[1]='b'; a[2]='c'; a[3]='d'; a[4]='e'; a[0*3+0] a[0*3+1] a[0*3+2] a[1*3+0] a[1*3+1] a[1*3+2] 2 3 4 5 6 7 8 0 1 1 0 0 0 0 1 0 1 1 0 0 0 1 0 0 1 1 0 0 0 1 1 0 1 1 0 0 1 0 0 0 1 1 0 0 1 0 1 0 1 1 0 0 1 1 0 a[5]='f'; 9...

Συμβολοσειρές / σειρές χαρακτήρων (strings) Strings υλοποιούνται ως πίνακες από char Τουλάχιστον ένα στοιχείο είναι ίσο με την τιμή '\0' (ή '\0x00' ή 0). Το πρώτο στοιχείο με την τιμή '\0' ορίζει το τέλος του string Όχι απαραίτητα και του πίνακα χαρακτήρων, τα υπόλοιπα στοιχεία του οποίου δεν λαμβάνονται υπόψη στις διάφορες πράξεις string. Ένα πρόγραμμα που χρησιμοποιεί strings υποθέτει πως τερματίζονται με '\0' και αν δημιουργεί strings φροντίζει αυτά να τερματίζονται με '\0'. Η βιβλιοθήκη string περιέχει αρκετές συναρτήσεις για τις πιο συχνές πράξεις με strings ώστε να μην χρειάζεται να υλοποιηθούν από τον προγραμματιστή. 33

char str1[] = {'w', 'i', 'n'}; char str2[] = {'w', 'i', 'n', '\0'}; /* "win" */ 34 char str3[] = {'w', 'i', 'n', '\0', 'x'}; /* "win" */ char str4[]="win"; /* "win" */ char str5[7]; str5[0] = str1[1]; /* 'i' */ str5[1] = ' '; /* ' ' */ str5[2] = str1[0]; /* 'w' */ str5[3] = str2[1]; /* 'i' */ str5[4] = str3[2]; /* 'n' */ str5[5] = '\0'; /* '\0' */ str5[6] = 'x'; /* 'x' */

Ανάγνωση και εκτύπωση strings Μπορούμε να τα υλοποιήσουμε (εμείς) χαρακτήρα προς χαρακτήρα μέσω της getchar και putchar. Ή να χρησιμοποιήσουμε την scanf και printf με τον αντίστοιχο προσδιορισμό, που είναι το "%s". Η printf σταματά την εκτύπωση των περιεχομένων του πίνακα όταν συναντήσει στοιχείο με τιμή '\0'. Η scanf σταματά την ανάγνωση χαρακτήρων (και την αποθήκευση τους στον πίνακα) όταν βρεθεί «λευκός» χαρακτήρας Προσοχή: μπορεί να γίνει αποθήκευση εκτός ορίων του πίνακα! Αντίθετα με ότι γνωρίζουμε, στην scanf δεν δίνουμε σαν παράμετρο την διεύθυνση της μεταβλητής πίνακα Το γιατί προσεχώς... 35

#include<stdio.h> int main(int argc, char *argv[]) { char str[4]; printf("enter string:"); scanf("%s",str); printf("you entered %s\n",str); σαν παράμετρος δίνεται απ ευθείας η μεταβλητή (πίνακας) αντί (όπως «θα έπρεπε») η διεύθυνση της (δεν γράφουμε &str) 36 } printf("enter string:"); scanf("%3s",str); printf("you entered %s\n",str); return(0); αν ο χρήστης εισάγει συμβολοσειρά με περισσότερους από 3 χαρακτήρες, θα υπάρξει πρόβλημα καθώς αυτοί θα αποθηκευτούν σε θέσεις εκτός ορίων του πίνακα... διαβάζει το πολύ 3 χαρακτήρες (εκτός από το '\0' που θα αποθηκευτεί ως τελευταίος χαρακτήρας της συμβολοσειράς)

/* μήκος string s */ 37 #include <stdio.h> #define N 32 int main(int argc, char *argv[]) { int len; char str[n]; printf("enter string:"); scanf("%31s", str); for (len=0; str[len]!='\0'; len++) {} } printf("length of %s is %d\n", str, len); return(0);

/* ανάποδη αντιγραφή του in στο out */ #include <stdio.h> #define N 32 int main(int argc, char *argv[]) { int len,pos; char in[n],out[n]; 38 printf("enter string:"); scanf("%31s", in); /* βρες το τέλος του in */ for (len=0; in[len]!='\0'; len++) {} /* αντέγραψε ανάποδα στο out */ for (pos=0,len--; len>=0; pos++,len--) { out[pos] = in[len]; } out[pos] = '\0'; /* τερμάτισε το out */ printf("%s in reverse is %s\n", in, out); return(0); }

/* αντιγραφή του in1 "και" του in2 στο out */ #include <stdio.h> #define N 32 int main(int argc, char *argv[]) { int i, j; char in1[n], in2[n], out[2*n-1]; 39 printf("enter string:"); scanf("%31s", in1); printf("enter string:"); scanf("%31s", in2); /* αντέγραψε το in1 στο out */ for (i=0; in1[i]!='\0'; i++) { out[i] = in1[i]; /* αντέγραψε το in2 στο out */ } for (j=0; in2[j]!='\0'; j++,i++) { out[i] = in2[j]; } out[i]='\0'; /* τερμάτισε το out */ } printf("%s + %s = %s\n", in1, in2, out); return(0);

Συναρτήσεις βιβλιοθήκης #include <string.h> char *strcat(char *s1, const char *s2); char *strchr(const char *s, int c); int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); char *strcpy(char *s1, const char *s2); char *strdup(const char *s2); size_t strlen(const char *s); 40 #include <stdlib.h> int atoi(const char *s); double atof(const char *s); #include <ctype.h> int isalpha(char c); int isupper(char c); int islower(char c); int isspace(char c); int isdigit(char c);

sprintf για τη δημιουργία format string #define SIZE 100 char word[size]; Όταν διαβάζουμε ένα string με scanf πρέπει ΠΑΝΤΑ να προσδιορίζουμε μέγιστο πλήθος χαρακτήρων που επιτρέπεται να αποθηκευτούν σε αυτό Θέλουμε το scanf να μπορεί να λειτουργήσει σωστά ακόμη κι αν αλλάξει αυτό το πλήθος. Άρα, πρέπει να βρούμε τρόπο να κατασκευάσουμε το format string με βάση το επιθυμητό μέγεθος!

sprintf για τη δημιουργία format string #define SIZE 100 char word[size]; θέλουμε να κατασκευάσουμε το "%99s" #define SIZE 50 char word[size]; θέλουμε να κατασκευάσουμε το "%49s"

sprintf για τη δημιουργία format string #define SIZE 100 char word[size]; θέλουμε να κατασκευάσουμε το "%99s" Από τι αποτελείται? Το σύμβολο % Ένα ακέραιο με τιμή SIZE-1 Το γράμμα s printf("%%"); printf("%d", SIZE-1); printf("s");

sprintf για τη δημιουργία format string printf("%%"); printf("%d", SIZE-1); printf("s"); printf("%%%ds", SIZE-1); Με τον ίδιο τρόπο λειτουργεί η sprintf μόνο που γράφει σε string (και όχι στην οθόνη!) sprintf(formatstring, "%%%ds", SIZE-1);

sprintf για τη δημιουργία format string sprintf(formatstring, "%%%ds", SIZE-1); Πόσο μεγάλο μπορεί να είναι το formatstring?: 1 θέση για το % 1 θέση για το s 1 θέση για το '\0' 10 θέσεις για το μέγεθος (ακέραιος 10 ψηφίων το πολύ) char formatstring[13]; char word[size]; sprintf(formatstring, "%%%ds", SIZE-1); scanf(formatstring, word);