C++

Jak używać wskaźników C++++

Jak używać wskaźników C++++
Pamięć komputera to długa seria komórek. Rozmiar każdej komórki to bajt. Bajt to przestrzeń zajmowana przez angielski znak alfabetu. Obiekt w zwykłym znaczeniu to kolejny zestaw bajtów w pamięci. Każda komórka ma adres, który jest liczbą całkowitą, zwykle zapisywaną w postaci szesnastkowej. Istnieją trzy sposoby uzyskania dostępu do obiektu w pamięci. Dostęp do obiektu można uzyskać za pomocą tak zwanego wskaźnika. Dostęp do niego można uzyskać za pomocą tak zwanej referencji. Nadal można uzyskać do niego dostęp za pomocą identyfikatora. Ten artykuł koncentruje się na wykorzystaniu wskaźników i odniesień. W C++ istnieje obiekt wskazujący i obiekt wskazujący. Wskazany przedmiot ma przedmiot zainteresowania. Obiekt wskaźnika ma adres do wskazanego obiektu.

Musisz mieć podstawową wiedzę na temat C++, w tym jego identyfikatory, funkcje i tablice; aby zrozumieć ten artykuł.

Obiekt wskaźnika i wskazany obiekt, każdy ma swój identyfikator.

Operator adresu, &

To jest jednoargumentowy operator. Gdy następuje identyfikator, zwraca adres obiektu identyfikatora. Rozważ następującą deklarację:

int ptdInt;

Poniżej znajduje się kod, poniższe wyrażenie zwróci adres zidentyfikowany przez ptdInt:

&ptdInt

Nie musisz znać dokładnego adresu (numeru) podczas kodowania.

Operator pośredni, *

Jest to operator jednoargumentowy w kontekście wskaźników. Zwykle wpisuje się go przed identyfikatorem. W przypadku użycia w deklaracji identyfikatora, to identyfikator jest obiektem wskaźnika, który przechowuje tylko adres wskazanego obiektu. Jeśli zostanie użyty przed identyfikatorem obiektu wskaźnika, aby coś zwrócić, to zwróconą rzeczą jest wartość wskazanego obiektu.

Tworzenie wskaźnika

Spójrz na następujący segment kodu:

pływak ptdFloat;
pływak *ptrFloat;
ptrFot = &ptdFloat;

Segment zaczyna się od deklaracji wskazanego obiektu, ptdFloat. ptdFloat to identyfikator, który po prostu identyfikuje obiekt pływający. Można było do niego przypisać rzeczywisty obiekt (wartość), ale w tym przypadku nic nie zostało do niego przypisane. Dalej w segmencie znajduje się deklaracja obiektu wskaźnika. Operator pośredni przed tym identyfikatorem oznacza, że ​​musi on zawierać adres wskazanego obiektu. Typ obiektu, float na początku instrukcji, oznacza, że ​​wskazany obiekt jest float. Obiekt wskazujący jest zawsze tego samego typu co wskazany obiekt. ptrFoat to identyfikator, który po prostu identyfikuje obiekt wskaźnika.

W ostatniej instrukcji kodu adres wskazywanego obiektu jest przypisany do obiektu wskaźnika. Zwróć uwagę na użycie operatora adresu, &.

Ostatnia instrukcja (linia) powyżej pokazuje, że po zadeklarowaniu obiektu wskaźnika bez inicjalizacji nie potrzebujesz operatora indirection, gdy musisz go zainicjalizować. W rzeczywistości użycie operatora pośredniego w trzecim (ostatnim) wierszu jest błędem składni.

Obiekt wskaźnika można zadeklarować i zainicjować przez wskazany obiekt w jednej instrukcji, w następujący sposób:

pływak ptdFloat;
pływak *ptrFot = &ptdFloat;

Pierwsza linia poprzedniego segmentu kodu i ta są takie same. Drugi i trzeci wiersz poprzedniego segmentu kodu zostały tutaj połączone w jedną instrukcję.

Zauważ w powyższym kodzie, że podczas deklarowania i inicjowania obiektu wskaźnika należy użyć operatora pośredniego. Jednak nie jest używany, jeśli inicjalizacja ma być wykonana później. Obiekt wskaźnika jest inicjowany adresem wskazanego obiektu.

W poniższym segmencie kodu operator pośredni służy do zwracania zawartości wskazanego obiektu.

