Marizza Δημοσ. 15 Μαΐου 2008 Δημοσ. 15 Μαΐου 2008 είμαι 1ο έτος ηλεκτρολόγος μηχανικός και τώρα αρχίζω προγραμματισμό.θα ήθελα αν μπορείτε να μου τι διαφορά ανάμεσα στα * και & που είναι δείκτες;ευχαριστώ.
kurkosdr Δημοσ. 15 Μαΐου 2008 Δημοσ. 15 Μαΐου 2008 Με λιγα λογια: Φαντασου τις μεταβλητες σαν κουτια στην μνημη. Εχουμε για παραδειγμα μια μεταβλητη τυπου int, ονοματι num, η οποια εχει καποια περιεχομενα. Εχει και μια διευθυνση, ωστε να ξερει ο υπολογιστης που θα ψαξει μεσα στην μνημη, ωστε να βρει το κουτι και να παρει τα δεδομενα. Εστω τωρα ότι δεν μπορουμε να προσεγγισουμε την μεταβλητη απευθειας (δεν μπορουμε δηλαδη να κανουμε num++; για παραδειγμα). Τι μπορουμε να κανουμε για να προσεγγισουμε τα περιεχομενα της? Μπορουμε να φτιαξουμε μια "συντομευση" αυτης της μεταβλητης, όπως θα φτιαχναμε μια συντομευση για ενα αρχειο που δεν μπορουμε να προσεγγισουμε απευθειας. Η "συντομευση" αυτη δεν θα εχει τιποτα αλλο μεσα εκτος από την διευθυνση της num. Bλεποντας την διευθυνση που εχει αυτη η συντομευση, ο υπολογιστης μπορει να ανακτησει τα δεδομενα της num (χωρις να προσεγγιζει απευθειας την num). Οι μεταβλητες που εχουν μεσα τους διευθυνσεις αλλων μεταβλητων λεγονται pointers. Εχουμε ορισμενα εργαλεια στην C για να χειριζομαστε pointers. Για να δηλωσουμε εναν pointer που θα "δειχνει" σε μια μεταβλητη τυπου int, (θα εχει δηλαδη την διευθυνση μιας μεταβλητης τυπου int) εστω ptr το ονομα του, κανουμε: int* ptr; Εστω τωρα ότι θελουμε να κανουμε αυτον τον ptr να "δειχνει" στην num. Πρέπει με καποιο τροπο να κανουμε τον υπολογιστη να μας εμφανισει την διευθυνση που εχει η num. Αυτο το κανουμε με &num. Το & δηλαδη πριν από μια μεταβλητη επιστρεφει την διευθυνση της. Ετσι με ptr=# ο pointer ονοματι ptr εχει πλεον την διευθυνση της num, "δειχνει" δηλαδη στην num ( το & επιστρεφει την διευθυνση της, ενω το = αναλαμβανει να την αποθηκευσει αυτην την διευθυνση στον ptr) Τωρα, πρέπει να υπάρχει και ενα εργαλειο που θα κανει τον υπολογιστη να βρισκει τα δεδομενα στα οποια δειχνει ο ptr και να ανακτα τα περιεχομενα του. Αυτο γινεται με *ptr. Δηλαδη, αμα κανεις *ptr, στην ουσια επεξεργαζεσαι τα περιεχομενα της μεταβλητης στην οποια "δειχνει" ο ptr, δηλαδη τα περιεχομενα της num. Ετσι, αντι να κανεις num++; (που όπως ειπαμε δεν μπορουμε), θα μπορουσες καλλιστα να κανεις *ptr++; Αμα θελεις να επεξεργαστεις την ptr αυτη καθεαυτη, χρησιμοποιεις σκετο ptr. Για παραδειγμα, αμα κανεις ptr++; δεν θα πειραξει καθολου τα περιεχομενα της num. θα αλλαξει ομως ο ptr. Θα παψει να δειχνει πλεον στην num, αλλα στην διπλανη μεταβλητη της (αν υπάρχει). Πολύ χρησιμο αυτο σε πινακες όπου οι μεταβλητες ειναι διπλα-διπλα (από αποψη διευθυνσεων). ----- Συμπερασμα: Με σκετο ptr αναφερεσαι στον pointer, ενω το *ptr αναφερεσαι στα περιεχομενα της μεταβλητης στην οποια "δειχνει" ο pointer. Το & πριν από μια μεταβλητη επιστρεφει την διευθυνση μιας μεταβλητης (κυριως ωστε να μπορεις να κανεις εναν pointer να δειχνει σε αυτην). ------ Αλλα χρησιμα: 1.Εστω ότι εχουμε εναν πινακα int Alpha[1,2,4,5,8,3]. Αμα κανω ptr=&Alpha[1] ο ptr πλεον θα δειχνει στο δευτερο στοιχειο, δηλαδη στο "2". Αμα κανω ptr++ όπως ειπαμε προηγουμενως, θα δειχνει πλεον στο τριτο στοιχειο δηλαδη στο "4" (ειναι η επομενη μεταβλητη, απο αποψη διευθυνσης, μετα το "2"). Και κατι καινουριο: Αμα κανω ptr[2], αναφερομαι πλεον στα περιεχομενα της μεταβλητης που (απο αποψη διευθυνσης) ειναι δυο βηματα διπλα από αυτην που δειχνει ο ptr. Ο ptr δειχνει στο τριτο στοιχειο, αρα αυτο με τα δυο βηματα διπλα ειναι το πεμπτο, αρα αναφερομαι στο "8". Περιττο να πω ότι το ptr[0] ειναι ιδιο με το *ptr. 2. Οι pointers ειναι πολύ χρησιμοι σε συναρτησεις, όπου δεν μπορεις (στην c) να επιστρεψεις πολλές τιμες. Εστω πχ, ότι θελουμε να φτιαξουμε μια συναρτηση που θα αυξανει κατα μια μοναδα την τιμη δυο μεταβλητων που δεχεται, και να τις επιστρεφει (θυμισου, δεν μπορουμε να κανουμε return πανω από μια φορα). Η λυση: Δεν περναμε τις τιμες με τον συνηθισμενο τροπο, αλλα ως pointers. Πχ, αντι αν εχουμε την συναρτηση example(int a, int ... , θα εχουμε την example(int* a, int* .. . Η κληση από την main γινεται με example (&c, &d) και οχι example(c,d); Ποια η διαφορα? Στην πρωτη περιπτωση (ονομαζεται "περασμα by value"), οι μεταβλητες c,d θα αντιγραφουν στις a,b, και ότι αλλαγες γινουν στις a,b δεν θα επιστραφουν στην main. Αντιθετα, στην δευτερη περιπτωση (αυτην με τους pointers, ονομαζεται "περασμα by reference") στην ουσια δεν επεξεργαζεσαι τις μεταβλητες a,b, αλλα τις c,d στην main (που δεν μπορεις να προσεγγιζεις απευθειας, επειδή ειναι στην main και οχι στην example). Για να κανεις αλλαγες στις c,d χρησιμοποιεις *a, *b αντιστοιχα. Ότι αλλαγες κανεις πλεον στις *a, *b (που δειχνουν στις c,d αντιστοιχα) επιρεαζουν τις τιμες των c,d αντιστοιχα, δηλαδη το αποτελεσμα της example επιστρεφεται στην main!!!
gtroza Δημοσ. 16 Μαΐου 2008 Δημοσ. 16 Μαΐου 2008 bravo kurkosdr πολύ κατατοπιστική η εξήγηση ευχαριστούμε .
Marizza Δημοσ. 17 Μαΐου 2008 Μέλος Δημοσ. 17 Μαΐου 2008 Ευχαριστώ πολύ.Τους κατάλαβα τους δείκτες αν και με μπέρδεψε λίγο το 1 από τα άλλα χρήσιμα.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.