W tym artykule wyjaśniliśmy różnicę między wskaźnikiem * i ** w C i C++.
Spis treści:
1. Czym są wskaźniki?
2. Przykłady wskaźnika
3. Implementacja wskaźników za pomocą C
4. *p
w porównaniu z **p
wskaźnik
5. Implementacja *p
i **p
używając C
Co to są wskaźniki?
Wskaźnik to zmienna używana do przechowywania adresu w pamięci innej zmiennej.
Dwa operatory użyte we wskaźnikach:
- Operator &:- Podaje adres zmiennej
- Operator * :- Podaje wartości w lokalizacji
Niektóre punkty:
- Adres nie może być ujemny.
- Zmienna wskaźnikowa zajmuje te same bajty pamięci niezależnie od typu danych.
- Zmienna wielkość wskaźnika różni się w zależności od systemu operacyjnego.
- Zmienna wskaźnikowa może wyłuskać nr. bajtów w zależności od typu danych.
* Wskaźnik liczby całkowitej może wyłuskać dwa bajty danych.
* Wskaźnik znakowy może uzyskać dostęp do jednego bajtu danych.
* Wskaźnik zmiennoprzecinkowy może uzyskać dostęp do czterech bajtów danych. - Zmienna wskaźnikowa zostanie zadeklarowana przy użyciu „*” (gwiazdka).
Przykłady wskaźnika:
int * p ; // Declaration of pointer ‘p’
int a = 10 ;
p = &a ; //Assigning
//now pointer ‘p’ is pointing at variable ‘a’.
Tutaj deklarujemy i przypisujemy blok pamięci 'a' do wskaźnika 'p'.
- 'p' jest zmienną wskaźnikową typu integer, w której możemy przechowywać adres dowolnej zmiennej całkowitej.
- „a” to zmienna całkowita przechowująca wartość 10.
int * p ;
int a = 10 , b ;
b = &a ; //ERROR
Tutaj widzimy błąd, ponieważ próbujemy zapisać adres liczby całkowitej „a” w innej liczbie całkowitej „b”
int a = 10 ;
printf(" a = %d " , * &a ); // output will be a = 10
Tutaj wypisujemy wartość 'a', przedstawiając ją jako wskaźnik. Po prostu powiedz a=``*&a
.
int * p ;
int a = 10 ;
p = &a ;
printf(" %d " , a * p ) ; // ERROR
printf(" %d " , a * * p ); // No ERROR
Tutaj widzimy BŁĄD, ponieważ „a” ma wartość (=10) i *p
ma również wartość (=10), ale kompilator będzie się mylić z tym, co chcemy zrobić, ponieważ kompilator widzi to jako printf(" %d ", (a) (*p
) ); , nie ma operatorów arytmetycznych dla kompilatora.
Ale w następnej instrukcji printf() nie widzimy żadnego BŁĘDU, ponieważ kompilator Now da na wyjściu 100, gdy robimy Mnożenie 'a' i *p
i oba zawierają w sobie wartość (=10).
Implementacja wskaźników za pomocą C
#include<stdio.h>
int main(){
int a=10;
int * p = &a ;
printf(" a = %d \n " , * p ) ; // It gives output a = 10
printf(" Address of a = %p \n ", p ) ; // It gives output Address of a
printf(" Address of p = %p \n ", & p ) ; // It gives output Address of p
return 0;
}
Tutaj wypisujemy wartość 'a' i adres 'a' i 'p'.
Wyjście:
a = 10
Address of a = 000000000061FE1C
Address of p = 000000000061FE10
*p
w porównaniu z **p
wskaźnik
*p
jest wskaźnikiem, oznacza, że przechowuje adres wartości lub bloku zarezerwowanej pamięci, może mieć dostęp do jednego poziomu.
Jest używany, jeśli chcesz zachować blok pamięci, w którym znajdują się twoje wartości.
**p
jest wskaźnikiem do wskaźnika, oznacza, że przechowuje adres, który przechowuje adres wartości lub blok zarezerwowanej pamięci, może mieć dostęp do dwóch poziomów.
Jest używany, jeśli chcesz przekazać wskaźnik, który otrzymuje swoją pamięć zaalokowaną w innej funkcji.
#include<stdio.h>
int main(){
int a=10;
int * p = & a ; // b is a single pointer or a pointer
int ** c = &p; // c is a double pointer or pointer to a pointer
printf("using p \n ");
printf(" value of a = %d \n " , * p ) ; // It gives output value of a = 10
printf(" Address of a = %p \n ", p ) ; // It gives output Address of a
printf(" Address of p = %p \n", & p ) ; // It gives output Address of p
printf("using c \n ");
printf(" value of a = %d \n ", ** c ) ; // It gives output value of a
printf(" Address of a = %p \n ", * c ) ; // It gives output Address of a
printf(" Address of c = %p \n ", &c ) ; // It gives output Address of c
printf(" Address of p = %p \n ", c ) ; // It gives output Address of p
return 0;
}
Tutaj wypisujemy wartości i adresy za pomocą wskaźnika i podwójnego wskaźnika.
Wyjście:
using p
value of a = 10
Address of a = 000000000061FE1C
Address of p = 000000000061FE10
using c
value of a = 10
Address of a = 000000000061FE1C
Address of c = 000000000061FE08
Address of p = 000000000061FE10
Implementacja *p
i **p
używając C
#include<stdio.h>
void swap(int * x ,int * y ){
int t = * x ;
* x = * y ;
* y = t ;
}
int main(){
int a = 10 , b = 20 ;
printf(" Value of 'a' before swap = %d \n", a );
printf(" Value of 'b' before swap = %d \n", b );
swap( & a , & b ) ; //function call
printf(" Value of 'a' after swap = %d \n", a );
printf(" Value of 'b' after swap = %d \n", b );
return 0;
}
Tutaj Zamieniamy dwie liczby za pomocą wskaźników.
Podczas wywoływania funkcji swap() wysyłamy adresy bloków pamięci (tj. a, b) i aby pobrać te adresy, jako argumenty w swap() przyjmujemy wskaźniki całkowite (tj. x, y).
W funkcji swap() zamieniamy wartości adresów.
Wyjście:
Value of 'a' before swap = 10
Value of 'b' before swap = 20
Value of 'a' after swap = 20
Value of 'b' after swap = 10
#include<stdio.h>
void func(int ** p1 )
{
int b = 2;
* p1 = & b;
}
int main()
{
int a = 10;
int * p = &a;
printf("Before the function, value of the p : %d \n", * p) ;
func(&p); //function Call
printf("After the function, new value of the p : %d \n", * p) ;
return 0;
}
Tutaj najpierw bierzemy liczbę całkowitą „a” i przypisujemy jej wartość 10,
następnie biorąc wskaźnik całkowity 'p' i przypisując adres 'a' do 'p'.
Teraz w wywołaniu funkcji func() podajemy adres 'p', który jest wskaźnikiem, aby pobrać adres wskaźnika, funkcja func() powinna mieć wskaźnik całkowity do wskaźnika jako argument (tj. p1 w func (p1) ).
W func() zmieniamy wartość z 10 na 2.
Wyjście:
Before the function, value of the p : 10
After the function, new value of the p : 2
Z tym artykułem w OpenGenus, musisz mieć pełny pomysł na wskaźnik * vs ** w C.