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

Σχετικά έγγραφα
Η γλώσσα προγραμματισμού C

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

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

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

ΑΣΚΗΣΗ 6: ΔΕΙΚΤΕΣ. Σκοπός της Άσκησης. 1. Εισαγωγικά στοιχεία για τους Δείκτες

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

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

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

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

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

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

ΦΥΛΛΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ 1

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

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

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

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

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

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

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

Οικονόμου Βαγγέλησ Διάλεξη Νο 2. Δομημένοσ Προγραμματιςμόσ - Διάλεξη 2

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

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

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

Οι δείκτες στη γλώσσα C

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

5ο σετ σημειώσεων - Δείκτες

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

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

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

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

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Διορθώσεις Συμπληρώσεις επί της επανεκτύπωσης 2003 της 2 ης έκδοσης του βιβλίου «Διαδικαστικός Προγραμματισμός C»

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

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

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

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

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

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

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

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

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

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΥΠΟΛΟΓΙΣΤΩΝ & ΥΠΟΛΟΓΙΣΤΙΚΗ ΦΥΣΙΚΗ

Εισαγωγή στον Προγραµµατισµό «C»

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

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

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

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

Διάλεξη 11η: Δείκτες, μέρος 1

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

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

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

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

Ενότητα 4: «Εισαγωγή στον Προγραμματισμό. Τα πρώτα προγράμματα σε γλώσσα C»

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

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

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

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

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

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

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

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

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

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ ΜΑΘΗΜΑ 3 Ο. Σταθερές-Παράμετροι-Μεταβλητές Αριθμητικοί & Λογικοί Τελεστές Δομή ελέγχου-επιλογής Σύνθετοι έλεγχοι

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

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

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

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

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

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

ΑΣΚΗΣΗ 2: ΔΟΜΗ ΠΡΟΓΡΑΜΜΑΤΟΣ C, ΧΕΙΡΙΣΜΟΣ ΜΕΤΑΒΛΗΤΩΝ ΚΑΙ ΣΥΝΑΡΤΗΣΕΙΣ ΕΙΣΟΔΟΥ ΚΑΙ ΕΞΟΔΟΥ

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

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

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

5 &6. Τύποι δεδομένων, τελεστές και

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

ΑΣΚΗΣΗ 2: ΧΕΙΡΙΣΜΟΣ ΜΕΤΑΒΛΗΤΩΝ ΣΤΗ C

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

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

Προγραμματισμός I (Θ)

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

Υπολογισμός - Εντολές Επανάληψης

Διάλεξη 6: Δείκτες και Πίνακες

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

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

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

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

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

Η γλώσσα προγραμματισμού C Οι συναρτήσεις στη C (2)

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

Εξοικ Εξ ε οικ ίωση ε με το το πρόγ ραμμα πρόγ DEV C++ Επικοι Επικ νωνία οι Χρήσ Χρήστη τη Υπολ Υπο ογισ λ τή

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

Υπολογισμός - Εντολές Ελέγχου

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

Παρακάτω δίνεται o σκελετός προγράμματος σε γλώσσα C. Σχολιάστε κάθε γραμμή του κώδικα.

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

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

Λογικό "και" (AND) μας επιστρέφει 1 αν και οι δύο operands είναι όχι μηδέν, διαφορετικά 0)

Transcript:

Η γλώσσα προγραμματισμού C Οι δείκτες στη C

Η έννοια του δείκτη Την έννοια του δείκτη τη συναντήσαμε σε προηγούμενα μαθήματα: είδαμε ότι συνάρτηση scanf(), καταχωρίζει τιμές σε μεταβλητές χρησιμοποιώντας τον τελεστή διεύθυνσης &. Όταν δηλώνεται μια μεταβλητή τότε δεσμεύεται μια περιοχή μνήμης, η οποία ξεκινά από κάποια διεύθυνση. Αυτή η διεύθυνση μπορεί να είναι περιεχόμενο μιας άλλης μεταβλητής. Τότε η μεταβλητή αυτή ονομάζεται δείκτης. O τελεστής & μπροστά από το όνομα μιας μεταβλητής μας δίνει τη διεύθυνση της δεσμευμένης μνήμης όπου αποθηκεύεται η μεταβλητή. Πχ int A = 7; printf("value of Α = %d \naddress of A = %u\n", A, &A); Αν λοιπόν Α είναι το όνομα μιας μεταβλητής, τότε &Α είναι η διεύθυνση της μεταβλητής Α στη μνήμη και είναι ένας δείκτης. 2

