Δείκτες στο C: Τι είναι το Pointer στον προγραμματισμό C; Τύποι

Τι είναι το Pointer στο C;

The Δείκτης στο C, είναι μια μεταβλητή που αποθηκεύει τη διεύθυνση μιας άλλης μεταβλητής. Ένας δείκτης μπορεί επίσης να χρησιμοποιηθεί για αναφορά σε μια άλλη συνάρτηση δείκτη. Ένας δείκτης μπορεί να αυξηθεί/μειωθεί, δηλ., να δείχνει στην επόμενη/προηγούμενη θέση μνήμης. Ο σκοπός του δείκτη είναι να εξοικονομήσει χώρο στη μνήμη και να επιτύχει ταχύτερο χρόνο εκτέλεσης.

Πώς να χρησιμοποιήσετε τους δείκτες στο C

Αν δηλώσουμε μια μεταβλητή v τύπου int, η v θα αποθηκεύσει πραγματικά μια τιμή.

Πώς να χρησιμοποιήσετε τους δείκτες στο C

Το v είναι ίσο με μηδέν τώρα.

Ωστόσο, κάθε μεταβλητή, εκτός από τιμή, έχει και τη διεύθυνσή της (ή, με απλά λόγια, πού βρίσκεται στη μνήμη). Η διεύθυνση μπορεί να ανακτηθεί βάζοντας ένα συμπλεκτικό σύμβολο (&) πριν από το όνομα της μεταβλητής.

Πώς να χρησιμοποιήσετε τους δείκτες στο C

Εάν εκτυπώσετε τη διεύθυνση μιας μεταβλητής στην οθόνη, θα μοιάζει με έναν εντελώς τυχαίο αριθμό (επιπλέον, μπορεί να διαφέρει από εκτέλεση σε εκτέλεση).

Ας το δοκιμάσουμε στην πράξη με δείκτη στο παράδειγμα Γ

Πώς να χρησιμοποιήσετε τους δείκτες στο C

Η έξοδος αυτού του προγράμματος είναι -480613588.

Τώρα, τι είναι ένας δείκτης; Αντί να αποθηκεύει μια τιμή, ένας δείκτης θα αποθηκεύσει τη διεύθυνση μιας μεταβλητής.


Μεταβλητή δείκτη

Int *y = &v;

ΜΕΤΑΒΛΗΤΟΣ ΔΕΙΚΤΗΣ
A αξία αποθηκεύονται σε ένα το όνομά του διεύθυνση αποθήκευσης/μνήμης A μεταβλητή ότι δείχνει προς τη διεύθυνση αποθήκευσης/μνήμης του άλλος μεταβλητή

Δήλωση δείκτη

Όπως οι μεταβλητές, οι δείκτες μέσα C προγραμματισμού πρέπει να δηλωθούν για να μπορέσουν να χρησιμοποιηθούν στο πρόγραμμά σας. Οι δείκτες μπορούν να ονομαστούν ό,τι θέλετε, αρκεί να υπακούουν στους κανόνες ονομασίας του C. Μια δήλωση δείκτη έχει την ακόλουθη μορφή.

data_type * pointer_variable_name;

Εδώ,

  • Τύπος δεδομένων είναι ο βασικός τύπος του δείκτη των τύπων μεταβλητών C και υποδεικνύει τον τύπο της μεταβλητής στην οποία δείχνει ο δείκτης.
  • Ο αστερίσκος (*: ο ίδιος αστερίσκος που χρησιμοποιείται για τον πολλαπλασιασμό) που είναι τελεστής έμμεσης κατεύθυνσης, δηλώνει δείκτη.

Ας δούμε μερικές έγκυρες δηλώσεις δείκτη σε αυτό το σεμινάριο δείκτες C:

int    *ptr_thing;            /* pointer to an integer */ 
int *ptr1,thing;/* ptr1 is a pointer to type integer and thing is an integer variable */
double    *ptr2;    /* pointer to a double */
float    *ptr3;      /* pointer to a float */
char    *ch1 ;       /* pointer to a character */
float  *ptr, variable;/*ptr is a pointer to type float and variable is an ordinary float variable */

Αρχικοποιήστε έναν δείκτη

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

Για να λάβουμε τη διεύθυνση μιας μεταβλητής, χρησιμοποιούμε τον τελεστή συμπλεκτικού συμβολικού (&), τοποθετημένο πριν από το όνομα μιας μεταβλητής της οποίας τη διεύθυνση χρειαζόμαστε. Η προετοιμασία του δείκτη γίνεται με την ακόλουθη σύνταξη.

Σύνταξη δείκτη

 pointer = &variable;

Ένα απλό πρόγραμμα για την απεικόνιση του δείκτη δίνεται παρακάτω:

#include <stdio.h>
int main()
{
   int a=10;    //variable declaration
   int *p;      //pointer variable declaration
   p=&a;        //store address of variable a in pointer p
   printf("Address stored in a variable p is:%x\n",p);  //accessing the address
   printf("Value stored in a variable p is:%d\n",*p);   //accessing the value
   return 0;
}

Παραγωγή:

Address stored in a variable p is:60ff08
Value stored in a variable p is:10
OperaTor Νόημα
* Εξυπηρετεί 2 σκοπούς

  1. Δήλωση ενός δείκτη
  2. Επιστρέφει την τιμή της αναφερόμενης μεταβλητής
& Εξυπηρετεί μόνο 1 σκοπό

  • Επιστρέφει τη διεύθυνση μιας μεταβλητής

Τύποι δεικτών στο C

Ακολουθούν τα διαφορετικά Τύποι δεικτών στο C:

Μηδενικός δείκτης

Μπορούμε να δημιουργήσουμε έναν μηδενικό δείκτη εκχωρώντας τιμή null κατά τη δήλωση του δείκτη. Αυτή η μέθοδος είναι χρήσιμη όταν δεν έχετε εκχωρήσει καμία διεύθυνση στον δείκτη. Ένας μηδενικός δείκτης περιέχει πάντα την τιμή 0.

Το παρακάτω πρόγραμμα απεικονίζει τη χρήση ενός μηδενικού δείκτη:

#include <stdio.h>
int main()
{
	int *p = NULL; 	//null pointer
	printf(“The value inside variable p is:\n%x”,p);
	return 0;
}

Παραγωγή:

The value inside variable p is:
0

Κενός δείκτης

In C προγραμματισμού, ένας δείκτης κενού καλείται επίσης ως γενικός δείκτης. Δεν έχει κανένα τυπικό τύπο δεδομένων. Ένας δείκτης κενού δημιουργείται χρησιμοποιώντας τη λέξη-κλειδί void. Μπορεί να χρησιμοποιηθεί για την αποθήκευση μιας διεύθυνσης οποιασδήποτε μεταβλητής.

Το παρακάτω πρόγραμμα απεικονίζει τη χρήση ενός δείκτη κενού:

#include <stdio.h>
int main()
{
void *p = NULL; 	//void pointer
printf("The size of pointer is:%d\n",sizeof(p));
return 0;
}

Παραγωγή:

The size of pointer is:4

Άγριος δείκτης

Ένας δείκτης λέγεται ότι είναι άγριος δείκτης εάν δεν προετοιμάζεται σε τίποτα. Αυτοί οι τύποι δεικτών C δεν είναι αποτελεσματικοί επειδή μπορεί να παραπέμπουν σε κάποια άγνωστη θέση μνήμης που μπορεί να προκαλέσει προβλήματα στο πρόγραμμά μας και να οδηγήσει σε διακοπή λειτουργίας του προγράμματος. Πρέπει πάντα να είστε προσεκτικοί όταν εργάζεστε με άγριους δείκτες.

Το παρακάτω πρόγραμμα απεικονίζει τη χρήση του wild pointer:

#include <stdio.h>
int main()
{
int *p; 	//wild pointer
printf("\n%d",*p);
return 0;
}

Παραγωγή:

timeout: the monitored command dumped core
sh: line 1: 95298 Segmentation fault      timeout 10s main

Άλλοι τύποι δεικτών στο 'c' είναι οι εξής:

  • Κρεμασμένος δείκτης
  • Σύνθετος δείκτης
  • Κοντά σε δείκτη
  • Μακρινός δείκτης
  • Τεράστιος δείκτης

Άμεσοι και έμμεσοι δείκτες πρόσβασης

Στο C, υπάρχουν δύο ισοδύναμοι τρόποι πρόσβασης και χειρισμού ενός μεταβλητού περιεχομένου

  • Άμεση πρόσβαση: χρησιμοποιούμε απευθείας το όνομα της μεταβλητής
  • Έμμεση πρόσβαση: χρησιμοποιούμε δείκτη στη μεταβλητή

Ας το καταλάβουμε αυτό με τη βοήθεια του προγράμματος παρακάτω

#include <stdio.h>
/* Declare and initialize an int variable */
int var = 1;
/* Declare a pointer to int */
int *ptr;
int main( void )
{
/* Initialize ptr to point to var */
ptr = &var;
/* Access var directly and indirectly */
printf("\nDirect access, var = %d", var);
printf("\nIndirect access, var = %d", *ptr);
/* Display the address of var two ways */
printf("\n\nThe address of var = %d", &var);
printf("\nThe address of var = %d\n", ptr);
/*change the content of var through the pointer*/
*ptr=48;
printf("\nIndirect access, var = %d", *ptr);
return 0;}

Μετά τη μεταγλώττιση του προγράμματος χωρίς σφάλματα, το αποτέλεσμα είναι:

Direct access, var = 1
Indirect access, var = 1

The address of var = 4202496
The address of var = 4202496

Indirect access, var = 48

Αριθμητική δείκτη σε C

Οι λειτουργίες του δείκτη συνοψίζονται στο παρακάτω σχήμα

Αριθμητική δείκτη σε C
Δείκτης Operaσεις

Λειτουργία προτεραιότητας (προτεραιότητα)

Όταν εργαζόμαστε με δείκτες C, πρέπει να τηρούμε τους ακόλουθους κανόνες προτεραιότητας:

  • Οι τελεστές * και & έχουν την ίδια προτεραιότητα με τους μοναδικούς τελεστές (η άρνηση!, η αύξηση++, η μείωση–).
  • Στην ίδια έκφραση, οι τελεστές *, &,!, ++, – αξιολογούνται από δεξιά προς τα αριστερά.

Εάν ένας δείκτης P δείχνει σε μια μεταβλητή X, τότε το * P μπορεί να χρησιμοποιηθεί όπου μπορεί να γραφτεί το X.

Οι παρακάτω εκφράσεις είναι ισοδύναμες:

int X =10
int *P = &Y;
For the above code, below expressions are true
Έκφραση Ισοδύναμη έκφραση
Υ=*Ρ+1

*P=*P+10

*P+=2

++*Σελ

(*P)++

Υ=Χ+1

Χ=Χ+10

X+=2

++Χ

X++

Στην τελευταία περίπτωση, χρειάζονται παρενθέσεις: καθώς οι μονατικοί τελεστές * και ++ αξιολογούνται από δεξιά προς τα αριστερά, χωρίς τις παρενθέσεις ο δείκτης P θα αυξανόταν και όχι το αντικείμενο στο οποίο δείχνει το P.

Ο παρακάτω πίνακας δείχνει την αριθμητική και τη βασική πράξη που μπορεί να χρησιμοποιηθεί όταν ασχολείται με δείκτες C

Operaσμού εξήγηση
Εκχώρηση int *P1,*P2
P1=P2;
Τα P1 και P2 δείχνουν στην ίδια ακέραια μεταβλητή
Αύξηση και μείωση Int *P1;
P1++;P1– ;
Προσθήκη μετατόπισης (Σταθερά) Αυτό επιτρέπει στον δείκτη να μετακινεί N στοιχεία σε έναν πίνακα.
Ο δείκτης θα αυξηθεί ή θα μειωθεί κατά N φορές τον αριθμό των byte (ων) του τύπου της μεταβλητής.
P1+5;

Γ Δείκτες & Πίνακες με Παραδείγματα

Παραδοσιακά, έχουμε πρόσβαση στα στοιχεία του πίνακα χρησιμοποιώντας το ευρετήριό του, αλλά αυτή η μέθοδος μπορεί να εξαλειφθεί χρησιμοποιώντας δείκτες. Οι δείκτες διευκολύνουν την πρόσβαση σε κάθε στοιχείο πίνακα.

#include <stdio.h>
int main()
{
    int a[5]={1,2,3,4,5};   //array initialization
    int *p;     //pointer declaration
               /*the ptr points to the first element of the array*/

    p=a; /*We can also type simply ptr==&a[0] */
    
    printf("Printing the array elements using pointer\n");
    for(int i=0;i<5;i++)    //loop for traversing array elements
    {
        	printf("\n%x",*p);  //printing array elements
        	p++;    //incrementing to the next element, you can also write p=p+1
    }
    return 0;
}

Παραγωγή:

1
2
3
4
5

Η προσθήκη ενός συγκεκριμένου αριθμού σε έναν δείκτη θα μετακινήσει τη θέση του δείκτη στην τιμή που προκύπτει από μια λειτουργία πρόσθεσης. Ας υποθέσουμε ότι το p είναι ένας δείκτης που δείχνει προς το παρόν στη θέση μνήμης 0, εάν εκτελέσουμε την ακόλουθη πράξη πρόσθεσης, p+1, τότε θα εκτελεστεί με αυτόν τον τρόπο:

Γ Δείκτες & Πίνακες

Προσθήκη/Αύξηση δείκτη

Εφόσον το p δείχνει προς το παρόν στη θέση 0 μετά την προσθήκη του 1, η τιμή θα γίνει 1 και ως εκ τούτου ο δείκτης θα δείχνει στη θέση μνήμης 1.

