Προς το περιεχόμενο

Ερώτηση για δείκτες στη C


Giorgos3924

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα!

Οι δείκτες είναι μεταβλητές που χρησιμοποιούνται για την αποθήκευση διευθύνσεων μνήμης

Η ερώτησή μου είναι απλή:

Τί διαφορά έχει αν δηλώσουμε μια μεταβλητή σαν απλή τύπου int, με τη δήλωση

μιας μεταβλητής δείκτη τύπου int;

Δηλαδή:

>int main()
{
int a,b; [color="Green"]//Μεταβλητές τύπου int.[/color]
int *pa,*pb; [color="green"]//Δείκτες τύπου int[/color]
[color="green"]//Τη διεύθυνση της μεταβλητής b δεν μπορούμε να την κατοχυρώσουμε στην a;[/color]
a=&b; [color="green"]//Η μεταβλητή a μας δείχνει την διεύθυνση της b[/color]
pa=&b; [color="green"]//Εδώ πάλι έχουμε τη διεύθυνση της μεταβλητής b.[/color]
}

Δημοσ.

Οι δείκτες μπορεί να φανούν αρκετά χρήσιμοι σε συναρτήσεις. Όταν περνάς μία παράμετρο σε μία συνάρτηση (που δεν είναι δείκτης) εσωτερικά γίνεται αντιγραφή της τιμής της μεταβλητής και άρα δημιουργείται μία άλλη μεταβλητή. Για να υλοποιήσεις την swap(int *, int *) όπου αλλάζεις τις τιμές σε δύο μεταβλητές χρειάζεσαι δείκτες για να το κάνεις.

 

>
int main(void)
{
int a,b;

a=1;
b=2;
swap(&a, &;
}

void swap(int *x, int *y)
{
int t;

t = *x;	/*	*x is value pointed to by x	*/
*x = *y;
*y = t;
}

 

Αν δεν χρησιμοποιούσες δείκτες, το swap των τιμών θα γινόταν στα "αντίγραφα" των μεταβλητών που χρησιμοποίησες και όταν η swap θα τερμάτιζε πρακτικά δεν θα είχε αλλάξει τίποτα.

Δημοσ.

a=&b; //Η μεταβλητή a μας δείχνει την διεύθυνση της b

pa=&b; //Εδώ πάλι έχουμε τη διεύθυνση της μεταβλητής b

 

Στην 1η περίπτωση αποθηκεύεις την διεύθυνσης μνήμης του b σε μία integer μεταβλητή.

Στην 2η περίπτωση βάζεις τον δείκτη pa να "δείχνει" στην διεύθυνση μνήμης όπου έχεις αποθηκευμένη την τιμή του b.

 

Ο δείκτης pa.. είναι "αντικείμενο" που μπορείς να το διαχειριστείς καταλλήλως.. ώστε να "δείχνει" σε διευθύνσεις μνήμης και να διαβάζεις τις τιμές που είναι αποθηκευμένες εκεί.

 

Ενώ το a είναι ένας integer.. ένας απλός αριθμός.. άσχετα αν στην συγκεκριμένη περίπτωση αυτός ο αριθμός εκφράζει μία διεύθυνση μνήμης.

Δημοσ.

Δηλαδή κάνεις swap χωρίς να χρησιμοποιήσεις return(), αν κατάλαβα σωστά!

Επίσης κάτι άσχετο τώρα που το πρόσεξα.

Το πρόγραμμα που έγραψες πρακτικά νομίζω δεν δουλεύει γιατί δεν έχεις δηλώσει τη συνάρτηση πάνω από τη main.

Αυτό γιατί γίνεται;

Στο dev-c++ για παράδειγμα, αν γράψω μια συνάρτηση πάνω από τη main δεν χρείαζεται να τη δηλώσω.

Αν την γράψω κάτω από τη main πρέπει επάνω από τη main να τη δηλώσω:

typos_synartisis onoma_synartisis();

 

Δεν μπόρεσα να καταλάβω αυτή την ιδιοτροπία.

Δημοσ.

Να μια μερική απάντηση.

 

Στο απλοϊκό παράδειγμα που θέτεις δεν έχει διαφορά.

Αλλά συχνά συμβαίνει να είναι γνωστές μόνον οι διευθύνσεις των μεταβλητών κι' όχι τα ονόματά τους,

οπότε δεν μπορείς να γράψεις a=&b.

Eπιπλέον, η αριθμητική των δεικτών γίνεται αυτόματα και αυτό εξυπηρετεί πολύ.

Π.χ. αν a είναι δείκτης σε έναν πίνακα double και k είναι ένας ακέραιος,

το *(a+k) προσπελαύνει άμεσα το στοιχείο k+1. Αν το a ήταν κοινή ακέραια μεταβλητή,

θα έπρεπε να πολλαπλασιάσεις με το μέγεθος του στοιχείου σε bytes (π.χ. για πίνακα double θα ήταν a+k*8).

 

---------- Προσθήκη στις 18:18 ---------- Προηγούμενο μήνυμα στις 18:13 ----------

 

Στο dev-c++ για παράδειγμα, αν γράψω μια συνάρτηση πάνω από τη main δεν χρείαζεται να τη δηλώσω.

Αν την γράψω κάτω από τη main πρέπει επάνω από τη main να τη δηλώσω:

typos_synartisis onoma_synartisis();

 

Δεν μπόρεσα να καταλάβω αυτή την ιδιοτροπία.

 

O compiler πρέπει να έχει μια "εικόνα" της συνάρτησης (ότι σημαίνει αυτό) για να την εκτελέσει.

Γι' αυτό πρέπει να την δηλώσεις. Αν δεν το κάνεις, συναντά κάτι άγνωστο...

Δημοσ.

Στη C χρειάζεται για να χρησιμοποιείς μία function πρέπει να έχει ήδη γραφτεί ψηλότερα στον κώδικα. Επειδή αυτό σαν απαίτηση μπορεί να δημιουργήσει δυσκολία στους προγραμματιστές μπορείς να βάζεις στην αρχή του προγράμματος τα signatures (η "εικόνα" που αναφέρει κ ο φίλος V.I.Smirnov) από όλες τις συναρτήσεις σου, όπως ίσως έχεις δει κ στα .h αρχεία, π.χ.

>
void swap(int *, int *);

int main(void)
{...}

void swap(int *x, int *y)
{...}

Δημοσ.
Καλησπέρα!

>int main()
{
int a,b; [color="Green"]//Μεταβλητές τύπου int.[/color]
a=&b; [color="green"]//Η μεταβλητή a μας δείχνει την διεύθυνση της b[/color]
}

 

Ο a είναι απλός integer. Δεν μπορείς να θέσεις την διεύθυνση του b στον a.

Δημοσ.
Στην πραγματικότητα μάλλον γίνεται (ίσως με κάποιο warning από τον compiler) λόγο type-casting.

 

Στην C τα πάντα γίνονται. Ας πούμε ότι έκανα λάθος επιλογή λέξεων. Όταν έγραψα

"δεν μπορείς" εννοούσα "δεν είναι σωστό" / "δεν έχει νόημα" (και εφόσον δεν έχει

καταλάβει καλά τους δείκτες θα τον μπερδέψει κιόλας"

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...