Η έννοια της διεύθυνσης Η περιοχή που δεσμεύεται στη μνήμη όταν δηλώνεται μια μεταβλητή είναι μια σειρά από διαδοχικά κελιά μνήμης που έχουν χωρητικότητα 1 byte. Σε κάθε κελί της μνήμης αντιστοιχεί μια διεύθυνση. Η διεύθυνση του 1 ου κελιού που δεσμεύεται για κάποια μεταβλητή είναι η διεύθυνση της μεταβλητής. Δήλωση στη C: int Α = 5 ; Η διεύθυνση της Α (&Α) Δείκτης της Α H Α καταλαμβάνει 4 bytes. Γιατί? Διευθύνσεις μνήμης 2293573 2293575 2293576 2293577 Μνήμη 11001010 00000000 00000000 00000000 00000101 01101111 Α 3

Στην πράξη #include <stdio.h> #include <stdlib.h> Διευθύνσεις μνήμης.. Μνήμη main() { int a; a = 7; printf("the value of a is %u\n",a); printf("the address of a is %p\n",&a); system("pause"); } The value of a is 7 The address of a is 0022FF44 Πιέστε ένα πλήκτρο για συνέχεια... 0022FF43 0022FF44 00000000 0022FF45 00000000 0022FF46 00000000 0022FF47 00000111 0022FF48. Το μήκος σε bits μιας διεύθυνσης εξαρτάται από τον υπολογιστή a 4

Οι μεταβλητές τύπου δείκτη (δήλωση) Στην C oι διευθύνσεις μεταβλητών είναι δυνατόν ν αποθηκευτούν επίσης σε μεταβλητές. Αυτές του είδους οι μεταβλητές που περιέχουν (δείχνουν) διευθύνσεις άλλων μεταβλητών ονομάζονται δείκτες (pointers). Η δήλωση μιας μεταβλητής-δείκτη γίνεται ως εξής: <τύπος> *<όνομα_δείκτη>; (δημιουργώ ένα δείκτη που μπορεί να δείξει σε διεύθυνση μεταβλητής που έχει δηλωθεί σαν <τύπος>) Ο <τύπος> μπορεί είναι ένας από τους τύπους δεδομένων της C και δηλώνει τον τύπο της μεταβλητής που δείχνει ο δείκτης. Ο αστερίσκος * υποδεικνύει ότι η μεταβλητή που ακολουθεί είναι ένας δείκτης. Το <όνομα_δείκτη> είναι οποιοδήποτε όνομα επιθυμούμε. 5

Παραδείγματα δήλωσης δεικτών int *intptr; Η μεταβλητή intptr είναι δείκτης σε ακεραία μεταβλητή (int) Δηλαδή στο δείκτη intptr μπορούμε να αποθηκεύσουμε τη διεύθυνση κάποιας ακεραίας μεταβλητής: intptr = &A; char *chatptr; (η μεταβλητή charptr είναι δείκτης σε μεταβλητή χαρακτήρα) float *floatptr; (η μεταβλητή floatptr είναι δείκτης σε μεταβλητή float) Επειδή οι δείκτες δείχνουν σε διευθύνσεις μεταβλητών και όχι στο περιεχόμενο τους το μέγεθος τους είναι σταθερό και ίδιο για όλους τους τύπους. Εξαρτάται από τον compiler (συνήθως 4 ή 8 bytes). Δεν εξαρτάται από τον τύπο της μεταβλητής. 6

