Wiemy, że zmienna wskaźnikowa może przechowywać adres pamięci w języku C i w tym artykule dowiemy się, jak używać tego wskaźnika, aby uzyskać dostęp do danych przechowywanych w lokalizacji pamięci wskazanej przez wskaźnik.
Co to jest wskaźnik?
Na początek przypomnijmy sobie, czym jest wskaźnik. Wskaźnik to zmienna przechowująca adres pamięci innej zmiennej. Wskaźnik pomaga nam manipulować danymi w adresie pamięci, który wskazuje wskaźnik. Co więcej, wiele wskaźników może wskazywać na tę samą pamięć.
Rozważ następujący przykład,
Java konwertuje ciąg na liczbę całkowitą
int num = 10; int *ptr; ptr = #>
Zapisaliśmy adres na jednego zmienna w pt wskaźnik, ale teraz jak uzyskać dostęp do wartości zapisanej w pamięci pod wskazanym adresem pt ? Tutaj w grę wchodzi dereferencja.
Wskaźnik dereferencji w C
Dostęp do treści przechowywanej pod adresem pamięci wskazanym przez wskaźnik lub manipulowanie nią za pomocą operatora wyłuskiwania lub operatora pośredniego (*) nazywa się wyłuskiwaniem wskaźnika.
Wskaźnik dereferencji w C
Składnia wyłuskiwania wskaźnika
Używamy operatora pośredniego (*) jako przedrostka do wyłuskiwania wskaźnika:
* ( pointer_name )>
Do modyfikacji danych zapisanych w pamięci używamy
* ( pointer_name ) = new_value;>
Należy zauważyć, że nowa_wartość musi być tego samego typu co poprzednia.
Rozważ powyższe przykłady, gdzie pt punkty dla czy, t Dostęp do zawartości adresu pamięci można uzyskać za pomocą operatora dereferencji *. Teraz *ptr pobierze zawartość przechowywaną pod adresem 10.
Adresy i wartości pamięci num i ptr będą wyglądać następująco.
| Zmienny | Adres pamięci | Wartość |
|---|---|---|
| liczba = 10 | 202020 | 10 |
| 202021 | ||
| 202022 | ||
| 202023 | ||
| ptr = &liczba | 202024 – 202032 | 202020 |
Notatka: Założyliśmy, że architektura w powyższym przykładzie jest adresowalna bajtowo, tj. minimalną jednostką posiadającą oddzielny adres jest bajt.
Przykłady dereferencji wskaźników
Przykład 1:
Używanie wskaźnika do uzyskiwania dostępu i modyfikowania wartości zmiennej całkowitej.
C
przekonwertuj ciąg znaków na bieżąco
// C Program to illustrate the dereferencing of pointer> #include> int> main()> {> >// Declare integer variable number> >int> num = 10;> >// Declare pointer to store address of number> >int>* ptr = #> >// Print the value of number> >printf>(>'Value of num = %d
'>, num);> >// Print Address of the number using & operator> >printf>(>'Address of num = %d
'>, &num);> >// Print Address stored in the pointer> >printf>(>'Address stored in the ptr = %p
'>, ptr);> >printf>(>'Dereference content in ptr using *ptr
'>);> >// Access the content using * operator> >printf>(>'Value of *ptr = %d
'>, *ptr);> >printf>(>'Now, *ptr is same as number
'>);> >printf>(>'Modify the value using pointer to 6
'>);> >// Modify the content in the address to 6 using pointer> >*ptr = 6;> >// Print the modified value using pointer> >printf>(>'Value of *ptr = %d
'>, *ptr);> >// Print the modified value using variable> >printf>(>'Value of number = %d
'>, num);> >return> 0;> }> |
>
>
liczba całkowita na ciąg w Javie
Wyjście
Value of num = 10 Address of num = 0x7ffe47d51b4c Address stored in the ptr = 0x7ffe47d51b4c Dereference content in ptr using *ptr Value of *ptr = 10 Now, *ptr is same as number Modify the value using pointer to 6 Value of *ptr = 6 Value of number = 6>
Przykład 2: Dereferencja podwójnego wskaźnika
Podwójne wskaźniki można również wyłuskać przy użyciu tej samej logiki, ale będziesz musiał użyć operatora pośredniego dwa razy: jednego do przejścia do wskaźnika, na który wskazuje podwójny wskaźnik, a drugiego do uzyskania dostępu do rzeczywistej wartości.
C
// C program to dereference double pointer> #include> int> main()> {> >int> var = 10;> >int>* ptr = &var;> >// double pointer> >int>** dptr = &ptr;> >// dereferencing the double pointer> >printf>(>'Accesing value from double pointer using '> >'**dptr: %d'>,> >**dptr);> >return> 0;> }> |
program w Pythonie do wyszukiwania binarnego
>
>Wyjście
Accesing value from double pointer using **dptr: 10>
W ten sposób możemy dereferować wskaźniki dowolnego poziomu.
Jak działa dereferencja?
Ilekroć prosimy kompilator o wyłuskanie wskaźnika, robi on trzy rzeczy:
- Najpierw sprawdza adres zapisany we wskaźniku.
- Następnie szuka typu wskaźnika, aby określić ilość pamięci do odczytania. Na przykład 4 bajty dla int, 1 bajt dla char itp. Jest to również główny powód, dla którego musimy określić typ wskaźnika w deklaracji, mimo że rozmiar każdego wskaźnika w systemie jest taki sam.
- Na koniec odczytuje pamięć i zwraca zapisane dane.
Notatka: Z powyższego rozumowania możemy również wywnioskować, że nie możemy wyłuskać wskaźnika void, ponieważ rozmiar danych, na które wskazuje, jest nieznany. Musimy więc wpisać wskaźnik pustki, aby go wyłuskać.