wewn ptdInt = 5;
int *ptrInt = &ptdInt;
Cout << *ptrInt << '\n';

Wyjście to 5.

W ostatniej instrukcji tutaj operator pośredni został użyty do zwrócenia wartości wskazywanej przez identyfikator wskaźnika. Zatem użyty w deklaracji identyfikator operatora pośredniego będzie zawierał adres wskazanego obiektu. W przypadku użycia w wyrażeniu zwracanym, w połączeniu z identyfikatorem wskaźnika, operator pośredni zwraca wartość wskazanego obiektu.

Przypisywanie zera do wskaźnika

Obiekt wskaźnika powinien zawsze mieć typ wskazywanego obiektu. Podczas deklarowania obiektu wskaźnika należy użyć typu danych wskazanego obiektu. Jednak wskaźnikowi można przypisać wartość zera dziesiętnego jak w następującym segmencie kodu:

wewn ptdInt = 5;
int *ptInt;
ptrInt = 0;
lub w segmencie,
wewn ptdInt = 5;
int *ptrInt = 0;

W obu przypadkach wskaźnik (identyfikator) nazywany jest wskaźnikiem zerowym; to znaczy, wskazuje na nigdzie. Oznacza to, że nie ma adresu żadnego wskazanego obiektu. Tutaj 0 jest zerem dziesiętnym, a nie szesnastkowym. Szesnastkowe zero wskazywałoby na pierwszy adres pamięci komputera computer.

Nie próbuj uzyskać wartości wskazywanej przez pusty wskaźnik. Jeśli spróbujesz, program może się skompilować, ale może się nie wykonać.

Nazwa tablicy jako stały wskaźnik

Rozważ następującą tablicę:

int tab[] = 000, 100, 200, 300, 400;

Nazwa tablicy, arr jest w rzeczywistości identyfikatorem, który ma adres pierwszego elementu tablicy. Poniższe wyrażenie zwraca pierwszą wartość z tablicy:

*arr

W przypadku tablicy operator inkrementacji ++ zachowuje się inaczej. Zamiast dodawać 1, zastępuje adres wskaźnika adresem kolejnego elementu tablicy. Jednak nazwa tablicy jest stałym wskaźnikiem; co oznacza, że ​​jego zawartość (adres) nie może być zmieniana ani powiększana. Tak więc, aby zwiększyć, adres początkowy tablicy musi być przypisany do wskaźnika niestałego w następujący sposób:

int *ptr = arr;

Teraz ptr można zwiększyć, aby wskazywał na następny element tablicy. ptr został tu zadeklarowany jako obiekt wskaźnika. Bez * tutaj nie byłby wskaźnikiem; byłby to identyfikator do przechowywania obiektu int, a nie do przechowywania adresu pamięci.

Poniższy segment kodu ostatecznie wskazuje na czwarty element:

++ptr;
++ptr;
++ptr;

Poniższy kod wyświetla czwartą wartość tablicy:

int tab[] = 000, 100, 200, 300, 400;
int *ptr = arr;
++ptr;
++ptr;
++ptr;
Cout << *ptr << '\n';

Wyjście wynosi 300.

Nazwa funkcji jako identyfikator

Nazwa funkcji jest identyfikatorem funkcji. Rozważ następującą definicję funkcji:

int fn()

Cout << "seen" << '\n';
powrót 4;

fn jest identyfikatorem funkcji. Ekspresja,

&fn

zwraca adres funkcji w pamięci. fn jest jak szpiczasty przedmiot. Poniższa deklaracja deklaruje wskaźnik do funkcji:

int (*funkcja)();

Identyfikator wskazywanego obiektu i identyfikator obiektu wskaźnika są różne. func jest wskaźnikiem do funkcji. fn jest identyfikatorem funkcji. I tak, func może wskazywać na fn w następujący sposób:

funkcja = &fn;

Wartość (treść) func jest adresem fn. Te dwa identyfikatory mogły zostać połączone z instrukcją inicjalizacji w następujący sposób:

int (*funkcja)() = &fn;

Zwróć uwagę na różnice i podobieństwa w obsłudze wskaźników funkcji i wskaźników skalarnych. func jest wskaźnikiem do funkcji; jest to przedmiot szpiczasty; jest zadeklarowany inaczej niż wskaźnik skalarny.

Funkcję można wywołać za pomocą,

fn()
lub
funkcja()

Nie można go wywołać za pomocą *func().

Gdy funkcja ma parametry, drugie nawiasy zawierają typy parametrów i nie muszą mieć identyfikatorów parametrów. Poniższy program ilustruje to:

#zawierać
przy użyciu standardowej przestrzeni nazw;
float fn(float fl, int in)

powrót fl;

int main()

float (*func)(float, int) = &fn;
wartość zmiennoprzecinkowa = func(2.5, 6);
Cout << val << '\n';
zwróć 0;

Wyjście to 2.5.

Odniesienie do C++

Odwoływanie się w C++ to tylko sposób na wytworzenie synonimu (innej nazwy) dla identyfikatora. Używa operatora &, ale nie w taki sam sposób, jak & jest używany do wskaźników. Rozważ następujący segment kodu:

int mojeInt = 8;
int &yourInt = myInt;
Cout << myInt << '\n';
Cout << yourInt << '\n';

Dane wyjściowe to:

8
8

Pierwsza instrukcja inicjuje identyfikator myInt; ja.mi. myInt jest zadeklarowane i zmuszone do przechowywania wartości, 8. Druga instrukcja tworzy nowy identyfikator, yourInt synonim myInt. Aby to osiągnąć, operator & jest umieszczany między typem danych a nowym identyfikatorem w deklaracji. Oświadczenia cout pokazują, że te dwa identyfikatory są synonimami. Aby zwrócić wartość w tym przypadku, nie trzeba poprzedzać jej * . Wystarczy użyć identyfikatora.

myInt i yourInt tutaj nie są dwoma różnymi obiektami. Są to dwa różne identyfikatory odwołujące się (identyfikujące) do tej samej lokalizacji w pamięci o wartości 8. Jeśli wartość myInt zostanie zmieniona, wartość yourInt również zmieni się automatycznie. Jeśli wartość yourInt zostanie zmieniona, wartość myInt również zmieni się automatycznie.

Referencje są tego samego typu.

Odniesienie do funkcji

Tak jak możesz mieć odwołanie do skalara, możesz również mieć odwołanie do funkcji. Jednak kodowanie referencji do funkcji różni się od kodowania referencji do skalara. Poniższy program ilustruje to:

#zawierać
przy użyciu standardowej przestrzeni nazw;
float fn(float fl, int in)

powrót fl;

int main()

float (&func)(float, int) = fn;
wartość zmiennoprzecinkowa = func(2.5, 6);
Cout << val << '\n';
zwróć 0;

Wyjście to 2.5.

Zwróć uwagę na pierwszą instrukcję w funkcji main, która sprawia, że ​​func jest synonimem fn. Oba odwołują się do tej samej funkcji. Zwróć uwagę na jednorazowe użycie i położenie &. Więc & jest tutaj operatorem odniesienia, a nie operatorem adresu. Aby wywołać funkcję, po prostu użyj dowolnej nazwy.

Identyfikator odniesienia to nie to samo, co identyfikator wskaźnika.

Funkcja zwracająca wskaźnik

W poniższym programie funkcja zwraca wskaźnik, którym jest adres wskazywanego obiektu:

#zawierać
przy użyciu standardowej przestrzeni nazw;
float *fn(float fl, int in)

pływak *pełny = &fl;
powrót pełny;

int main()

float *val = fn(2.5, 6);
Cout << *val << '\n';
zwróć 0;

Wyjście to 2.5

Pierwsza instrukcja w funkcji, fn(), służy tylko do utworzenia obiektu wskaźnika. Zwróć uwagę na jednorazowe użycie i pozycję * w sygnaturze funkcji. Zwróć także uwagę, w jaki sposób wskaźnik (adres) został odebrany w funkcji main() przez inny obiekt wskaźnika.

Funkcja zwracająca referencję

W poniższym programie funkcja zwraca odwołanie:

#zawierać
przy użyciu standardowej przestrzeni nazw;
float &fn(float fl, int in)

pływak &frr = fl;
powrót frr;

int main()

zmiennoprzecinkowa &val = fn(2.5, 6);
Cout << val << '\n';
zwróć 0;

Wyjście to 2.5.

Pierwsza instrukcja w funkcji, fn(), służy tylko do tworzenia referencji. Zwróć uwagę na jednorazowe użycie i pozycję & w sygnaturze funkcji. Zwróć także uwagę, w jaki sposób odwołanie zostało odebrane w funkcji main() przez inną referencję.

