Πξνγξακκαηηζκόο Ι Δείθηεο Κσλζηαληίλνο Τζεξπέο (βαζηζκέλν ζηηο δηαθάλεηεο ηνπ θ. Δεκήηξε Μηραήι) Τκήκα Πιεξνθνξηθήο θαη Τειεκαηηθήο Φαξνθόπεην Παλεπηζηήκην
Τη είλαη ν δείθηεο Έλαο δείθηεο είλαη κηα κεηαβιεηή πνπ πεξηέρεη κηα δηεύζπλζε κλήκεο. Θπκεζείηε πσο ε κλήκε κνηάδεη κε έλαλ κνλνδηάζηαην πίλαθα. Σην παξάδεηγκα πνπ βιέπεηε ε ζέζε κλήκεο 1024 πεξηέρεη ηελ ηηκή 99. 0 4 12 16 20 24 2 32 36 40 1024 00000000 00000000 00000000 01100011 Φαξνθόπεην Παλεπηζηήκην 2/59
Δήισζε Δείθηε ζε C Τν "*" ρξεζηκνπνηείηαη γηα λα δειώζεη δείθηε: int * p ; Η παξαπάλσ δήισζε δεκηνπξγεί κηα κεηαβιεηή ηύπνπ δείθηε ζε αθέξαην (pointer to int). Φαξνθόπεην Παλεπηζηήκην 3/59
Δήισζε Δείθηε ζε C Τν "*" ρξεζηκνπνηείηαη γηα λα δειώζεη δείθηε: int * p ; Η παξαπάλσ δήισζε δεκηνπξγεί κηα κεηαβιεηή ηύπνπ δείθηε ζε αθέξαην (pointer to int). Τν όλνκα απηήο ηεο κεηαβιεηήο είλαη p. Φαξνθόπεην Παλεπηζηήκην 3/59
Δήισζε Δείθηε ζε C Τν "*" ρξεζηκνπνηείηαη γηα λα δειώζεη δείθηε: int * p ; Η παξαπάλσ δήισζε δεκηνπξγεί κηα κεηαβιεηή ηύπνπ δείθηε ζε αθέξαην (pointer to int). Τν όλνκα απηήο ηεο κεηαβιεηήο είλαη p. Η ηηκή ηεο κεηαβιεηήο είλαη κία δηεύζπλζε κλήκεο. Φαξνθόπεην Παλεπηζηήκην 3/59
Αλάζεζε Τηκήο ζε Δείθηε Όπσο όιεο ηηο άιιεο κεηαβιεηέο ζηελ C πξέπεη λα αξρηθνπνηήζνπκε έλαλ δείθηε. Γηα λα βξνύκε ηελ δηεύζπλζε κλήκεο κηαο κεηαβιεηήο ρξεζηκνπνηνύκε ηνλ ηειεζηή &. int main ( ) { int a ; int * ptr ; a = 99; ptr = &a ; return 0 ; Φαξνθόπεην Παλεπηζηήκην 4/59
Αλάζεζε Τηκήο ζε Δείθηε Γηα λα βξνύκε ηελ δηεύζπλζε κλήκεο κηαο κεηαβιεηήο ρξεζηκνπνηνύκε ηνλ 0 ηειεζηή &. 4 int main ( ) { int a ; int * ptr ; a = 99; ptr = &a ; 1024 99 a 12 16 return 0 ; 1024 ptr Με απηόλ ηνλ ηξόπν ν δείθηεο ptr "δείτνει" ζηελ κεηαβιεηή a. Η ηιμή ηης μεηαβληηής ptr είναι η διεύθσνζη μνήμης ηης μεηαβληηής a. Φαξνθόπεην Παλεπηζηήκην 5/59
Η Τηκή 0 θαη ε Τηκή NULL Γηα λα κελ δείρλεη έλαο δείθηεο θάπνπ πξέπεη λα ηνπ αλαζέζνπκε ηελ ηηκή 0. Η βηβιηνζήθε ηεο C νξίδεη κηα ζηαζεξά κε όλνκα NULL γηα λα ζπκβνιίζεη ην γεγνλόο πσο έλαο δείθηεο δελ δείρλεη πνπζελά. int main ( ) { int * ptr = 0; // return 0 ; ή #include < s t d i o. h> int main ( ) { int * ptr = NULL ; // return 0 ; Φαξνθόπεην Παλεπηζηήκην 6/59
Τειεζηήο Έκκεζεο Αλαθνξάο Indirection/dereferencing operator Μπνξνύκε λα αθνινπζήζνπκε έλα δείθηε κε ηελ ρξήζε ηνπ ηειεζηή έκκεζεο αλαθνξάο, "*"; int main ( ) { 0 int a ; 4 int * ptr ; a = 99; 16 ptr = &a ; printf ( "%d\n", * ptr ) ; 12 return 0 ; 1024 99 a Η έκθραζη *ptr μας δίνει ηην μεηαβληηή ζηην θέζη μνήμης ποσ δείτνει ο δείκηης ptr. Σηελ πξνθεηκέλε πεξίπησζε είλαη ε κεηαβιεηή a. 2404 1024 ptr Φαξνθόπεην Παλεπηζηήκην 7/59
Πξνηεξαηόηεηα Τειεζηώλ 1 2 3 4 5 6 7 9 παρενθέζεις: () [] expr++ expr Υπνινγίδνληαη πξώηα, από ηα αξηζηεξά πξνο ηα δεμηά. Εάλ ππάξρνπλ έλζεηεο ππνινγίδνληαη πξώηα νη εζσηεξηθέο. μοναδιαίοι ηελεζηές: + ++expr expr! * & Υπνινγίδνληαη από δεμηά πξνο ηα αξηζηεξά. πολλαπλαζιαζμός, διαίρεζη και σπόλοιπο: * / % Υπνινγίδνληαη δεύηεξα από αξηζηεξά πξνο ηα δεμηά. πρόζθεζη, αθαίρεζη: + Εάλ ππάξρνπλ πνιινί, ππνινγίδνληαη από ηα αξηζηεξά πξνο ηα δεμηά. Στεζιακοί: < > <= >= Υπνινγίδνληαη από ηα αξηζηεξά πξνο ηα δεμηά. Ιζόηηηας: ==!= Υπνινγίδνληαη από ηα αξηζηεξά πξνο ηα δεμηά. λογικό AND: && Από αξηζηεξά πξνο ηα δεμηά. λογικό OR: Από αξηζηεξά πξνο ηα δεμηά. εκτώρηζης: = += = *= /= %= Από δεμηά πξνο ηα αξηζηεξά. Φαξνθόπεην Παλεπηζηήκην /59
Τειεζηήο Έκκεζεο Αλαθνξάο Indirection/dereferencing operator 1 2 3 4 5 6 7 9 10 11 12 13 int main ( ) { int a, b ; int * ptr_to_a, * ptr_to_b ; a = 99; ptr_to_a = &a ; ptr_to_b = &b ; * ptr_to_b = * ptr_t_a ; printf ( "%d\n",* ptr_to_b ) ; return 0 ; 0 4 12 16 1024 99 a 102 b 2404 1024 ptr to a 102 ptr to b Η γξακκή 10 είλαη νπζηαζηηθά ε γξακκή: 10 b = a; ελώ ε 11 είλαη 12 printf ( "%d\n", b ) ; Φαξνθόπεην Παλεπηζηήκην 9/59
Τειεζηήο Έκκεζεο Αλαθνξάο Indirection/dereferencing operator 1 2 3 4 5 6 7 9 10 11 12 13 int main ( ) { int a, b ; int * ptr_to_a, * ptr_to_b ; a = 99; ptr_to_a = &a ; ptr_to_b = &b ; * ptr_to_b = * ptr_t_a ; printf ( "%d\n",* ptr_to_b ) ; return 0 ; 0 4 12 16 1024 99 a 102 99 b 2404 1024 ptr to a 102 ptr to b Η γξακκή 10 είλαη νπζηαζηηθά ε γξακκή: 10 b = a; ελώ ε 11 είλαη 12 printf ( "%d\n", b ) ; Φαξνθόπεην Παλεπηζηήκην 9/59
Δείθηεο Άιισλ Τύπσλ Σηελ γιώζζα C κπνξνύκε λα έρνπλ δείθηεο ζε νπνηαδήπνηε κεηαβιεηή αλεμάξηεηα από ηνλ ηύπν ηεο. Πξέπεη όκσο λα δειώζνπκε ηνλ δείθηε αλάινγα. 1 2 3 4 5 6 7 9 10 11 #include < s t d i o. h> int main ( ) { double pi ; double * ptr = &pi ; * ptr = 3.14159265; printf ( "%lf\n", pi ) ; return 0 ; Αληίζηνηρα θαη κε ηνπο ππόινηπνπο ηύπνπο. Φαξνθόπεην Παλεπηζηήκην 10/59
Πνιινί Δείθηεο, ζε κηα Μεηαβιεηή 1 int main ( ) { 2 int a ; 3 int * ptr1, * ptr2 ; 4 5 a = 99; 6 ptr1 = &a ; 7 ptr2 = &a ; 9 (*ptr1)++; 10 (*ptr2)++; 11 12 printf ( "%d\n", a ) ; 13 return 0 ; 14 0 4 12 16 1024 99 a 2404 1024 ptr1 240 1024 ptr2 Η γξακκέο 10 θαη 11 είλαη νπζηαζηηθά ε γξακκή: a++; Φαξνθόπεην Παλεπηζηήκην 11/59
Πνιινί Δείθηεο, ζε κηα Μεηαβιεηή 1 int main ( ) { 2 int a ; 3 int * ptr1, * ptr2 ; 4 5 a = 99; 6 ptr1 = &a ; 7 ptr2 = &a ; 9 (*ptr1)++; 10 (*ptr2)++; 11 12 printf ( "%d\n", a ) ; 13 return 0 ; 14 0 4 12 16 1024 101 a 2404 1024 ptr1 240 1024 ptr2 Η γξακκέο 10 θαη 11 είλαη νπζηαζηηθά ε γξακκή: a++; Τν πξόγξακκα ζα εθηππώζεη 101. Φαξνθόπεην Παλεπηζηήκην 11/59
Εθηύπσζε ηεο Τηκή Ελόο Δείθηε Η ηηκή ελόο δείθηε είλαη κηα δηεύζπλζε κλήκεο. Γηα λα ηππώζνπκε ηελ ηηκή ελόο δείθηε ε printf() καο παξέρεη ηελ επηινγή %p. 1 2 3 4 5 6 7 9 10 #include < s t d i o. h> int main ( ) { int a = 5 ; int * ptr = &a ; printf ( "address of a is %p\n", ptr ) ; return 0 ; Σην ζύζηεκα ηνπ νκηιεηή ην πξόγξακκα ηππώλεη: address of a is 0x7fff5bc2d5cc Φαξνθόπεην Παλεπηζηήκην 12/59
Σπρλά Λάζε Δήισζε Πνιιαπιώλ Δεηθηώλ Πξνζνρή όηαλ νξίδεηε πνιινύο δείθηεο ζηελ ίδηα γξακκή. int * ptr1, ptr2, ptr3 ; Τν αζηεξάθη αλήθεη νπζηαζηηθά ζην όλνκα θαη όρη ζηνλ ηύπν. Η παξαπάλσ γξακκή νξίδεη 1 δείθηε ζε αθέξαην κε όλνκα ptr1 θαη δύν αθεξαίνπο κε νλόκαηα ptr2 θαη ptr3. Γηα λα νξίζνπκε 3 δείθηεο ζε αθέξαην πξέπεη λα γξάςνπκε: int * ptr1, * ptr2, * ptr3 ; Φαξνθόπεην Παλεπηζηήκην 13/59
Σπρλά Λάζε Δείθηεο θαη ην Αληηθείκελν 1 2 3 4 5 6 7 9 10 11 12 13 14 15 #include < s t d i o. h> int main ( ) { int a = 10, b = 20; int * p1,* p2 ; p1 = &a ; p2 = &b ; * p1 = * p2 ; p1 = p2 ; * p1 = * p2 ; return 0 ; ε γξακκή 10 είλαη ηζνδύλακε κε a = b. ε γξακκή 11 αλαζέηεη ηελ δηεύζπλζε ηνπ b ζηνλ δείθηε p1. Οη δύν δείθηεο δείρλνπλ ζην b. ε γξακκή 12 είλαη ηζνδύλακε κε b = b. Φαξνθόπεην Παλεπηζηήκην 14/59
Σπρλά Λάζε Πξνηεξαηόηεηα Τειεζηώλ 1 2 3 4 5 6 7 9 10 11 12 13 14 15 16 17 1 #include < s t d i o. h> int main ( ) { int x, *p; p = &x; /* initialise pointer */ *p = 0; /* set x to zero */ printf ( "x is %d\n", x ) ; printf ( "*p is %d\n", *p); *p += 1; /* increment what p points to */ printf ( "x is %d\n", x ) ; (*p)++; /* increment what p points to */ printf ( "x is %d\n", x ) ; return 0 ; Πξνζνρή ε γξακκή 14 ζέιεη παξελζέζεηο, αθνύ ν ηειεζηήο postfix ++ έρεη κεγαιύηεξε πξνηεξαηόηεηα από ηνλ ηειεζηή *. Φαξνθόπεην Παλεπηζηήκην 15/59
Κιήζε Σπλάξηεζεο Μέζσ Αλαθνξάο Με ηελ ρξήζε δεηθηώλ κπνξνύκε λα θάλνπκε θιήζε κέζσ αλαθνξάο ζηελ C. Θπκεζείηε πσο ζηελ C νη παξάκεηξνη κηαο ζπλάξηεζεο αληηγξάθνληαη ζε πξνζσξηλέο ηνπηθέο κεηαβιεηέο πξηλ θιεζεί ε ζπλάξηεζε. Θα θάλνπκε κηα κηθξή παξέλζεζε θαη ζα εμεγήζνπκε ηνλ ηξόπν ιεηηνπξγίαο ησλ θιήζεσλ ζπλαξηήζεσλ. Φαξνθόπεην Παλεπηζηήκην 16/59
Κιήζε Σπλαξηήζεσλ Stack Frame Γηα λα κπνξνύκε λα ππνζηεξίδνπκε θιήζε ζπλαξηήζεσλ ν κεηαγισηηηζηήο παξάγεη θώδηθα πνπ ρξεζηκνπνηεί ηελ ιεγόκελε ζηνίβα θιήζεσλ. Η ζηνίβα θιήζεσλ είλαη ππεύζπλε γηα λα απνζεθεύεη δηάθνξεο πιεξνθνξίεο όπσο: ηελ δηεύζπλζε επηζηξνθήο κεηά ηελ ζπλάξηεζε, ηηο παξακέηξνπο ηεο ζπλάξηεζεο, ηηο ηνπηθέο κεηαβιεηέο ηεο ζπλάξηεζεο, θ.η.ι Φαξνθόπεην Παλεπηζηήκην 17/59
Κιήζε Σπλαξηήζεσλ Stack Frame Κάζε θνξά πνπ θαιείηαη κηα ζπλάξηεζε πξνζηίζεηαη ζηελ θνξπθή ηεο ζηνίβαο κηα εγγξαθή πνπ πεξηέρεη ηηο ηνπηθέο κεηαβιεηέο ηεο ζπλάξηεζεο ηελ δηεύζπλζε επηζηξνθήο ηηο παξακέηξνπο ηεο ζπλάξηεζεο Μόιηο ηειεηώζεη ε εθηέιεζε ηεο ζπλάξηεζεο αθαηξείηαη ε ηειεπηαία εγγξαθή, θαη άξα θαηαζηξέθνληαη όιεο νη ηνπηθέο κεηαβιεηέο θαη παξάκεηξνη. Ο θώδηθαο δεκηνπξγίαο θαη θαηαζηξνθήο ησλ εγγξαθώλ απηώλ παξάγεηαη από ηνλ κεηαγισηηηζηή θαη πξνζηίζεηαη ζε θάζε ζεκείν ηνπ πξνγξάκκαηνο πνπ γίλεηαη θιήζε ζπλάξηεζεο. ηνπηθέο κεηαβιεηέο ζπλάξηεζεο δηεύζπλζε επηζηξνθήο παξάκεηξνη ζπλάξηεζεο ηνπηθέο κεηαβιεηέο ζπλάξηεζεο δηεύζπλζε επηζηξνθήο παξάκεηξνη ζπλάξηεζεο Φαξνθόπεην Παλεπηζηήκην 1/59
Κιήζε Σπλάξηεζεο Μέζσ Αλαθνξάο Γηα λα πινπνηήζνπκε θιήζε κέζσ αλαθνξάο ζηελ C ρξεζηκνπνηνύκε δείθηεο. Δίλνπκε σο παξάκεηξν ζε κηα ζπλάξηεζε έλα δείθηε ζηελ κεηαβιεηή πνπ ζέινπκε λα πεξάζνπκε ζηελ ζπλάξηεζε. Μέζσ ηνπ δείθηε αιιάδνπκε ηελ ηηκή ηεο κεηαβιεηήο πνπ ζέινπκε Μόιηο επηζηξέςεη ε ζπλάξηεζε ε παξάκεηξνο (δείθηεο) ζα θαηαζηξαθεί αιιά ε κεηαβιεηή καο ζα έρεη αιιάμεη θαλνληθά ηηκή. Φαξνθόπεην Παλεπηζηήκην 19/59
Κιήζε Σπλάξηεζεο Μέζσ Αλαθνξάο 1 2 3 4 5 6 7 9 10 11 12 13 14 #include < s t d i o. h> void increase ( int * x ) { (*x)++; int main ( ) { int a = 1 ; increase(&a ) ; printf ( "%d\n", a ) ; return 0 ; Τν παξαπάλσ πξόγξακκα ηππώλεη 2. Η κεηαβιεηή x δείρλεη ζηελ κεηαβιεηή πνπ ζέινπκε λα πεξάζνπκε σο παξάκεηξν. Μέζα ζηελ ζπλάξηεζε αιιάδνπκε ηελ κεηαβιεηή καο ρξεζηκνπνηώληαο *x. Με ην ηέινο ηεο ζπλάξηεζεο ε ηνπηθή κεηαβιεηή x ζα θαηαζηξαθεί, αιιά ε κεηαβιεηή a ζα έρεη αιιάμεη ηηκή. Φαξνθόπεην Παλεπηζηήκην 20/59
Κιήζε Σπλάξηεζεο Μέζσ Αλαθνξάο 1 2 3 4 5 6 7 9 10 11 12 13 14 15 16 17 1 19 #include < s t d i o. h> void swap ( int * a, int * b ) { int tmp = * a ; *a = *b; *b = tmp; int main ( ) { int x = 1, y = 2; swap(&x, &y ) ; printf ( "x = %d\n", x ) ; printf ( "y = %d\n", y ) ; return 0 ; Τν πξόγξακκα ηππώλεη x = 2 y = 1 Φαξνθόπεην Παλεπηζηήκην 21/59
Δείθηεο θαη const Θπκεζείηε πσο κε ηελ δεζκεπκέλε ιέμε const ιέκε ζηνλ κεηαγισηηηζηή πσο θάηη δελ πξέπεη λα αιιάμεη. Επεηδή όηαλ αζρνινύκαζηε κε δείθηεο έρνπκε νπζηαζηηθά 2 αληηθείκελα: 1 2 έλα δείθηε θαη εθεί πνπ δείρλεη ν δείθηεο ε ρξήζε ηνπ const είλαη ιίγν πην πνιύπινθε. Φαξνθόπεην Παλεπηζηήκην 22/59
Δείθηεο θαη const Υπάξρνπλ 3 ρξήζεηο: 1 2 3 const int * ptr ; Δείθηεο ζε ζηαζεξό αθέξαην. Ο δείθηεο κπνξεί λα αιιάμεη ηηκή, ν αθέξαηνο όρη. int * const ptr ; Σηαζεξόο δείθηεο ζε αθέξαην. Ο δείθηεο δελ κπνξεί λα αιιάμεη ηηκή, ν αθέξαηνο κπνξεί. const int * const ptr ; Σηαζεξόο δείθηεο ζε ζηαζεξό αθέξαην. Ούηε ν δείθηεο αιιά νύηε θαη ν αθέξαηνο κπνξεί λα αιιάμεη ηηκή. Είλαη εύθνιν λα δηαθξίλεηαη ηηο πεξηπηώζεηο θνηηώληαο δεμηά θαη αξηζηεξά ηνπ αζηεξίζθνπ γηα ηελ δεζκεπκέλε ιέμε const. Φαξνθόπεην Παλεπηζηήκην 23/59
Δείθηεο θαη const Παξάδεηγκα 1 2 3 4 5 6 7 9 10 11 12 #include < s t d i o. h> int main ( ) { const int y = 5 ; const int x = 3 ; const int * ptr = &y ; (*ptr)++; ptr = &x ; // ok / / NO! Ο κεηαγισηηηζηήο δελ καο επηηξέπεη λα γξάςνπκε ηελ γξακκή 9. Φαξνθόπεην Παλεπηζηήκην 24/59
Δείθηεο θαη const Παξάδεηγκα 1 2 3 4 5 6 7 9 10 11 12 #include < s t d i o. h> int main ( ) { int y = 5 ; int x = 3 ; int * const ptr = &y ; (*ptr)++; ptr = &x ; // ok / / NO! Ο κεηαγισηηηζηήο δελ καο επηηξέπεη λα γξάςνπκε ηελ γξακκή 11. Φαξνθόπεην Παλεπηζηήκην 25/59
Δείθηεο θαη const Παξάδεηγκα 1 2 3 4 5 6 7 9 10 11 12 #include < s t d i o. h> int main ( ) { const int y = 5 ; const int x = 3 ; const int * const ptr = &y ; (*ptr)++; ptr = &x ; / / NO! / / NO! Ο κεηαγισηηηζηήο δελ καο επηηξέπεη λα γξάςνπκε ηηο γξακκέο 9 θαη 11. Φαξνθόπεην Παλεπηζηήκην 26/59
Λάζε θαη casts Πξνζνρή κε ηα casts. 1 2 3 4 5 6 7 9 10 11 12 13 14 15 16 17 1 19 #include < s t d i o. h> int main ( ) { int i ; const int ci = 1 2 3 ; const int * cpi ; int * ncpi ; cpi = &ci ; ncpi = &i ; cpi = ncpi ; // pointer to const // allowed // this needs a cast usually BIG MISTAKE ncpi = ( int*)cpi; * ncpi = 0; / / UNDEFINED BEHAVIOR!! Φαξνθόπεην Παλεπηζηήκην 27/59
Δείθηεο θαη Πίλαθεο Οη πίλαθεο θαη νη δείθηεο είλαη πνιύ ζηελά ζπλδεδεκέλνη ζηελ C. Γηα λα δειώζνπκε έλα πίλαθα αθεξαίσλ κεγέζνπο 10 κε όλνκα a γξάθνπκε: int a [ 1 0 ] ; a: a[0] a[1] a[9] Φαξνθόπεην Παλεπηζηήκην 2/59
Δείθηεο θαη Πίλαθεο Εάλ ν pa είλαη έλαο δείθηεο ζε αθέξαην int * pa ; ηόηε ε αλάζεζε pa = &a [ 0 ] ; βάδεη ηνλ pa λα δείρλεη ζην κεδεληθό ζηνηρείν ηνπ πίλαθα a. pa : a: a[0] a[1] a[9] Φαξνθόπεην Παλεπηζηήκην 29/59
Δείθηεο θαη Πίλαθεο Από ηνλ νξηζκό, ε ηηκή κηαο κεηαβιεηήο ή έθθξαζεο ηύπνπ πίλαθα είλαη ε δηεύζπλζε ηνπ κεδεληθνύ ζηνηρείνπ ηνπ πίλαθα. Έηζη κεηά ηελ αλάζεζε pa = &a [ 0 ] ; ν pa θαη ν a έρνπλ αθξηβώο ηελ ίδηα ηηκή. Επεηδή ην όλνκα ελόο πίλαθα είλαη ζπλώλπκν κε ηελ ηνπνζεζία ηνπ κεδεληθνύ ηνπ ζηνηρείνπ, ε ηειεπηαία αλάζεζε κπνξεί λα γξαθεί θαη σο pa = a ; Φαξνθόπεην Παλεπηζηήκην 30/59
Δείθηεο θαη Πίλαθεο Επεηδή ην όλνκα ελόο πίλαθα είλαη ζπλώλπκν κε ηελ ηνπνζεζία ηνπ κεδεληθνύ ηνπ ζηνηρείνπ, κπνξνύκε λα θάλνπκε θαη dereference. 1 2 3 4 5 6 7 9 10 11 #include < s t d i o. h> int main ( ) { int a [ ] = {9,, 7, 6, 5, 4, 3, 2, 1; printf ( "%d\n", *a); *a = 11; printf ( "%d\n", a [ 0 ] ) ; return 0 ; Τν παξαπάλσ πξόγξακκα ηππώλεη 9 11 Φαξνθόπεην Παλεπηζηήκην 31/59
Δείθηεο θαη Πίλαθεο Έλαο δείθηεο κπνξεί λα δείρλεη ζε κηα κεηαβιεηή ελόο πίλαθα. #include < s t d i o. h> a ptr int main ( ) { int a [ ] = {9,, 7, 6, 5; int * ptr = &a [ 2 ] ; printf ( "%d\n", * ptr ) ; return 0 ; Τν παξαπάλσ πξόγξακκα ηππώλεη 7 Φαξνθόπεην Παλεπηζηήκην 32/59
Αξηζκεηηθή Δεηθηώλ Έρνληαο έλα δείθηε ζε έλα ζηνηρείν ελόο πίλαθα, κπνξνύκε λα θάλνπκε αριθμηηική δεικηών. #include < s t d i o. h> int main ( ) { int a [ ] = {9,, 7, 6, 5; int * ptr = &a [ 1 ] ; int * ptr1 = ptr + 2; printf ( "%d\n", * ptr ) ; printf ( "%d\n", * ptr1 ) ; a ptr ptr1 return 0 ; Τν παξαπάλσ πξόγξακκα ηππώλεη 6 Φαξνθόπεην Παλεπηζηήκην 33/59
Αξηζκεηηθή Δεηθηώλ Σηελ αξηζκεηηθή δεηθηώλ κπνξνύκε λα πξνζζέζνπκε ή λα αθαηξέζνπκε. Όηαλ γξάθνπκε p+1 όπνπ p είλαη έλαο δείθηεο, ην απνηέιεζκα είλαη έλαο δείθηεο πνπ δείρλεη κηα ζέζε κεηά ηελ ζέζε πνπ δείρλεη ν p. Πόζν καθξύηεξα δείρλεη ν p+1 από ηνλ p εμαξηάηαη από ηνλ ηύπν δεδνκέλσλ πνπ δείρλεη ν p. Εαλ ν p είλαη έλαο δείθηεο ζε αθεξαίνπο ηόηε ε ζέζε κλήκεο p+1 ζα είλαη 4 bytes κεηά ηελ ζέζε p. Εαλ όκσο ν p δείρλεη ζε char ηόηε ζα είλαη κόιηο 1 byte κεηά. Φαξνθόπεην Παλεπηζηήκην 34/59
Δείθηεο θαη Πίλαθεο Όηαλ γξάθνπκε a[i] ζηελ C, γίλεηαη ε κεηαηξνπή ζε *(a+i). Οη δύν απηέο κνξθέο είλαη ηζνδύλακεο. Φξεζηκνπνηώληαο ηνλ ηειεζηή & θαη ζηηο δύν κνξθέο πξνθύπηεη πσο ηα &a[i] a+i είλαη επίζεο ηζνδύλακα. a+i είλαη ε δηεύζπλζε ηνπ i ζηνηρείνπ κεηά ην a. Παξόκνηα έρνληαο έλα δείθηε pa = &a[0] ε έθθξαζε pa[2] είλαη ηζνδύλακε κε *(pa + 2). Άξα κπνξνύκε λα ρξεζηκνπνηήζνπκε έλα δείθηε κε ηνλ ηειεζηή []. Φαξνθόπεην Παλεπηζηήκην 35/59
Δείθηεο θαη Πίλαθεο Επεηδή γξάθνληαο a[i] ζηελ C, γίλεηαη ε κεηαηξνπή ζε *(a+i), ην ίδην γίλεηαη θαη γξάθνληαο i[a]. a[i] *((a) + (i)) *((i) + (a)) i[a] (ορισμός) (αντιμεταθετικότητα πρόσθεσης) (ορισμός) Απηό ην γεγνλόο επηηξέπεη λα γξάθνπκε "πεξίεξγν" θώδηθα ζε δηαγσληζκνύο "πεξίεξγνπ" θώδηθα C. Γηα παξάδεηγκα ε έθθξαζε 5["abcdef"] είλαη απόιπηα ζσζηή θαη είλαη νπζηαζηηθά ν ραξαθηήξαο 'f'. Φαξνθόπεην Παλεπηζηήκην 36/59
Αξηζκεηηθή Δεηθηώλ Αληηγξαθή Σπκβνινζεηξώλ 1 void mystrcpy ( char * dest, const char * src ) { 2 char * dp = &dest [ 0 ], 3 * sp = &src [ 0 ] ; 4 5 while ( * sp!= '\0') 6 * dp++ = * sp + + ; 7 * dp = '\0' ; 9 Η έθθξαζε *dp++ θάλεη dereference ηνλ δείθηε dp θαη κεηά θάλεη dp=dp+1. Γηα λα απμήζεη ηελ κεηαβιεηή πνπ δείρλεη ν dp πξέπεη λα γξαθεί σο (*dp)++. Φαξνθόπεην Παλεπηζηήκην 37/59
Αξηζκεηηθή Δεηθηώλ Αληηγξαθή Σπκβνινζεηξώλ Όηαλ θάλνπκε αξηζκεηηθή δεηθηώλ πξέπεη λα πξνζέρνπκε λα κελ μεθύγνπκε εθηόο πίλαθα. 1 2 3 4 5 6 7 9 10 #include < s t d i o. h> int main ( ) { int a [ ] = {1, 2, 3, 4, 5; int * p = &a [ 2 ] ; printf ( "%d\n", *(p + 4)); return 0 ; Επεηδή δελ γλσξίδνπκε ηη πεξηέρεη θαη ζε πνηνλ αλήθεη ε κλήκε εθηόο ηνπ πίλαθα, κπνξεί λα ζπκβεί νηηδήπνηε. Φαξνθόπεην Παλεπηζηήκην 3/59
Αξηζκεηηθή Δεηθηώλ Μηα κηθξή εμαίξεζε Όηαλ θάλνπκε αξηζκεηηθή δεηθηώλ κπνξνύκε λα ρξεζηκνπνηήζνπκε γηα ζύγθξηζε (όρη όκσο θαη λα θάλνπκε dereference) ηελ ζέζε πνπ αθνινπζεί ακέζσο κεηά ην ηέινο ελόο πίλαθα. 1 #include < s t d i o. h> 2 int main ( ) { 3 int a [ ] = {1, 4 2, 3, 4, 5; 5 6 int * it = &a [ 0 ], 7 * end = it + 5; 9 while ( it < end ) { printf ( "%d\n", * it + + ) ; 10 11 12 return 0 ; 13 14 a it end Φαξνθόπεην Παλεπηζηήκην 39/59
Αξηζκεηηθή Δεηθηώλ Μηα κηθξή εμαίξεζε 1 2 3 4 5 6 7 9 10 11 12 13 14 #include < s t d i o. h> int main ( ) { int a [ ] = {1, 2, 3, int * it = &a [ 0 ], * end = it + 5; while ( it < end ) { printf ( "%d\n", return 0 ; 4, 5; * it + + ) ; a it end Σηνλ παξαπάλσ θώδηθα πνπ ηππώλεη όια ηα ζηνηρεία ελόο πίλαθα, ν δείθηεο end δείρλεη ακέζσο κεηά ην ηέινο ηνπ πίλαθα. Είλαη επηηξεπηό λα θάλνπκε ηελ ζύγθξηζε it < end. Ο θώδηθαο είλαη ζσζηόο αξθεί λα κελ θάλνπκε πνηέ *end. Φαξνθόπεην Παλεπηζηήκην 39/59
Αξηζκεηηθή Δεηθηώλ Μπνξνύκε λα θάλνπκε θαη αθαίξεζε δεηθηώλ. a 1 #include < s t d i o. h> 2 3 int main ( ) { ptr2 4 int a [ ] = { 1, 2, 3, 4, 5 ; 5 int * ptr1 = &a [ 0 ], 6 * ptr2 = &a [ 4 ] ; 7 printf ( "%d", ptr2 ptr1 ) ; 9 10 return 0 ; 11 ptr1 Τη εθηππώλεη ν παξαπάλσ θώδηθαο; Φαξνθόπεην Παλεπηζηήκην 40/59
Δείθηεο θαη Πίλαθεο Υπάξρεη κηα δηαθνξά κεηαμύ ηνπ νλόκαηνο ελόο πίλαθα θαη ελόο δείθηε πνπ πξέπεη πάληα λα ζπκόκαζηε. Έλαο δείθηεο είλαη κηα κεηαβιεηή θαη άξα εθθξάζεηο όπσο pa = a ; ή pa + + ; είλαη ζσζηέο. Τν όλνκα ελόο πίλαθα όκσο δελ είλαη κεηαβιεηή θαη άξα νη αληίζηνηρεο a = pa; ή a++; δελ επηηξέπνληαη. Φαξνθόπεην Παλεπηζηήκην 41/59
Δείθηεο, Πίλαθεο θαη Σπλαξηήζεηο Όηαλ έλαο πίλαθαο δίλεηαη ζε κηα ζπλάξηεζε, νπζηαζηηθά δίλεηαη ε ζέζε ηνπ πξώηνπ ζηνηρείνπ ηνπ πίλαθα. Μέζα ζηελ ζπλάξηεζε, ε παξάκεηξνο είλαη ηνπηθή κεηαβιεηή, θαη άξα είλαη έλαο δείθηεο. Οη παξαθάησ δύν δειώζεηο είλαη ινηπόλ ηζνδύλακεο int strlen ( char s [ ] ) ; θαη int strlen ( char * s ) ; θαη θαιό είλαη λα ρξεζηκνπνηνύκε ηνλ δεύηεξν ηξόπν κηαο θαη εμεγεί ην γεγνλόο πσο ε παξάκεηξνο s είλαη δείθηεο θαη όρη πίλαθαο. Φαξνθόπεην Παλεπηζηήκην 42/59
Δείθηεο, Πίλαθεο θαη Σπλαξηήζεηο Είλαη δπλαηό λα πεξάζνπκε μέρος ενός πίνακα ζε κηα ζπλάξηεζε, πεξλώληαο έλα δείθηε ζηελ αξρή ηνπ ππνπίλαθα. Γηα παξάδεηγκα εάλ a είλαη έλαο πίλαθαο, ηόηε f(&a[2]) θαη f(a+2) πεξλάλε ζηελ ζπλάξηεζε ηελ δηεύζπλζε ηνπ ππνπίλαθα πνπ μεθηλά ζην a[2]. Φαξνθόπεην Παλεπηζηήκην 43/59
Δείθηεο, Πίλαθεο θαη Σπλαξηήζεηο Η ζπλάξηεζε κπνξεί λα γξαθεί σο f(int arr [ ] ) {... ή f(int * arr ) {... Η ζπλάξηεζε f δελ δηαθνξνπνηείηαη επεηδή ε παξάκεηξνο αλαθέξεηαη ζε θνκκάηη κεγαιύηεξνπ πίλαθα. Εάλ θάπνηνο είλαη ζίγνπξνο πσο ηα ζηνηρεία ππάξρνπλ, κπνξεί λα ρξεζηκνπνηήζεη θαη αξλεηηθέο δηεπζύλζεηο όπσο p[ 1] ή p[ 2]. Είλαη θπζηθά ιάζνο λα βγεί θάπνηνο εθηόο πίλαθα. Φαξνθόπεην Παλεπηζηήκην 44/59
Πίλαθεο Δεηθηώλ Όπσο κπνξνύκε λα έρνπκε πίλαθεο δηαθόξσλ ηύπσλ, κε ηνλ ίδην ηξόπν κπνξνύκε λα έρνπκε θαη πίλαθεο δεηθηώλ. Η ζύληαμε είλαη ιίγν πην πνιύπινθε. Η παξαθάησ εληνιή δειώλεη έλα πίλαθα κε 10 δείθηεο ζε αθεξαίνπο. int * a [ 1 0 ] ; Φαξνθόπεην Παλεπηζηήκην 45/59
Πίλαθεο Δεηθηώλ Παξάδεηγκα 1 #include < s t d i o. h> 2 3 int main ( ) { 4 int i ; 5 int a [ 5 ] = {0, 1, 2, 3, 4; 6 int * ptr [ 5 ] ; 7 for ( i = 0; i < 5; i++) 9 ptr [ i ] = &a[4 i ] ; 10 11 for ( i = 0; i < 5; i++) 12 printf ( "%2d", * ptr [ i ] ) ; 13 14 return 0 ; 15 a ptr Ο θώδηθαο ηππώλεη 4 3 2 1 0 Φαξνθόπεην Παλεπηζηήκην 46/59
Δείθηεο ζε Σπλαξηήζεηο Η C εθηόο από δείθηεο ζε ηύπνπο καο επηηξέπεη λα έρνπκε θαη δείθηεο ζε ζπλαξηήζεηο. Απηό είλαη επηηξεπηό αθνύ θαη νη ζπλαξηήζεηο είλαη θάπνπ θνξησκέλεο ζηελ κλήκε. Γηα λα δειώζνπκε έλα δείθηε ζε ζπλάξηεζε, ν ηύπνο ηνπ δείθηε πξέπεη λα πεξηγξάθεη ηηο παξακέηξνπο θαη ηνλ ηύπν επηζηξνθήο ηεο ζπλάξηεζεο. int (*ptr)(int, double ) ; Η παξαπάλσ εληνιή δειώλεη έλα δείθηε ζε ζπλάξηεζε πνπ πέξλεη σο παξακέηξνπο έλαλ int θαη έλαλ double θαη επηζηξέθεη int. Τν όλνκα ηνπ δείθηε είλαη ptr. Φαξνθόπεην Παλεπηζηήκην 47/59
Δείθηεο ζε Σπλαξηήζεηο Παξαθάησ δειώλνπκε έλα δείθηε κε όλνκα ptr πνπ κπνξεί λα δείρλεη ζε ζπλάξηεζε πνπ παίξλεη κηα παξάκεηξν ηύπνπ int θαη επηζηξέθεη void. 1 2 3 4 5 6 7 9 10 11 12 13 #include < s t d i o. h> void print ( int x ) { printf ( "%d\n", x ) ; int main ( ) { void (*ptr)(int ) ; ptr = &print ; return 0 ; Γηα λα δείμεη θάπνπ ν δείθηεο ρξεζηκνπνηνύκε ηνλ ηειεζηή δηεύζπλζεο &. Γηα παξάδεηγκα ptr = &print. Η C γηα επθνιία καο επηηξέπεη λα γξάςνπκε θαη ptr = print κε ην ίδην απνηέιεζκα. Φαξνθόπεην Παλεπηζηήκην 4/59
Δείθηεο ζε Σπλαξηήζεηο 1 2 3 4 5 6 7 9 10 11 12 13 14 #include < s t d i o. h> void print ( int x ) { printf ( "%d\n", x ) ; int main ( ) { void (*ptr)(int ) ; ptr = &print ; (*ptr)(5); return 0 ; Γηα λα ρξεζηκνπνηήζνπκε έλα δείθηε ζε ζπλάξηεζε ηνλ θάλνπκε dereference θαη δίλνπκε παξακέηξνπο, π.ρ (*ptr)(5). Η C γηα επθνιία καο επηηξέπεη λα γξάςνπκε θαη ptr(5) κε ην ίδην απνηέιεζκα. Φαξνθόπεην Παλεπηζηήκην 49/59
Δείθηεο ζε Σπλαξηήζεηο 1 #include < s t d i o. h> 2 3 void foo ( int x ) { 4 printf ( "foo %d\n", x ) ; 5 6 7 void bar ( int y ) { printf ( "bar %d\n", y ) ; 9 10 11 int main ( ) { 12 void (*ptr)(int ) ; 13 14 ptr = &foo ; 15 (*ptr )(5); 16 17 ptr = &bar ; 1 (*ptr )(5); 19 20 return 0 ; 21 Ο θώδηθαο θαιεί κέζσ ελόο δείθηε ηηο 2 ζπλαξηήζεηο foo() θαη bar(). Φαξνθόπεην Παλεπηζηήκην 50/59
Δείθηεο ζε Σπλαξηήζεηο Παξάκεηξνη Σπλαξηήζεσλ 1 #include < s t d i o. h> 2 3 void print ( int x, void (*ptr)(int)) { 4 (*ptr)(x ) ; 5 6 7 void foo ( int x ) { printf ( "foo %d\n", x ) ; 9 10 11 void bar ( int y ) { 12 printf ( "bar %d\n", y ) ; 13 14 15 int main ( ) { 16 print ( 5, &foo ) ; 17 print ( 5, &bar ) ; 1 19 return 0 ; 20 Μπνξνύκε λα πεξάζνπκε έλα δείθηε ζπλάξηεζεο σο παξάκεηξν ζε άιιε ζπλάξηεζε. Ο θώδηθαο θαιεί πξώηα ηελ foo() θαη κεηά ηελ bar(). Φαξνθόπεην Παλεπηζηήκην 51/59
Επηζηξνθή Δείθηε Σπλάξηεζεο Είλαη ιίγν πνιύπινθε ε ζύληαμε αιιά κπνξνύκε λα γξάςνπκε ην εμήο: float { (*getfunction(const char code )) ( float, float) // code here Πνπ νξίδεη κηα ζπλάξηεζε κε όλνκα getfunction ε νπνία παίξλεη σο παξάκεηξν έλα ραξαθηήξα ηύπνπ const char, επηζηξέθεη έλα δείθηε ζε ζπλάξηεζε πνπ έρεη 2 float παξακέηξνπο θαη κε ηελ ζεηξά ηεο επηζηξέθεη ηύπν float. Φαξνθόπεην Παλεπηζηήκην 52/59
Επηζηξνθή Δείθηε Σπλάξηεζεο Παξάδεηγκα 1 2 3 4 5 6 7 9 10 11 12 13 14 15 16 17 1 19 20 21 22 23 #include < s t d i o. h> float minus ( float f1, float f2 ){ return f1 f2 ; float plus ( float f1, float f2 ){ return f1+f2 ; float { (*getfunction(const char code )) ( float, float) if ( code == '+' ) return &plus ; else if ( code == '-' ) return &minus ; return NULL ; int main ( ) { float f ; f =(*getfunction('+'))(2.0,1.0); f =(*getfunction('-' )) ( f,1.0); printf ( "%f\n", f ) ; return 0 ; Φαξνθόπεην Παλεπηζηήκην 53/59
Πίλαθεο Δεηθηώλ Σπλαξηήζεσλ Μπνξνύκε λα έρνπκε θαη πίλαθεο κε δείθηεο ζπλαξηήζεσλ. Η ζύληαμε είλαη πάιη θάπσο παξάμελε. Παξαθάησ θαίλεηαη πώο κπνξνύκε λα δειώζνπκε έλα πίλαθα 10 ζέζεσλ πνπ θάζε ζέζε είλαη έλαο δείθηεο ζε κηα ζπλάξηεζε πνπ επηζηξέθεη int θαη παίξλεη 3 παξακέηξνπο float, char θαη char. int (*funcarr[10])(float, char, char ) ; Τν όλνκα ηνπ πίλαθα είλαη funcarr. Φαξνθόπεην Παλεπηζηήκην 54/59
Πίλαθεο Δεηθηώλ Σπλαξηήζεσλ 1 2 3 4 5 6 7 9 10 11 12 13 14 15 16 17 1 19 20 21 22 #include < s t d i o. h> void foo1 ( int x ){ printf ( "foo1 %d\n", x ) ; void foo2 ( int x ){ printf ( "foo2 %d\n", x ) ; void foo3 ( int x ){ printf ( "foo3 %d\n", x ) ; void foo4 ( int x ){ printf ( "foo4 %d\n", x ) ; int main ( ) { int i, j ; void (*farray [ 4 ] ) ( int) = { NULL ; farray [ 0 ]= &foo1 ; farray [ 1 ]= &foo2 ; farray [ 2 ]= &foo3 ; farray [ 3 ]= &foo4 ; for ( i = 0; i < 100; i++) for ( j = 0; j < 4; j++) (*farray[j ] ) ( i ) ; return 0 ; Φαξνθόπεην Παλεπηζηήκην 55/59
Δείθηεο ζε void Σην παξαθάησ πξόγξακκα 1 2 3 4 5 6 7 9 10 #include < s t d i o. h> int main ( ) { int c ; double * ptr ; ptr = &c ; return 0 ; ν κεηαγισηηηζηήο καο πξνεηδνπνηεί πσο test.c: In function main : test.c:: warning: assignment from incompatible pointer type Φαξνθόπεην Παλεπηζηήκην 56/59
Δείθηεο ζε void Η C καο παξέρεη έλα δείθηε ηύπνπ void πνπ κπνξεί λα δείμεη νπνπδήπνηε. 1 2 3 4 5 6 7 9 10 11 12 #include < s t d i o. h> int main ( ) { int c ; double k ; void * ptr ; ptr = &c ; ptr = &k ; return 0 ; Θα δνύκε πνπ ρξεζηκεύεη ζε επόκελεο δηαιέμεηο. Φαξνθόπεην Παλεπηζηήκην 57/59
Δείθηεο ζε Δείθηεο Γηα λα δειώζνπκε έλα δείθηε πνπ λα δείρλεη ζε κηα κεηαβιεηή πνπ είλαη θαη απηή δείθηεο πξέπεη λα ρξεζηκνπνηήζνπκε ηελ παξαθάησ ζύληαμε. int * * x ; Θα ήηαλ πην επδηάθξηην εαλ γξάθακε int* *x γηα λα θαηαιάβνπκε πσο ν x είλαη έλαο δείθηεο πνπ δείρλεη ζε έλα δείθηε αθεξαίσλ. Φαξνθόπεην Παλεπηζηήκην 5/59
Δείθηεο ζε Δείθηεο 1 #include < s t d i o. h> 2 3 int main ( ) { 4 int a [ 5 ] = {1, 2, 3, 4, 5; 5 int * ptr1 = &a [ 2 ] ; 6 int * * ptr2 = &ptr1 ; 7 printf ( "%d\n", **ptr2 ) ; 9 10 return 0 ; 11 a ptr1 ptr2 Ο θώδηθαο ηππώλεη 3 Φαξνθόπεην Παλεπηζηήκην 59/59