Jak używać wskazówek C ++

Jak używać wskazówek C ++
Pamięć komputera to długa seria komórek. Rozmiar każdej komórki nazywa się bajtem. Bajt to przestrzeń zajmowana przez angielską postać alfabetu. Obiekt w zwykłym znaczeniu jest kolejnym zestawem bajtów w pamięci. Każda komórka ma adres, który jest liczbą całkowitą, zwykle napisaną w formie sześciokadciowskiej. Istnieją trzy sposoby dostępu do obiektu w pamięci. Do obiektu można uzyskać za pomocą tak zwanego wskaźnika. Można do niego uzyskać dostęp, używając tak zwanego odniesienia. Nadal można go uzyskać za pomocą identyfikatora. Ten artykuł koncentruje się na użyciu wskazówek i odniesień. W C ++ znajduje się spiczasty obiekt i obiekt wskaźnika. Spiczasty obiekt ma przedmiot zainteresowania. Obiekt wskaźnika ma adres do spiczastego obiektu. Obiekt wskaźnika i spiczasty obiekt, każdy ma swój identyfikator. Musisz mieć podstawową wiedzę w C ++, w tym jej identyfikatory, funkcje i tablice; Aby zrozumieć ten artykuł.

Adres Operator i

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

int Ptdint;

Poniżej znajduje się kod, następujące wyrażenie zwróci adres zidentyfikowany przez PTDINT:

& Ptdint

Nie musisz znać dokładnego adresu (numeru) jako kodu.

Operator pośrednich, *

To jest nieusowy operator w kontekście wskaźników. Zwykle jest wpisany przed identyfikatorem. Jeśli używany w deklaracji identyfikatora, wówczas identyfikatorem jest obiekt wskaźnika, który utrzymuje tylko adres spiczastego obiektu. Jeśli zostanie użyty przed identyfikatorem obiektu wskaźnika, aby coś zwrócić, to zwrócona rzecz to wartość spiczastego obiektu.

Tworzenie wskaźnika

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

float ptdfloat;
float *ptrfloat;
ptrfoat = &ptdFloat;

Segment rozpoczyna się od deklaracji spiczastego obiektu, Ptdfloat. PTDFLOAT to identyfikator, który po prostu identyfikuje obiekt zmiennoprzecinkowy. Rzeczywisty obiekt (wartość) mógł zostać przypisany do niego, ale w tym przypadku nic nie zostało do niego przypisane. Następnie w segmencie znajduje się deklaracja obiektu wskaźnika. Operator pośredniego przed tym identyfikatorem oznacza, że ​​musi utrzymywać adres spiczastego obiektu. Typ obiektu, unoszący się na początku instrukcji, oznacza, że ​​spiczasty obiekt jest pływakiem. Obiekt wskaźnika jest zawsze tego samego typu, co spiczasty obiekt. Ptrfoat to identyfikator, który po prostu identyfikuje obiekt wskaźnika.

W ostatnim stwierdzeniu kodu adres spiczastego obiektu jest przypisany do obiektu wskaźnika. Zwróć uwagę na korzystanie z operatora adresu i.

Ostatnie stwierdzenie (wiersz) powyżej pokazuje, że po ogłoszeniu obiektu wskaźnika bez inicjalizacji nie potrzebujesz operatora pośredniego, gdy musisz go zainicjować. W rzeczywistości użycie operatora pośredniego jest błędem składni.

Obiekt wskaźnika może być zadeklarowany i zainicjowany przez spiczasty obiekt w jednym stwierdzeniu, jak następuje:

float ptdfloat;
float *ptrfoat = &ptdFloat;

Pierwszy wiersz poprzedniego segmentu kodu i ten jest taki sam. Drugie i trzecie wiersze poprzedniego segmentu kodu zostały tutaj połączone w jedno stwierdzenie.

Zwróć uwagę w powyższym kodzie, że podczas deklarowania i inicjalizacji obiektu wskaźnika należy użyć operatora pośredniego. Nie jest jednak używane, jeśli inicjalizacja ma być później wykonana. Obiekt wskaźnika jest inicjowany z adresem spiczastego obiektu.

W poniższym segmencie kodu operator pośredniego służy do zwrócenia zawartości spiczastego obiektu.

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

Wyjście to 5.

W ostatnim stwierdzeniu tutaj operator pośredniego został wykorzystany do zwrócenia wartości wskazanej przez identyfikator wskaźnika. Tak więc, gdy jest używany w deklaracji, identyfikator dla operatora pośredniego utrzymałby adres spiczastego obiektu. W przypadku wyrażenia powrotu, w połączeniu z identyfikatorem wskaźnika, operator pośrednich zwraca wartość spiczastego obiektu.

Przypisanie zeru do wskaźnika

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

int Ptdint = 5;
int *ptrint;
ptrint = 0;
lub w segmencie,
int Ptdint = 5;
int *ptrint = 0;

W obu przypadkach wskaźnik (identyfikator) nazywa się wskaźnikiem zerowym; Oznacza to, że nie wskazuje na nigdzie. Oznacza to, że nie ma adresu żadnego spiczastego obiektu. Tutaj 0 to zero dziesiętne, a nie heksadecimal zero. Heksadecimal zero wskazywałby na pierwszy adres pamięci komputera.

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

Nazwa tablicy jako stały wskaźnik

Rozważ następującą tablicę:

int arr [] = 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ść w tablicy:

*arr

Z tablicą operator przyrostowy ++ zachowuje się inaczej. Zamiast dodawać 1, zastępuje adres wskaźnika, adresem następnego elementu w tablicy. Nazwa tablicy jest jednak stałym wskaźnikiem; Oznacza to, że jego treści (adres) nie można zmienić ani zwiększyć. Tak więc, aby zwiększyć, adres początkowy tablicy należy przypisać do wskaźnika nieksięgowego w następujący sposób:

int *ptr = arr;

Teraz PTR można zwiększyć, aby wskazać następny element tablicy. PTR został tutaj ogłoszony jako obiekt wskaźnika. Bez * tutaj nie byłby to wskaźnik; Byłoby to identyfikator przechowywania obiektu INT, a nie przechowywanie adresu pamięci.

Poniższy segment kodu w końcu wskazuje na czwarty element:

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

Poniższy kod przedstawia czwartą wartość tablicy:

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

Wyjście to 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,

i fn

Zwraca adres funkcji w pamięci. FN jest jak spiczasty obiekt. Poniższa deklaracja deklaruje wskaźnik do funkcji:

int (*func) ();

Identyfikator dla spiczastego obiektu i identyfikatora obiektu wskaźnika jest inny. FUNC jest wskaźnikiem funkcji. FN jest identyfikatorem funkcji. I tak, FUNC można wskazać na FN w następujący sposób:

func = &fn;

Wartość (treść) FUNC jest adresem FN. Dwa identyfikatory mogły być powiązane z oświadczeniem inicjalizacyjnym w następujący sposób:

int (*func) () = &fn;

Zwróć uwagę na różnice i podobieństwa w zakresie obsługi wskaźników funkcji i wskaźników skalarnych. FUNC jest wskaźnikiem funkcji; Jest to spiczasty obiekt; jest deklarowany inaczej niż wskaźnik skalarny.

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

fn ()
Lub
func ()

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

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

#włączać
za pomocą przestrzeni nazw Std;
float fn (float fl, int in)

return fl;

int main ()

float (*func) (float, int) = &fn;
float val = func (2.5, 6);
Cout << val << '\n';
powrót 0;

Wyjście to 2.5.

Odniesienie C ++

Odwołanie się do C ++ to tylko sposób na stworzenie synonimu (inna nazwa) dla identyfikatora. Używa i operatora, ale nie w taki sam sposób, jak i jest używany do wskazówek. Rozważ następujący segment kodu:

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

Wyjście to:

8
8

Pierwsze stwierdzenie inicjuje identyfikator, MyINT; I.mi. Myint jest zadeklarowany i zmuszony do utrzymania wartości, 8. Drugie stwierdzenie stanowi nowy identyfikator, twój jest synonimem MyINT. Aby to osiągnąć, i operator jest umieszczany między typem danych a nowym identyfikatorem w deklaracji. Oświadczenia Cout pokazują, że dwa identyfikatory są synonimami. Aby zwrócić wartość w tym przypadku, nie musisz jej poprzedzać * . Po prostu użyj identyfikatora.

MyINT i twójt tutaj, nie są dwa różne obiekty. Są to dwa różne identyfikatory odnoszące się (identyfikujące) tę samą lokalizację w pamięci o wartości, 8. Jeśli wartość MyINT zostanie zmieniona, wartość Twojego Int zmieni się również automatycznie. Jeśli wartość twojegot zostanie zmieniona, wartość MyINT również zmieni się automatycznie.

Odniesienia są tego samego typu.

Odniesienie do funkcji

Podobnie jak możesz odwołać się do skalaru, możesz również mieć odniesienie do funkcji. Jednak kodowanie odniesienia do funkcji różni się od kodowania odniesienia do skalar. Poniższy program ilustruje to:

#włączać
za pomocą przestrzeni nazw Std;
float fn (float fl, int in)

return fl;

int main ()

float (& func) (float, int) = fn;
float val = func (2.5, 6);
Cout << val << '\n';
powrót 0;

Wyjście to 2.5.

Zwróć uwagę na pierwsze stwierdzenie w głównej funkcji, która czyni FUNC synonimem FN. Oba odwołują się do tej samej funkcji. Zwróć uwagę na jedno zastosowanie i pozycję i. Więc i jest operatorem referencyjnym, a nie operatorem adresu. Aby wywołać funkcję, po prostu użyj dowolnej nazwy.

Identyfikator referencyjny nie jest taki sam jak identyfikator wskaźnika.

Funkcja zwracająca wskaźnik

W poniższym programie funkcja zwraca wskaźnik, który jest adresem spiczastego obiektu:

#włączać
za pomocą przestrzeni nazw Std;
float *fn (float fl, int in)

float *fll = &fl;
return fll;

int main ()

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

Wyjście to 2.5

Pierwsza instrukcja w funkcji, fn () jest tylko po to, aby utworzyć obiekt wskaźnika. Zwróć uwagę na jedno zastosowanie i pozycję * w podpisie funkcji. Zwróć również uwagę, w jaki sposób wskaźnik (adres) został odebrany w funkcji Main () przez inny obiekt wskaźnika.

Funkcja zwracająca odniesienie

W poniższym programie funkcja zwraca referencję:

#włączać
za pomocą przestrzeni nazw Std;
float & fn (float fl, int in)

float & frr = fl;
return frr;

int main ()

float & val = fn (2.5, 6);
Cout << val << '\n';
powrót 0;

Wyjście to 2.5.

Pierwsza instrukcja w funkcji, fn () jest tylko po to, aby utworzyć odniesienie. Zwróć uwagę na jedno zastosowanie i pozycję i w podpisie funkcji. Zwróć również uwagę, w jaki sposób odniesienie zostało odebrane w funkcji Main () przez inne odniesienie.

Przekazanie wskaźnika do funkcji

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

#włączać
za pomocą przestrzeni nazw Std;
float fn (float *fl, int in)

return *fl;

int main ()

float v = 2.5;
float val = fn (& v, 6);
Cout << val << '\n';
powrót 0;

Wyjście to 2.5

Zwróć uwagę na użycie i położenie * dla parametru zmiennoprzecinkowego w podpisie funkcji. Gdy tylko rozpocznie się ocena funkcji FN (), dokonano następującego stwierdzenia:

float *fl = & v;

Zarówno Fl i i V wskazują na ten sam spiczasty obiekt, który zawiera 2.5. *Fl w oświadczeniu zwrotnym nie jest deklaracją; Oznacza to, że wartość wskazanego obiektu wskazanego przez obiekt wskaźnika.

Przekazywanie odniesienia do funkcji

W poniższym programie odniesienie jest wysyłane jako argument do funkcji:

#włączać
za pomocą przestrzeni nazw Std;
float fn (float i fl, int in)

return fl;

int main ()

float v = 2.5;
float val = fn (v, 6);
Cout << val << '\n';
powrót 0;

Wyjście to 2.5

Zwróć uwagę na użycie i pozycję parametru pływaka w podpisie funkcji. Gdy tylko rozpocznie się ocena funkcji FN (), dokonano następującego stwierdzenia:

float & fl = v;

Przekazanie tablicy do funkcji

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

#włączać
za pomocą przestrzeni nazw Std;
int fn (int arra [])

return arra [2];

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
Cout << val << '\n';
powrót 0;

Wyjście to 200.

W tym programie jest to przekazana tablica. Zauważ, że parametr podpisu funkcji ma pustą deklarację tablicy. Argument w wywołaniu funkcji to 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. Kompilowanie następującego programu powoduje komunikat o błędzie:

#włączać
za pomocą przestrzeni nazw Std;
int fn (int arra [])

return arra;

int main ()

int arr [] = 000, 100, 200, 300, 400;
int val = fn (arr);
powrót 0;

Wskaźnik wskaźnika

Wskaźnik może wskazać na inny wskaźnik. To znaczy obiekt wskaźnika może mieć adres innego obiektu wskaźnika. Nadal muszą być tego samego typu. Poniższy segment kodu to ilustruje:

int Ptdint = 5;
int *ptrint = &ptdInt;
int ** ptrptrint = &ptrInt;
Cout << **ptrptrInt << '\n';

Wyjście to 5.

W Deklaracji Wskaźnika do wskaźnika jest używane podwójne *. Aby zwrócić wartość ostatecznego spiczastego obiektu, podwójne * jest nadal używane.

Szereg wskaźników

Poniższy program pokazuje, jak kodować szereg wskazówek:

#włączać
za pomocą przestrzeni nazw Std;
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 [] = no0, no1, no2, no3, no4;
Cout << *arr[4] << '\n';
powrót 0;

Wyjście to:

400

Zwróć uwagę na użycie i pozycję * w deklaracji tablicy. Zwróć uwagę na użycie * przy zwracaniu wartości w tablicy. Z wskaźnikami wskaźników zaangażowanych jest dwa *. W przypadku tablicy wskaźników jeden * został już zaopiekowany, ponieważ identyfikator tablicy jest wskaźnikiem.

Tablica strun o zmiennej długości

Literał łańcuchowy to stała, która zwraca wskaźnik. Szereg ciągów o zmiennej długości to szereg wskaźników. Każda wartość w tablicy jest wskaźnikiem. Wskaźniki są adresami do lokalizacji pamięci i są tego samego rozmiaru. Struny różnych długości są gdzie indziej w pamięci, a nie w tablicy. Poniższy program ilustruje użycie:

#włączać
za pomocą przestrzeni nazw Std;
int main ()

const char *arr [] = „kobieta”, „chłopiec”, „dziewczyna”, „dorosła”;
Cout << arr[2] << '\n';
powrót 0;

Wyjście to „dziewczyna”.

Deklaracja tablicy zaczyna się od zastrzeżonego słowa „const” dla stałego; a następnie „char” dla postaci, a następnie gwiazdka *, aby wskazać, że każdy element jest wskaźnikiem. Aby zwrócić ciąg z tablicy, * nie jest używany, ze względu na niejawną naturę wskaźnika każdego łańcucha. Jeśli użyje się *, wówczas pierwszy element ciągu zostanie zwrócony.

Wskaźnik do funkcji zwracającej wskaźnik

Poniższy program ilustruje, w jaki sposób wskaźnik do funkcji zwracającej wskaźnik jest kodowany:

#włączać
za pomocą przestrzeni nazw Std;
int *fn ()

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

int main ()

int *( *func) () = &fn;
int val = *func ();
Cout << val << '\n';
powrót 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ą. Pierwsze stwierdzenie w funkcji main () ilustruje to. Aby wywołać funkcję za pomocą wskaźnika, poprzedź ją *.

Wniosek

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

pływak spiczasty;
float *wskaźnik = &pointed;

* ma dwa znaczenia: w deklaracji wskazuje wskaźnik; Aby coś zwrócić, dotyczy wartości spiczastego obiektu.

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

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

int (*func) () = &fn;

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

i ma dwa znaczenia: w deklaracji wskazuje to odniesienie (synonim) tego samego obiektu co inny identyfikator; Przy zwracaniu czegoś oznacza adres.

Aby utworzyć odniesienie do funkcji, możesz zrobić,

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

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

Gdy funkcja zwróci wskaźnik, zwrócona wartość musi zostać odebrana przez wskaźnik. Gdy funkcja zwraca referencję, zwrócona wartość musi zostać odebrana przez odniesienie.

Podczas przekazywania wskaźnika do funkcji parametr jest deklaracją, podczas gdy argument jest adresem spiczastego obiektu. Podczas przekazywania odniesienia do funkcji parametr jest deklaracją, podczas gdy argument jest odniesieniem.

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

Wskaźnik wskaźnika do wskaźnika potrzebuje dwóch * zamiast jednego, w stosownych przypadkach.