Przekazywanie wskaźnika do funkcji

W poniższym programie wskaźnik, który w rzeczywistości jest adresem obiektu ze wskazaniem zmiennoprzecinkowym, jest wysyłany jako argument do funkcji:

#zawierać
przy użyciu standardowej przestrzeni nazw;
float fn(float *fl, int in)

powrót *fl;

int main()

pływak v = 2.5;
wartość zmiennoprzecinkowa = fn(&v, 6);
Cout << val << '\n';
zwróć 0;

Wyjście to 2.5

Zwróć uwagę na użycie i pozycję * dla parametru float w sygnaturze funkcji. Zaraz po rozpoczęciu oceny funkcji fn() tworzona jest następująca instrukcja:

pływak *fl = &v;

Zarówno fl, jak i &v wskazują na ten sam spiczasty obiekt, który zawiera 2.5. *fl w deklaracji return nie jest deklaracją; oznacza to wartość wskazanego obiektu wskazywanego przez obiekt wskaźnika.

Przekazywanie referencji do funkcji

W poniższym programie referencja jest wysyłana jako argument do funkcji:

#zawierać
przy użyciu standardowej przestrzeni nazw;
float fn(float &fl, int in)

powrót fl;

int main()

pływak v = 2.5;
wartość zmiennoprzecinkowa = fn(v, 6);
Cout << val << '\n';
zwróć 0;

Wyjście to 2.5

Zwróć uwagę na użycie i położenie & dla parametru float w sygnaturze funkcji. Zaraz po rozpoczęciu oceny funkcji fn() tworzona jest następująca instrukcja:

pływak &fl = v;

Przekazywanie tablicy do funkcji

Poniższy program pokazuje, jak przekazać tablicę do funkcji:

#zawierać
przy użyciu standardowej przestrzeni nazw;
int fn(int arra[])

powrót arra[2];

int main()

int tab[] = 000, 100, 200, 300, 400;
int wart = fn(arr);
Cout << val << '\n';
zwróć 0;

Wyjście to 200.

W tym programie przekazywana jest tablica. Zauważ, że parametr sygnatury funkcji ma pustą deklarację tablicy. Argumentem w wywołaniu funkcji jest tylko nazwa utworzonej tablicy.

Czy funkcja C++ może zwrócić tablicę??

Funkcja w C++ może zwrócić wartość tablicy, ale nie może zwrócić tablicy. Kompilacja następującego programu powoduje wyświetlenie komunikatu o błędzie:

#zawierać
przy użyciu standardowej przestrzeni nazw;
int fn(int arra[])

powrót arra;

int main()

int tab[] = 000, 100, 200, 300, 400;
int wart = fn(arr);
zwróć 0;

Wskaźnik wskaźnika

Wskaźnik może wskazywać na inny wskaźnik. Oznacza to, że obiekt wskaźnika może mieć adres innego obiektu wskaźnika. Wciąż muszą być tego samego typu. Poniższy segment kodu ilustruje to:

wewn ptdInt = 5;
int *ptrInt = &ptdInt;
int **ptrptrInt = &ptrInt;
Cout << **ptrptrInt << '\n';

Wyjście to 5.

W deklaracji „wskaźnik-wskaźnik” użyto podwójnego *. Aby zwrócić wartość ostatniego wskazanego obiektu, nadal używane jest podwójne *.

Tablica wskaźników

Poniższy program pokazuje, jak zakodować tablicę wskaźników:

#zawierać
przy użyciu standardowej przestrzeni nazw;
int main()

int num0=000, num1=100, num2=200, num3=300, num4=400;
int *no0=&num0, *no1=&num1, *no2=&num2, *no3=&num3, *no4=&num4;
int *arr[] = nr0, nr1, nr2, nr3, nr4;
Cout << *arr[4] << '\n';
zwróć 0;

Dane wyjściowe to:

400

Zwróć uwagę na użycie i pozycję * w deklaracji tablicy. Zwróć uwagę na użycie * podczas zwracania wartości w tablicy. W przypadku wskaźników ze wskaźnikami zaangażowane są dwa *. W przypadku tablicy wskaźników jeden * został już załatwiony, ponieważ identyfikator tablicy to wskaźnik point.

Tablica ciągów o zmiennej długości

Literał łańcuchowy to stała, która zwraca wskaźnik. Tablica ciągów o zmiennej długości jest tablicą wskaźników. Każda wartość w tablicy jest wskaźnikiem. Wskaźniki są adresami do lokalizacji w pamięci i mają ten sam rozmiar. Łańcuchy o różnych długościach znajdują się gdzie indziej w pamięci, a nie w tablicy. Poniższy program ilustruje zastosowanie:

#zawierać
przy użyciu standardowej przestrzeni nazw;
int main()

const char *arr[] = "kobieta", "chłopiec", "dziewczyna", "dorosły";
Cout << arr[2] << '\n';
zwróć 0;

Wyjście to „dziewczyna”.

Deklaracja tablicy zaczyna się od słowa zastrzeżonego „const” dla stałej; po którym następuje „znak” dla znaku, a następnie gwiazdka, *, aby wskazać, że każdy element jest wskaźnikiem. Aby zwrócić łańcuch z tablicy, * nie jest używane ze względu na niejawną naturę wskaźnika każdego łańcucha. Jeśli użyto *, to zostanie zwrócony pierwszy element ciągu.

Wskaźnik do funkcji zwracającej wskaźnik

Poniższy program ilustruje kodowanie wskaźnika do funkcji zwracającej wskaźnik:

#zawierać
przy użyciu standardowej przestrzeni nazw;
int *fn()

liczba int = 4;
int *inter = #
powrót inter;

int main()

int *(*funkcja)() = &fn;
int wart = *funkcja();
Cout << val << '\n';
zwróć 0;

Wyjście to 4.

Deklaracja wskaźnika do funkcji zwracającej wskaźnik jest podobna do deklaracji wskaźnika do zwykłej funkcji ale poprzedzona gwiazdką. Ilustruje to pierwsza instrukcja funkcji main(). Aby wywołać funkcję za pomocą wskaźnika, poprzedź ją *.

Wniosek

Aby utworzyć wskaźnik do skalara, zrób coś takiego:,

pływak wskazał;
pływak *wskaźnik = &pointed;

* ma dwa znaczenia: w deklaracji wskazuje wskaźnik; zwrócić coś, to za wartość wskazanego przedmiotu.

Nazwa tablicy jest stałym wskaźnikiem do pierwszego elementu tablicy.

Aby utworzyć wskaźnik do funkcji, możesz zrobić,

int (*funkcja)() = &fn;

gdzie fn() jest funkcją zdefiniowaną gdzie indziej, a func jest wskaźnikiem.

& ma dwa znaczenia: w deklaracji wskazuje odwołanie (synonim) do tego samego obiektu co inny identyfikator; kiedy coś zwracasz, oznacza to adres.

Aby utworzyć odwołanie do funkcji, możesz zrobić,

float (&refFunc)(float, int) = fn;

gdzie fn() jest funkcją zdefiniowaną gdzie indziej, a refFunc jest odniesieniem.

Gdy funkcja zwraca wskaźnik, zwracana wartość musi zostać odebrana przez wskaźnik. Gdy funkcja zwraca referencję, zwracana wartość musi zostać odebrana przez referencję.

Przy przekazywaniu wskaźnika do funkcji parametrem jest deklaracja, a argumentem adres wskazywanego obiektu. Podczas przekazywania referencji do funkcji parametrem jest deklaracja, a argumentem referencja.

Podczas przekazywania tablicy do funkcji parametr jest deklaracją, a argumentem jest nazwa tablicy bez []. Funkcja C++ nie zwraca tablicy.

Wskaźnik do wskaźnika wymaga dwóch * zamiast jednego, jeśli jest to właściwe.

Chrys

Gry Jak zwiększyć FPS w Linuksie??
Jak zwiększyć FPS w Linuksie??
FPS oznacza Klatki na sekundę. Zadaniem FPS jest pomiar liczby klatek na sekundę podczas odtwarzania wideo lub wydajności gier. W prostych słowach lic...
Gry Najlepsze gry w laboratorium aplikacji Oculus
Najlepsze gry w laboratorium aplikacji Oculus
Jeśli jesteś posiadaczem gogli Oculus, musisz wiedzieć o sideloadingu. Sideloading to proces instalowania w zestawie nagłownym treści innych niż sklep...
Gry Top 10 Games to Play on Ubuntu
Top 10 Games to Play on Ubuntu
Windows platform has been one of the dominating platforms for gaming because of the huge percentage of games that are developing today to natively sup...