2015-11-11 12 views
6

Jestem mylić, co wiersz kodu w tym programie:Co robi "* (wskaźnik + liczba całkowita)" w C++?

int *temp = new int [cap]; 
int num = 0; 

for(int i = name; i < number; i++) 
{ 
*(temp + count) = *(foo + i); 
num++; 
} 

name, number i foo są zmienne globalne (foo bycia wskaźnik), i cap jest argumentem.

Konkretnie, nie rozumiem tej linii:

*(temp + count) = *(foo + i); 

Dlaczego są wskaźnikami do nawiasów, a co będzie to zrobić?

+6

Nie mogę uwierzyć, że nie mamy odpowiedniego duplikatu tego pytania. –

+3

To jest całkiem dobre pierwsze pytanie, ale zredagowałem wiele obcojęzycznych słów. Niepotrzebne * informacje *, zgodnie z oryginalną linią "przepraszam za wszelkie informacje"; w szczególności zaczynałeś od stwierdzenia, że ​​nie masz pewności co do * konkretnej linii * w programie, ale bez twoich "dodatkowych" informacji, nie byłoby żadnego wskazania, * która * linia cię pomyliła! –

+0

Jest to alternatywna składnia do indeksowania tablic. –

Odpowiedz

1

*(temp + count) = *(foo + i) oznacza:

uzyskać adres temp, dodać count przesunięcie do niego, a następnie ustawić wartość wynikająca adres temp + count cenić od adresu foo z przesunięciem i

Lepsze będą:

temp[count] = foo[i]; 

(Nawiasem mówiąc, jest to styl C (z wyjątkiem new), a nie C++. Bardzo zły kod.)

+2

Jest to niejasny sposób na zapisanie temp [count] = foo [i]; – cwallach

+3

To też nie jest styl "C", jest po prostu złe. –

+1

@ cwallach alternatywnie 'count [temp] = i [foo];' i inne kombinacje :) – Kevin

9
*(temp + count) = *(foo + i); 

Operatory + wykonują arytmetykę wskaźnika. Dodanie liczby całkowitej do wartości wskaźnika powoduje, że nowy wskaźnik inkrementował określoną liczbę obiektów poza oryginalny wskaźnik. Na przykład, jeśli p jest wskaźnikiem do arr[0], wówczas p+2 wskazuje na arr[2].

Wynikający z tego wynikowy wskaźnik, podając obiekt, na który wskazuje.

W rzeczywistości operator indeksowania tablicy [] jest zdefiniowany w kategoriach arytmetyki wskaźników, tak aby A[i] oznacza *(A+i) (ignorowanie przeciążenia operatora). Więc powyższej linii kodu:

*(temp + count) = *(foo + i); 

można także zapisać (jaśniej IMHO) jako:

temp[count] = foo[i]; 

Czasami warto przeczytać comp.lang.c FAQ, zwłaszcza rozdziały 4 (wskaźniki) i 6 (tablice i wskaźniki). Większość informacji dotyczy również języka C++.

Jednak interfejs, C++ zapewnia interfejsy biblioteki wyższego poziomu, które mogą być bardziej niezawodne niż odpowiedniki C niskiego poziomu. W C++ rzadko jest pisanie kodu, który zajmuje się bezpośrednio tablicami i wskaźnikami do elementów tablicy, chyba że jest to kod bardzo niskiego poziomu i wydajność jest krytyczna i/lub masz do czynienia ze strukturami danych z kodu C.

2

W przykładzie

*(temp + count) = *(foo + i); 

jest równoważna

temp[count] = foo[i]; 

Wyrażenie *(temp + count) dodaje całkowitą count do wskaźnika temp, co daje wskaźnik do elementu w pozycji count w tablicy wskazywanej przez temp iit.

0

Być może kluczem linia pytanie brzmi:

Dlaczego są wskaźnikami do nawiasach [...]?

Symbol * w C i C++ jest nieco myląco semantycznie przeciążony. Masz rację, że czasami oznacza "wskaźnik do", jak w int* int_ptr, gdzie * oznacza "int_ptr jest wskaźnikiem do typu na lewo od *".

Ale to również oznacza "dereference a wskaźnik do ...", co właśnie tutaj się dzieje. Wyrażenia (temp + count) i (foo + i) są oceniane na wskaźniki-na-int s, ponieważ dodanie typu int do wartości wskaźnika powoduje, że wartość wskaźnika przesuwa o typ całkowitą (tj. Obliczasz adres pamięci w pewnej odległości od oryginalny wskaźnik). Nawiasy po prostu zapewniają, że operacje dodawania mają miejsce przed zastosowaniem *. Tak więcma wartość z wartością wskaźnika temp + count. Oznacza to, że ocenia on wartość całkowitą przechowywaną pod adresem temp + count.

można wyeliminować niektóre z zamieszania myśląc o pierwszym znaczeniu jako również wskazującego dereference: int* int_ptr jest równoważna int *int_ptr, to znaczy „jeśli dereference int_ptr, będziesz uzyskać int”. Daje to intuicyjne poczucie dlaczego int* int_one, int_two deklaruje int_one jako wskaźnik doint i int_two jako int - nie jako typ wskaźnika.