2010-09-26 18 views
20

Jestem trochę zdezorientowany, jak działają wskaźniki przejścia.C++ Przekazywanie wskaźnika do funkcji (Howto) + manipulacja wskaźnikiem C++

Powiedzmy mam następujące funkcje i wskaźnik, a ...

EDIT:

... Chcę użyć wskaźnika do jakiegoś przedmiotu jako argument funkcji.

tj .:

void Fun(int Pointer){ 
    int Fun_Ptr = ---Passed Pointer---; 
    //So that Fun_Ptr points to whatever ---Passed Pointer points to 

Między * wskaźnik i & Pointer zapisów, jestem bardzo mylić. Wiem, że * Wskaźnik oznacza dawanie tego, co wskazuje.

Czy wstawię pustą (int * wskaźnik) w deklaracji. A co z tym, kiedy używam tej funkcji?

Twoja pomoc jest doceniana.

EDIT 2:

Ok, teraz rozumiem, że za pomocą * zmienna w deklaracji oznacza, że ​​wskaźnik zostanie przekazany. Co jednak z tym, kiedy korzystam z tej funkcji?

tj

int main(){ 
    int foo; 
    int *bar; 
    bar = foo; 
    Fun(bar); 
} 

EDIT 3: Ok, więc poprawcie mnie jeśli się mylę:

Zgodnie z konwencjami powyższego kodu:

bar = & środki Foo : Spraw, aby pasek wskazywał foo w pamięci

* słupek = foo oznacza Zmień t on wartość, która punkty kreskowych do dorównać cokolwiek foo równa

Jeśli mam drugi wskaźnik (int * oof), a następnie:

bar = oof oznacza: punkty kreskowe do wskaźnika oof

bar = * oof oznacza: punkty bar do wartości, które OOF punkty, ale nie do wskaźnika oof samego

* bar = * oof oznacza: Zmień wartość punktów kreskowych do wartości że punkty OOF do

& bar = & oof oznacza: zmień adres pamięci tak, aby były takie same, jak adres pamięci, który wskazuje na:

Czy mam to prawo?

EDYCJA 4: Wielkie dzięki za twoją pomoc (chciałbym przyjąć więcej niż jedną odpowiedź, ale muszę iść z pierwszą.) Nie jestem pewien, jak działa wiki społecznościowe, ale odejdę w ten sposób do edycji (jeśli wolisz, możesz go zamienić w poradnik).

+0

Twoja druga edycja jest prawie poprawna, jednak – Tomas

+0

"Czy to prawda?". Nie. Nie chcesz, aby 'bar' był równy * dla' foo', chcesz żeby * wskazywał * 'foo'. Odbywa się to za pomocą operatora adresu. 'bar = &foo;'. –

+0

bar = foo, jest nieprawidłowy, ponieważ foo jest int i wskazuje wskaźnik. Poprawny kod to "bar = i foo", ponieważ jako wskaźnik, pasek może przechowywać tylko adresy pamięci, a nie int. Przepraszamy za odpowiedź na komentarz. – Tomas

Odpowiedz

39

Jest różnica w używaniu * Podczas definiowania zmiennej i kiedy używasz go.

W deklaracji

int *myVariable; 

Środki wskaźnik do danych typu liczba całkowita. W użyciu, jednak

*myVariable = 3; 

Środki szacunek wskaźnika, a także sprawiają, że struktura jest wskazując na trzy równe, a następnie dokonać wskaźnik równy adres pamięci 0x 0003.

Tak więc w swojej funkcji, to aby to zrobić:

void makePointerEqualSomething(int* pInteger) 
{ 
    *pInteger = 7; 
} 

w deklaracji funkcji, * oznacza, że ​​są przechodzącą wskaźnik, ale w jego rzeczywistym ciałem kod * oznacza uzyskiwania dostępu, co wskazuje na wskaźnik.

Próbując machać dala wszelkie nieporozumienia masz, ja krótko wejść do ampersand (&)

& środki uzyskać adres czegoś, jego dokładną lokalizację w pamięci komputerów, więc

int & myVariable; 

W deklaracji oznacza adres liczby całkowitej lub wskaźnika!

To jednak

int someData;  
pInteger = &someData; 

Środki zrobić wskaźnik pInteger sama (należy pamiętać, wskaźniki są tylko adresy pamięci, co oni point at) równych na adres „someData” - tak teraz pInteger będzie wskazywać na jakiś danych i można go użyć, aby uzyskać do niego dostęp, gdy go oceniasz:

*pInteger += 9000; 

Czy ma to dla ciebie sens? Czy jest coś jeszcze, co uważasz za mylące?

@ Edit3:

Prawie prawidłowe, z wyjątkiem trzech sprawozdaniach

bar = *oof; 

oznacza, że ​​wskaźnik bar jest równa liczbie całkowitej, co nie bar na punkty, które jest nieprawidłowy.

&bar = &oof;

Znak & jest jak funkcja, gdy zwraca adres pamięci nie można modyfikować, skąd pochodzi. Tak jak ten kod:

returnThisInt("72") = 86; 

Jest nieważny, więc jest twój.

Wreszcie

bar = oof 

nie oznacza, że ​​"punkty bar do wskaźnika oof" Oznacza to, że punkty pasek do adresu, który OOF wskazuje, więc punkty bar na cokolwiek foo wskazuje na - nie bar wskazuje na foo, które wskazuje na oof.

+0

Okay, więc czy to oznacza, że ​​wskaźnik pInteger wskazuje wskaźnik someData? – Biosci3c

+1

Powinienem był wyjaśnić, niektóre dane nie są wskaźnikiem, to jest surowe int. Odpowiednio zredagowałem swoją odpowiedź. Czy znak & ma dla ciebie sens? – Tomas

+0

Dobra, myślę, że mam go trochę w dół (wskaźniki zawsze mnie myliły i naprawdę staram się je zrozumieć). Myślę, że mam teraz całkiem dobre pojęcie. – Biosci3c

-1

Być może łatwiej Ci zrozumieć, używając Functionoidów, które są wyraźnie bardziej eleganckie i wydajniejsze w użyciu, zobacz to doskonałe i wysoce zalecane C++ FAQ lite, w szczególności spójrz na sekcję 33.12 i dalej, ale przeczytaj ją od początku w tej sekcji, aby uzyskać jego zrozumienie i zrozumienie.

Aby odpowiedzieć na to pytanie:

typedef void (*foobar)() fubarfn; 

void Fun(fubarfn& baz){ 
    fubarfn = baz; 
    baz(); 
} 

Edit:

  • & oznacza adres odniesienia
  • * oznacza wartość co zawarte na adres odniesienia, zwany de- Odwołanie:

Wykorzystanie poniższego przykładu pokazuje, że przekazujemy parametr i bezpośrednio go modyfikujemy.

void FunByRef(int& iPtr){ 
    iPtr = 2; 
} 

int main(void){ 
    // ... 
    int n; 
    FunByRef(n); 
    cout << n << endl; // n will have value of 2 
} 
+0

Może powinienem wyjaśnić. Nie próbuję użyć wskaźnika do funkcji, ale przekazuję wskaźnik do jakiegoś obiektu (powiedzmy int) do funkcji, więc funkcja może na nim działać. Zmienię moje pytanie, aby to wyjaśnić. – Biosci3c

1
void Fun(int *Pointer) 
{ 
    //if you want to manipulate the content of the pointer: 
    *Pointer=10; 
    //Here we are changing the contents of Pointer to 10 
} 

* przed wskaźnik oznacza zawartość wskaźnika (z wyjątkiem deklaracji!)

& przed kursorem (lub dowolnej zmiennej) oznacza adres

EDIT:

int someint=15; 
//to call the function 
Fun(&someint); 
//or we can also do 
int *ptr; 
ptr=&someint; 
Fun(ptr); 
+0

To jest składnia C, gdy OP wyraźnie określa C++ ... – t0mm13b

+0

@ tommieb75: dlaczego ma znaczenie, że jest poprawny C? Jest to również składnia C++, a osoba pytająca nie określiła "C++, z usuniętym C". Cokolwiek to jest. –

3

Aby przekazać wskaźnik do int, powinno być void Fun(int* pointer).

Przechodząc odwołanie do int wyglądałby następująco ...

void Fun(int& ref) { 
    ref = 10; 
} 

int main() { 
    int test = 5; 
    cout << test << endl; // prints 5 

    Fun(test); 
    cout << test << endl; // prints 10 because Fun modified the value 

    return 1; 
} 
3

Jeśli chcesz przekazać wskaźnik do int do swojej funkcji,

Deklaracja funkcji (jeśli jest to potrzebne):

void Fun(int *ptr); 

Definicja funkcji:

void Fun(int *ptr) { 
    int *other_pointer = ptr; // other_pointer points to the same thing as ptr 
    *other_ptr = 3;   // manipulate the thing they both point to 
} 

Wykorzystanie funkcji:

int main() { 
    int x = 2; 
    printf("%d\n", x); 
    Fun(&x); 
    printf("%d\n", x); 
} 

Zasadniczo należy zauważyć, że zmienne o nazwie Ptr lub Pointer nigdy nie powinny mieć typu int, czyli tego, co masz w swoim kodzie. Wskaźnik do int ma typ int *.

Jeśli mam drugi wskaźnik (int * oof), następnie:

bar = oof oznacza: punkty pasek do oof wskaźnik

To oznacza „uczynić punkt bar do to samo wskazuje na ".

bar = * oof oznacza: punkty bar do wartości że OOF punkty, ale nie do wskaźnik oof sam

To nic nie znaczy, to nieważne. bar to wskaźnik *oof to int. Nie możesz przypisać jednego do drugiego.

* bar = * oof oznacza: Zmień wartość punktów kreskowych do wartości, która oof punkty

Tak.

& bar = & oof oznacza: zmienić adres pamięci że punkty bar taka sama jako adres pamięci, który OOF punkty do

Nie, to znowu nieważne. &bar to wskaźnik do zmiennej bar, ale jest to tak zwana "wartość r" lub "tymczasowa", której nie można przypisać. To jest jak wynik obliczeń arytmetycznych. Nie można pisać x + 1 = 5.

Może pomóc w określeniu wskaźników jako adresów. bar = oof oznacza "make bar, który jest adresem, równym oof, który jest również adresem". bar = &foo oznacza "make bar, który jest adresem, równym adresowi foo". Jeśli bar = *oof nic nie znaczyłoby, oznaczałoby to "make bar, który jest adresem, równym *oof, który jest int". Nie możesz.

Następnie, & jest adresem operatora. To znaczy "adres operandu", więc &foo to adres foo (tj. Wskaźnik do foo). * to operator dereferencji. To znaczy "rzecz pod adresem podanym przez operand". Tak więc po wykonaniu bar = &foo, *bar jest foo.

1
void Fun(int* Pointer) -- would be called as Fun(&somevariable) 

pozwoli na manipulowanie zawartości co punkty „pointer”, aby przez dereferencji go wewnątrz Fun funkcji IE

*Pointer = 1; 

uznającej go jak powyżej pozwala również również do przetwarzania danych poza to, co wskazuje na:

int foo[10] = {0}; 
Fun(foo); 

w funkcji, którą możesz następnie polubić * (Wskaźnik + 1) = 12; ustawienie drugiej wartości tablicy.

void Fun(int& Pointer) -- would be called Fun(somevariable) 

można zmodyfikować, do czego odwołuje się Wskaźnik, jednak w tym przypadku nie można uzyskać dostępu do niczego poza tym, do czego odwołuje się Wskaźnik.

12

Aby zadeklarować funkcję, która pobiera wskaźnik do int:

void Foo(int *x);

Aby korzystać z tej funkcji:


int x = 4; 
int *x_ptr = &x; 
Foo(x_ptr); 
Foo(&x); 

Jeśli chcesz wskaźnik dla innego typu obiektu, jest dużo to samo:

void Foo(Object *o);

Możesz jednak użyć referencji. Są one nieco mniej kłopotliwe niż wskaźniki:


// pass a reference 
void Foo(int &x) 
{ 
    x = 2; 
} 

//pass a pointer 
void Foo_p(int *p) 
{ 
    *x = 9; 
} 

// pass by value 
void Bar(int x) 
{ 
    x = 7; 
} 
int x = 4; 
Foo(x); // x now equals 2. 
Foo_p(&x); // x now equals 9. 
Bar(x); // x still equals 9. 

odniesieniami, nadal się zmieniać X, który został przekazany do funkcji (jak w przypadku wskaźnika), ale nie trzeba się martwić o dereferencji lub adres operacji.

Zgodnie z zaleceniami innych osób, sprawdź numer C++FAQLite. Jest to doskonałe źródło tego.

Edycja 3 odpowiedź:

foo bar = & oznacza: Dodać punkt do foo bar w pamięci

Tak.

* bar = foo oznacza Zmień wartość punktów bar do dorównać cokolwiek foo równa

Tak.

Jeśli mam drugi wskaźnik (int * oof), wówczas:

bar = oof oznacza: Punkty kreskowe do wskaźnika oof

bar będzie wskazywać na dowolnych punktów oof do. Obie będą wskazywały na to samo.

bar = * oof oznacza: punkty pasek do wartości, która OOF punkty, ale nie do tego samego wskaźnika oof

Nie, nie mogę tego zrobić (zakładając bar jest typu int *) Możesz tworzyć wskaźniki wskaźników. (int **), ale nie wdawajmy się w to ... Nie możesz przypisać wskaźnika do int (cóż, możesz, ale to szczegół, który nie jest zgodny z dyskusją).

* bar = * oof oznacza: Zmień wartość punktów kreskowych do wartości, które oof punktów

Tak.

& bar = & oof oznacza zmianę adresu pamięci, który punkty kreskowe być taki sam jak adres pamięci, który oof punktów

Nie, nie może tego zrobić, ponieważ adres zwrotów operatorskich rwartość. Zasadniczo oznacza to, że nie możesz przypisać czegoś do niego.

Powiązane problemy