Ανάθεση τιμών σε δείκτες Πριν χρησιμοποιηθεί ένας δείκτης πρέπει να δείχνει σε μια διεύθυνση. Ο τελεστής & που δίνει την διεύθυνση μιας μεταβλητής χρησιμοποιείται για να δώσουμε τιμές σε δείκτες: int A, *intptr; Προσοχή: Ο τύπος του δείκτη πρέπει να είναι ο ΙΔΙΟΣ με αυτόν της μεταβλητής. intptr = &A; Η τιμή που δίνουμε σε έναν δείκτη πρέπει να είναι διεύθυνση κάποιας μεταβλητής και ΟΧΙ μια αριθμητική τιμή. intptr = 2000; Στην εντολή printf () για να δούμε το περιεχόμενο ενός δείκτη χρησιμοποιούμε το προσδιοριστή %p που εμφανίζει τη τιμή του δείκτη σε 16-δική μορφή. Μπορούμε επίσης να κάνουμε χρήση και των προσδιοριστών %u και %d. 7

Η τιμή NULL Αν προσπαθήσουμε να χρησιμοποιήσουμε ένα δείκτη πριν αυτός πάρει κάποια τιμή διεύθυνσης, τότε το πρόγραμμα δεν θα εκτελεστεί σωστά. Όταν δηλώνεται ένας δείκτης δεν του αποδίδεται από τη C κάποια συγκεκριμένη τιμή. Μπορούμε να χρησιμοποιήσουμε τη σταθερά NULL για να δώσουμε αρχική τιμή σ ένα δείκτη: int *intptr = NULL; Η σταθερά NULL βρίσκεται στη βιβλιοθήκη <stdio.h> και έχει τη τιμή 0. Δεν δείχνει πουθενά και πρέπει να χρησιμοποιείται με προσοχή. Έλεγχος της τιμής ενός δείκτη: if (intprt == NULL) // ή if (!intprt) 8

Ο τελεστης * Εφαρμόζεται μόνο σε δείκτες. Δεν είναι ο ίδιος με τον τελεστή του πολλαπλασιασμού. O τελεστής * πριν το όνομα του δείκτη μας δίνει το περιεχόμενο (την τιμή) της διεύθυνσης που δείχνει ο δείκτης: int a =5, *aptr; Value of a = 5 aptr=&a; printf(" Value of a = %d", *aptr); Μπορούμε ν αλλάξουμε το περιεχόμενο μιας μεταβλητής με τον δείκτη της: *aptr =78; *aptr = *aptr+1; a = 78 a = 79 Πρόκειται για μια έμμεση αναφορά στη τιμή μιας μεταβλητής. Μπορούμε ακόμα να δηλώσουμε και δείκτη σε δείκτη: int **aptr ; //δείκτης σε δείκτη που δείχνει σε ακέραιο! 9

Τι συμβαίνει ότι δίνουμε τιμές σε δείκτες Διευθύνσεις μνήμης Μνήμη int A, B; int *p1, *p2; 2293582 2293586 Α B p1 p2 A = 56; B = -23; 2293582 2293586 56-23 Α B p1 p2 p1 = &A; p2 = &B; 2293582 2293586 56-23 Α B p1 p2 10

Διαχείριση και διευθύνσεων και τιμών μεταβλητών Διευθύνσεις μνήμης Μνήμη *p1 = 78; (αλλάζω το περιεχόμενο της Α) 2293582 2293586 78-23 Α B p1 p2 *p1 = *p2; (αποτέλεσμα ίδιο σαν Α=Β) 2293582 2293586-23 -23 Α B p1 p2 p1 = p2; (ο p1 δείχνει όπου και ο p2) 2293582 2293586-23 -23 Α B p1 p2 11

Πρόγραμμα με αλλαγή σε τιμή μεταβλητής με δείκτη #include <stdio.h> main() { int i, *pi; i = 155; pi = &i; printf("%d - %d \n",i,*pi); printf("%p - %p \n",pi,&i); printf("%u - %u \n\n",pi,&i); *pi=199; printf("%d - %d \n",i,*pi); printf("%p - %p \n",pi,&i); printf("%u - %u \n",pi,&i); } 155-155 0022FF44-0022FF44 2293572 2293572 199-199 0022FF44-0022FF44 2293572-2293572 12

Πράξεις με χρήση δεικτών - πρόγραμμα #include <stdio.h> main() { int a, b, c; int *pa, *pb, *pc; printf("\n a:"); scanf("%d", &a); printf("\n b:"); scanf("%d", &b); printf("\n c:"); scanf("%d", &c); pa = &a; pb = &b; pc = &c; a:5 b:6 c:7 a(5)+ b(6)+c(7) = 18 a(5)* b(6)*c(7) = 210 printf("\n a(%d)+ b(%d)+c(%d) = %d\n", a, b, c, *pa+*pb+*pc); printf("\n a(%d)* b(%d)*c(%d) = %d\n", a, b, c, *pa**pb**pc); getchar();getchar(); } 13

Πόσα bytes καταλαμβάνει ένας δείκτης; #include <stdio.h> main() { int a, *pa; float b, *pb; char c, *pc; pa = &a; pb = &b; pc = &c; printf("\n a:"); scanf("%d", pa); printf(" b:"); scanf("%f", pb); printf(" c:"); scanf("%s", pc); a:3 b:5.2 c:a a=3, size of a=4, size of pa=8 b=5.199951, size of b=4, size of pb=8 c=a, size of c=1, size of pc=8 printf("\n a=%d, size of a=%d, size of pa=%d\n", *pa, sizeof(a),sizeof(pa)); printf(" b=%f, size of b=%d, size of pb=%d\n", *pb, sizeof(b),sizeof(pb)); printf(" c=%c, size of c=%d, size of pc=%d\n", *pc, sizeof(c),sizeof(pc)); getchar();getchar(); } 14

Τα & και * είναι συμπληρωματικά (αντίστροφα) #include <stdio.h> #include <stdlib.h> main() { int a; int *aptr; a = 7; } The address of a is 0028FF4 The value of aptr is 0028FF44 The value of a is 7 The value of *aptr is 7 &*aptr = 0028FF44 *&aptr = 0028FF44 aptr = &a; // aptr δείχνει στη διεύθυνση του a printf( "The address of a is %p\n The value of aptr is %p\n", &a, aptr ); printf( "The value of a is %d\n The value of *aptr is %d", a, *aptr ); // Τα & και * είναι συμπληρωματικά - αλληλοαναιρούνται printf( "\n &*aptr = %p\n*&aptr = %p\n", &*aptr, *&aptr ); system("pause"); 15

Αριθμητική των δεικτών Επιτρέπονται μόνο 2 αριθμητικές πράξεις: η πρόσθεση και η αφαίρεση. Οι τελεστές που χρησιμοποιούνται είναι οι +, -, ++ και --. Όταν προσθέτω 1 σ ένα δείκτη τότε Αν η μεταβλητή που δείχνει είναι char, ο δείκτης αυξάνεται κατά 1 (μέγεθος του char 1 = Byte). Αν η μεταβλητή που δείχνει είναι int, ο δείκτης αυξάνεται κατά 4 (υποθέτουμε ότι το μέγεθος του int 4 = Bytes). Αν η μεταβλητή που δείχνει είναι double, ο δείκτης αυξάνεται κατά 8 (μέγεθος του double 8 = Bytes). Κάνουμε ΜΟΝΟ πρόσθεση ακεραίου σε δείκτη ή αφαίρεση ακεραίου από δείκτη. Μπορούμε να κάνουμε ΜΟΝΟ αφαίρεση ή σύγκριση 2 δεικτών, όταν αυτοί δείχνουν στο ίδιο τύπο μεταβλητής. 16

Πρόγραμμα με αριθμητική δεικτών char *chp, ch; int *inp, in; float *flp, fl; double *dp, d; chp=&ch; inp=&in; flp=&fl; dp=&d; printf("\ndeiktis char:%d, Deiktis int:%d\n", chp,inp); printf("deiktis float:%d, Deiktis double:%d\n", flp, dp); chp++; inp++; flp++; dp++; printf("\ndeiktis char:%d, Deiktis int:%d\n", chp,inp); printf("deiktis float:%d, Deiktis double:%d\n", flp, dp); Deiktis char:2293571, Deiktis int:2293560 Deiktis float:2293552, Deiktis double:2293536 Deiktis char:2293572, Deiktis int:2293564 Deiktis float:2293556, Deiktis double:2293544 17