C Δείκτες και συμβολοσειρές με παραδείγματα

Μια συμβολοσειρά είναι ένας πίνακας αντικειμένων χαρακτήρων, που τελειώνει με έναν μηδενικό χαρακτήρα '\ 0'. Μπορούμε να χειριστούμε συμβολοσειρές χρησιμοποιώντας δείκτες. Αυτός ο δείκτης στο παράδειγμα C εξηγεί αυτήν την ενότητα

#include <stdio.h>
#include <string.h>
int main()
{
char str[]="Hello Guru99!";
char *p;
p=str;
printf("First character is:%c\n",*p);
p =p+1;
printf("Next character is:%c\n",*p);
printf("Printing all the characters in a string\n");
p=str;  //reset the pointer
for(int i=0;i<strlen(str);i++)
{
printf("%c\n",*p);
p++;
}
return 0;
}

Παραγωγή:

First character is:H
Next character is:e
Printing all the characters in a string
H
e
l
l
o

G
u
r
u
9
9
!

Ένας άλλος τρόπος αντιμετώπισης συμβολοσειρών είναι με μια σειρά δεικτών όπως στο παρακάτω πρόγραμμα:

#include <stdio.h>
int main(){
char *materials[ ] = {  "iron",  "copper",  "gold"};
printf("Please remember these materials :\n");
int i ;
for (i = 0; i < 3; i++) {
  printf("%s\n", materials[ i ]);}
  return 0;}

Παραγωγή:

Please remember these materials:
iron
copper
gold

Πλεονεκτήματα των δεικτών στο C

  • Οι δείκτες είναι χρήσιμοι για την πρόσβαση σε τοποθεσίες μνήμης.
  • Οι δείκτες παρέχουν έναν αποτελεσματικό τρόπο πρόσβασης στα στοιχεία μιας δομής πίνακα.
  • Οι δείκτες χρησιμοποιούνται για τη δυναμική εκχώρηση μνήμης καθώς και για την κατανομή.
  • Οι δείκτες χρησιμοποιούνται για να σχηματίσουν σύνθετες δομές δεδομένων όπως συνδεδεμένη λίστα, γράφημα, δέντρο κ.λπ.

Μειονεκτήματα των Pointers στο C

  • Οι δείκτες είναι λίγο περίπλοκοι στην κατανόηση.
  • Οι δείκτες μπορούν να οδηγήσουν σε διάφορα σφάλματα, όπως σφάλματα τμηματοποίησης ή να έχουν πρόσβαση σε μια θέση μνήμης που δεν απαιτείται καθόλου.
  • Εάν δοθεί μια εσφαλμένη τιμή σε έναν δείκτη, μπορεί να προκαλέσει καταστροφή της μνήμης.
  • Οι δείκτες είναι επίσης υπεύθυνοι για τη διαρροή μνήμης.
  • Οι δείκτες είναι συγκριτικά πιο αργοί από αυτόν των μεταβλητών.
  • Οι προγραμματιστές δυσκολεύονται πολύ να δουλέψουν με τους δείκτες. Επομένως, είναι ευθύνη του προγραμματιστή να χειριστεί προσεκτικά έναν δείκτη.

Περίληψη

  • Ένας δείκτης δεν είναι παρά μια θέση μνήμης όπου αποθηκεύονται τα δεδομένα.
  • Ένας δείκτης χρησιμοποιείται για πρόσβαση στη θέση μνήμης.
  • Υπάρχουν διάφοροι τύποι δεικτών, όπως μηδενικός δείκτης, άγριος δείκτης, δείκτης κενού και άλλοι τύποι δεικτών.
  • Οι δείκτες μπορούν να χρησιμοποιηθούν με πίνακα και συμβολοσειρά για την πιο αποτελεσματική πρόσβαση σε στοιχεία.
  • Μπορούμε να δημιουργήσουμε δείκτες συνάρτησης για να καλέσουμε μια συνάρτηση δυναμικά.
  • Οι αριθμητικές πράξεις μπορούν να γίνουν σε έναν δείκτη που είναι γνωστός ως αριθμητική δείκτης.
  • Οι δείκτες μπορούν επίσης να υποδεικνύουν τη συνάρτηση που διευκολύνουν την κλήση διαφορετικών συναρτήσεων στην περίπτωση ορισμού μιας σειράς δεικτών.
  • Όταν θέλετε να αντιμετωπίσετε διαφορετικούς τύπους δεδομένων μεταβλητής, μπορείτε να χρησιμοποιήσετε έναν δείκτη κενού typecast.

Συνοψίστε αυτήν την ανάρτηση με: