Przekazywanie tablic jako odniesienia
W C ++, jak mogę przejść
tablica jako odniesienie
jeśli nie znam jego rozmiaru w czasie kompilacji? Jak dotąd doszedłem do wniosku, że jedynym sposobem, aby to zadziałało, jest użycie czegoś takiego
const double( &numbers ) [size]
ale to oznacza, że potrzebuję
znać rozmiar tablicy w czasie kompilacji
więc nie mogę go używać w funkcji zewnętrznej.
Moje pytania to:
- Jeśli nie przekażę tablicy jako
(const double (& amp; numbers) [length])
bo na przykład nie znam jej rozmiaru, jak mogę się upewnić, że nie zostanie skopiowany ale na nim odnosić się - Jeśli przekażę tablicę jak w powyższym przykładzie
(double array [])
odnosi się do niego lub skopiowane
Nie znaleziono powiązanych wyników
Zaproszony:
Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się
6 odpowiedzi
Anonimowy użytkownik
Potwierdzenie od:
Anonimowy użytkownik
Potwierdzenie od:
std::vector
http://en.cppreference.com/w/cpp/container/vector
.
W C/C ++ nie można przekazywać tablic jako kopii. Tablice są zawsze przekazywane przez odwołanie.
EDIT
W C ++
tablice przekazywane przez odwołanie
mają inne znaczenie. Zarówno w C, jak i C ++, tablice rozpadają się na wskaźnik do pierwszego elementu tablicy. Sprawdź poniższe komentarze.
Anonimowy użytkownik
Potwierdzenie od:
W każdym razie prawdopodobnie zechcesz zamiast tego rozważyć użycie .
EDYCJA: patrz komentarze.
Anonimowy użytkownik
Potwierdzenie od:
stały wskaźnik
do pierwszego elementu. Stały
wskaźnik
oznacza wskaźnik, który jest w stanie zmienić wszystko, na co wskazuje, ale nie można go zmienić, aby wskazywał na coś innego.
Oznacza to, że zawsze, gdy transmitujesz
szyk
, faktycznie mijasz
stały wskaźnik
do tej tablicy. Innymi słowy, już przekazujesz go przez odniesienie, bez dodatkowego wysiłku. Mówiąc dokładniej, w rzeczywistości
skopiowane
ten
stały wskaźnik
więc ostatnie (miejmy nadzieję, że niezbyt mylące) sformułowanie brzmi: zdałeś
stały wskaźnik
na tablicę
według wartości
.
Jeśli nie znasz rozmiaru swojej tablicy w czasie kompilacji, po prostu użyj (zwykłego) wskaźnika do swojego typu danych zamiast jawnej tablicy. Więc cokolwiek
T my_array []
(gdzie to typ, na przykład , lub nawet jeden z Twoje klasy) zmieni się na , a składnia jest dokładnie taka sama ...my_array [i]
będzie działać dobrze (jest inna składnia, ale nie tak elegancka ). Użyj operatora , aby zainicjować:T* my_array;my_array = new T[3];
lub
T* my_array;my_array = new T[x];
gdzie jest liczbą całkowitą (niekoniecznie stałą, jak w przypadku zwykłych tablic). Możesz więc pobrać to od użytkownika w czasie wykonywania, a następnie utworzyć swoją „tablicę”. Po prostu uważaj, aby nie zapomnieć o
usunięciu [] my_array
po zakończeniu jej używania, aby uniknąć wycieku pamięci.[Ostatnia uwaga] wykorzystanie takich
przydzielane dynamicznie
tablica jest dobrym wyborem tylko wtedy, gdy wiesz dokładnie, ile elementów potrzebujesz ... w czasie kompilacji lub nawet w czasie wykonywania. Na przykład, jeśli użytkownik poda swoje na pewno ich użyjesz, to w porządku. W przeciwnym razie grozi Ci przepełnienie tablicy (jeśli potrzebujesz więcej niż ) - co zwykle powoduje awarię aplikacji - lub po prostu marnowanie miejsca. Mimo to sam zaimplementujesz większość funkcji potrzebnych do manipulowania tablicami. Dlatego lepiej jest używać kontenerów udostępnianych przez standardową bibliotekę C ++, takich jak (jak wspomniał Donotalo). Chciałem tylko rozwinąć tę kwestię.
Anonimowy użytkownik
Potwierdzenie od:
bo np. nie znam jego rozmiaru, skąd mam mieć pewność, że to
nie skopiowane, ale przywoływane?
Tak, to znaczy, że przekazujesz tablicę jako odniesienie,
void Foo(const double( &numbers ) [length]);
Zwróć uwagę, że jest stałą liczbą całkowitą.
Jeśli przekażę do niej tablicę jak w powyższym przykładzie (double array [])
czy są połączone czy skopiowane?
Nie, nie jest kopiowane. Oznacza to, że przekazujesz wskaźnik do swojej tablicy, który jest równoważny,
Anonimowy użytkownik
Potwierdzenie od:
Zawsze, gdy w kodzie masz tablicę o stałym rozmiarze, kompilator zna rozmiar tablicy, ponieważ odczytuje ją z samego kodu źródłowego. Ale gdy tylko kod zostanie skompilowany, informacja o długości zostanie utracona. Na przykład:
void f1(double array[10]) {...}
Kompilator nie wymusi rozmiaru tablicy. Poniższy kod zostanie automatycznie skompilowany, ponieważ parametr tablicy jest tylko wskaźnikiem do pierwszego elementu tablicy:
Ponieważ kompilator ignoruje statyczny rozmiar tablicy podczas przekazywania jej do funkcji, jedynym sposobem na poznanie rozmiaru tablicy o dowolnym rozmiarze przekazanej jako odniesienie jest jawne określenie jej rozmiaru:
void f2(double array[], size_t array_size) {...}
Następnie możesz wywołać tę funkcję z dowolną tablicą:
Parametr zawiera rzeczywisty rozmiar tablicy.
Na marginesie, działa tylko z tablicami zdefiniowanymi statycznie. Przekazanie tej tablicy do innych funkcji powoduje utratę informacji o rozmiarze.
Tablica to nie to samo, co wskaźnik. Jednak nieokreślona tablica, taka jak parametr , jest po prostu wskaźnikiem do pierwszego elementu w sekwencji:
Z praktycznego punktu widzenia i są równoważne.
Tak działa . Wewnętrznie wektor jest klasą z dwoma polami: wskaźnikiem do pierwszego elementu i liczbą elementów w wektorze. Ułatwia to trochę sprawę, gdy chcesz zaakceptować tablicę o dowolnym rozmiarze jako parametr: