Czy istnieje sposób na sprawdzenie, ile wartości ma tablica? Sprawdzanie, czy osiągnąłem koniec tablicy, również by działało.
Czy istnieje sposób na sprawdzenie, ile wartości ma tablica? Sprawdzanie, czy osiągnąłem koniec tablicy, również by działało.
Odpowiedzi:
Jeśli masz na myśli tablicę w stylu C, możesz zrobić coś takiego:
int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
To nie działa na wskaźniki (tzn. Nie będzie działać dla żadnego z poniższych):
int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
lub:
void func(int *p)
{
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}
int a[7];
func(a);
W C ++, jeśli chcesz tego rodzaju zachowanie, powinieneś użyć klasy kontenera; Prawdopodobnie std::vector.
Jak powiedzieli inni, możesz użyć, sizeof(arr)/sizeof(*arr)ale da to złą odpowiedź na typy wskaźników, które nie są tablicami.
template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
Ma to dobrą właściwość polegającą na niepowodzeniu kompilacji dla typów innych niż macierz (studio wizualne ma _countoftaką możliwość). To constexprsprawia, że jest to wyrażenie czasu kompilacji, więc nie ma żadnych wad w stosunku do makra (przynajmniej żadnego, o którym wiem).
Możesz również rozważyć użycie std::arrayz C ++ 11, który ujawnia swoją długość bez narzutu na natywną tablicę C.
C ++ 17 ma std::size()w <iterator>nagłówku, który robi to samo i działa również dla kontenerów STL (dzięki @Jon C ).
T(arg&)[N].
extent, patrząc na to teraz są dwie cechy, które sprawiają, że jest mniej przydatny niż funkcja powyżej (w tym przypadku użycia). (1) Zwraca zero dla wskaźników (zamiast błędu kompilacji). (2) Wymaga parametru typu, więc aby sprawdzić zmienną, którą musisz zrobićdecltype
W ten sposób sizeof( myArray )otrzymasz całkowitą liczbę bajtów przydzielonych dla tej tablicy. Następnie możesz dowiedzieć się o liczbie elementów w tablicy, dzieląc przez rozmiar jednego elementu w tablicy:sizeof( myArray[0] )
Chociaż jest to stare pytanie, warto zaktualizować odpowiedź do C ++ 17. W bibliotece standardowej znajduje się teraz funkcja szablonowa std::size(), która zwraca liczbę elementów zarówno w kontenerze standardowym, jak i tablicy typu C. Na przykład:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
Czy istnieje sposób na sprawdzenie, ile wartości ma tablica?
Tak!
Próbować sizeof(array)/sizeof(array[0])
Sprawdzanie, czy osiągnąłem koniec tablicy, również by działało.
Nie widzę w tym żadnego sposobu, chyba że twoja tablica jest tablicą znaków (tzn. Ciągiem znaków).
PS: W C ++ zawsze używaj std::vector. Istnieje kilka wbudowanych funkcji i rozszerzonej funkcjonalności.
std::vector ma metodę size() która zwraca liczbę elementów w wektorze.
(Tak, to odpowiedź na język)
#include <iostream>
int main ()
{
using namespace std;
int arr[] = {2, 7, 1, 111};
auto array_length = end(arr) - begin(arr);
cout << "Length of array: " << array_length << endl;
}
Od wersji C ++ 11 wprowadzono kilka nowych szablonów, które pomagają zmniejszyć ból związany z długością tablicy. Wszystkie są zdefiniowane w nagłówku <type_traits>.
Jeśli Tjest typem tablicy, zapewnia stałą wartość elementu równą liczbie wymiarów tablicy. Dla każdego innego typu wartość wynosi 0.
If Tjest typem tablicy, zapewnia stałą wartość elementu równą liczbie elementów wzdłuż Nth wymiaru tablicy, jeśli Njest w [0, std::rank<T>::value). Dla każdego innego typu lub jeśli Ttablica nieznanych jest związana wzdłuż pierwszego wymiaru i Nwynosi 0, wartość wynosi 0.
Jeśli Tjest tablicą jakiegoś typu X, podaje typ typedef elementu równy X, w przeciwnym razie typ to T. Zauważ, że jeśli Tjest to tablica wielowymiarowa, usuwany jest tylko pierwszy wymiar.
std::remove_all_extents<T>::type
Jeśli Tjest wielowymiarową tablicą jakiegoś typu X, zapewnia typ typef elementu równy X, w przeciwnym razie typ jest T.
Aby uzyskać długość dowolnego wymiaru tablicy wielowymiarowej, decltypemożna go użyć do połączenia std::extent. Na przykład:
#include <iostream>
#include <type_traits> // std::remove_extent std::remove_all_extents std::rank std::extent
template<class T, size_t N>
constexpr size_t length(T(&)[N]) { return N; }
template<class T, size_t N>
constexpr size_t length2(T(&arr)[N]) { return sizeof(arr) / sizeof(*arr); }
int main()
{
int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};
// New way
constexpr auto l1 = std::extent<decltype(a)>::value; // 5
constexpr auto l2 = std::extent<decltype(a), 1>::value; // 4
constexpr auto l3 = std::extent<decltype(a), 2>::value; // 3
constexpr auto l4 = std::extent<decltype(a), 3>::value; // 0
// Mixed way
constexpr auto la = length(a);
//constexpr auto lpa = length(*a); // compile error
//auto lpa = length(*a); // get at runtime
std::remove_extent<decltype(a)>::type pa; // get at compile time
//std::remove_reference<decltype(*a)>::type pa; // same as above
constexpr auto lpa = length(pa);
std::cout << la << ' ' << lpa << '\n';
// Old way
constexpr auto la2 = sizeof(a) / sizeof(*a);
constexpr auto lpa2 = sizeof(*a) / sizeof(**a);
std::cout << la2 << ' ' << lpa2 << '\n';
return 0;
}
BTY, aby uzyskać całkowitą liczbę elementów w tablicy wielowymiarowej:
constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
Lub umieść go w szablonie funkcji:
#include <iostream>
#include <type_traits>
template<class T>
constexpr size_t len(T &a)
{
return sizeof(a) / sizeof(typename std::remove_all_extents<T>::type);
}
int main()
{
int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}};
constexpr auto ttt = len(a);
int i;
std::cout << ttt << ' ' << len(i) << '\n';
return 0;
}
Więcej przykładów ich użycia można znaleźć, klikając linki.
Istnieje również sposób TR1 / C ++ 11 / C ++ 17 (zobacz Live on Coliru):
const std::string s[3] = { "1"s, "2"s, "3"s };
constexpr auto n = std::extent< decltype(s) >::value; // From <type_traits>
constexpr auto n2 = std::extent_v< decltype(s) >; // C++17 shorthand
const auto a = std::array{ "1"s, "2"s, "3"s }; // C++17 class template arg deduction -- http://en.cppreference.com/w/cpp/language/class_template_argument_deduction
constexpr auto size = std::tuple_size_v< decltype(a) >;
std::cout << n << " " << n2 << " " << size << "\n"; // Prints 3 3 3
Zamiast używać wbudowanej funkcji tablicowej aka:
int x[3] = {0, 1, 2};
powinieneś użyć klasy tablicy i szablonu tablicy. Próbować:
#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};
Więc teraz, jeśli chcesz znaleźć długość tablicy, wszystko co musisz zrobić, to użyć funkcji size w klasie tablicy.
Name_of_Array.size();
i to powinno zwrócić długość elementów w tablicy.
W C ++, używając klasy std :: array do zadeklarowania tablicy, można łatwo znaleźć rozmiar tablicy, a także ostatni element.
#include<iostream>
#include<array>
int main()
{
std::array<int,3> arr;
//To find the size of the array
std::cout<<arr.size()<<std::endl;
//Accessing the last element
auto it=arr.end();
std::cout<<arr.back()<<"\t"<<arr[arr.size()-1]<<"\t"<<*(--it);
return 0;
}
W rzeczywistości klasa tablicowa ma wiele innych funkcji, które pozwalają nam używać tablic standardowych kontenerów.
Odniesienia 1 do klasy C ++ std :: array
Odniesienia 2 do klasy std :: array
Przykłady w odnośnikach są pomocne.
To dość stare i legendarne pytanie, a jest już wiele niesamowitych odpowiedzi. Ale z czasem dodano nowe funkcje do języków, dlatego musimy ciągle aktualizować rzeczy zgodnie z dostępnymi nowymi funkcjami.
Właśnie zauważyłem, że nikt jeszcze nie wspomniał o C ++ 20. Więc pomyślałem, aby napisać odpowiedź.
W C ++ 20 do standardowej biblioteki dodano nowy lepszy sposób znajdowania długości tablicy, tj std:ssize(). Ta funkcja zwraca a signed value.
#include <iostream>
int main() {
int arr[] = {1, 2, 3};
std::cout << std::ssize(arr);
return 0;
}
W C ++ 17 istniał lepszy sposób (w tym czasie) na to samo, co jest std::size()zdefiniowane w iterator.
#include <iostream>
#include <iterator> // required for std::size
int main(){
int arr[] = {1, 2, 3};
std::cout << "Size is " << std::size(arr);
return 0;
}
PS Ta metoda działa dla vector .
To tradycyjne podejście jest już wspomniane w wielu innych odpowiedziach.
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
Po prostu FYI, jeśli zastanawiasz się, dlaczego to podejście nie działa, gdy tablica jest przekazywana do innej funkcji . Powodem jest,
Tablica nie jest przekazywana przez wartość w C ++, zamiast tego przekazywany jest wskaźnik do tablicy. Podobnie jak w niektórych przypadkach przekazywanie całych tablic może być kosztowną operacją. Możesz to przetestować, przekazując tablicę do jakiejś funkcji i wprowadzić tam zmiany, a następnie ponownie wydrukować tablicę w main. Otrzymasz zaktualizowane wyniki.
I jak już wiesz, sizeof()funkcja podaje liczbę bajtów, więc w innej funkcji zwróci liczbę bajtów przydzielonych wskaźnikowi, a nie całej tablicy. To podejście nie działa.
Ale jestem pewien, że możesz znaleźć dobry sposób na zrobienie tego, zgodnie z wymaganiami.
Happy Coding.
Dostępnych jest wiele opcji pozwalających uzyskać rozmiar tablicy C.
int myArray [] = {0, 1, 2, 3, 4, 5, 7};
1) sizeof(<array>) / sizeof(<type>):
std::cout << "Size:" << sizeof(myArray) / sizeof(int) << std::endl;
2) sizeof(<array>) / sizeof(*<array>):
std::cout << "Size:" << sizeof(myArray) / sizeof(*myArray) << std::endl;
3) sizeof(<array>) / sizeof(<array>[<element>]):
std::cout << "Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl;
Oto jedna implementacja ArraySizez Google Protobuf .
#define GOOGLE_ARRAYSIZE(a) \
((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
// test codes...
char* ptr[] = { "you", "are", "here" };
int testarr[] = {1, 2, 3, 4};
cout << GOOGLE_ARRAYSIZE(testarr) << endl;
cout << GOOGLE_ARRAYSIZE(ptr) << endl;
ARRAYSIZE (arr) działa poprzez sprawdzenie sizeof (arr) (liczba bajtów w tablicy) i sizeof (* (arr)) (liczba bajtów w jednym elemencie tablicy). Jeśli ten pierwszy jest podzielny przez ten drugi, być może arr jest rzeczywiście tablicą, w którym to przypadku wynikiem podziału jest liczba elementów w tablicy. W przeciwnym razie arr nie może być tablicą i generujemy błąd kompilatora, aby zapobiec kompilacji kodu.
Ponieważ rozmiar bool jest zdefiniowany w implementacji, musimy rzutować! (Sizeof (a) i sizeof (* (a))) na size_t, aby upewnić się, że końcowy wynik ma typ size_t.
To makro nie jest idealne, ponieważ błędnie akceptuje niektóre wskaźniki, a mianowicie tam, gdzie rozmiar wskaźnika jest podzielny przez rozmiar wskaźnika. Ponieważ cały nasz kod musi przejść przez 32-bitowy kompilator, w którym wskaźnik ma 4 bajty, oznacza to, że wszystkie wskaźniki do typu o rozmiarze 3 lub większym niż 4 zostaną (słusznie) odrzucone.
int nombres[5] = { 9, 3 };funkcja zwraca 5zamiast 2.
W przypadku C ++ / CX (podczas pisania np. Aplikacji UWP przy użyciu C ++ w Visual Studio) możemy znaleźć liczbę wartości w tablicy, po prostu używając size()funkcji.
Kod źródłowy:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);
Jeśli wyjście będzie:coutsize_of_array
>>> 4
sizeof(array_name)podaje rozmiar całej tablicy i sizeof(int)podaje rozmiar typu danych każdego elementu tablicy.
Zatem podzielenie rozmiaru całej tablicy przez rozmiar pojedynczego elementu tablicy daje długość tablicy.
int array_name[] = {1, 2, 3, 4, 5, 6};
int length = sizeof(array_name)/sizeof(int);
ODPOWIEDŹ :
int number_of_elements = sizeof(array)/sizeof(array[0])
OBJAŚNIENIE :
Ponieważ kompilator ustawia określoną wielkość fragmentu pamięci dla każdego typu danych, a tablica jest po prostu grupą tych danych, wystarczy podzielić tablicę przez rozmiar typu danych. Jeśli mam tablicę 30 ciągów, mój system odkłada 24 bajty na każdy element (ciąg) tablicy. Przy 30 elementach to łącznie 720 bajtów. 720/24 == 30 elementów. Mały, ścisły algorytm to:
int number_of_elements = sizeof(array)/sizeof(array[0]) co równa się
number_of_elements = 720/24
Pamiętaj, że nie musisz wiedzieć, jaki typ danych ma tablica, nawet jeśli jest to niestandardowy typ danych.
To tylko myśl, ale właśnie postanowiłem utworzyć zmienną licznika i zapisać rozmiar tablicy w pozycji [0]. Usunąłem większość kodu, który miałem w funkcji, ale po wyjściu z pętli zobaczysz, że pierwsza [0] ma przypisaną końcową wartość „a”. Próbowałem użyć wektorów, ale VS Express 2013 nie bardzo to lubił. Zauważ też, że „a” zaczyna się od pierwszego, aby uniknąć zastąpienia [0], i jest inicjalizowane na początku, aby uniknąć błędów. Nie jestem ekspertem, pomyślałem, że się podzielę.
int prime[] = {0};
int primes(int x, int y){
using namespace std; int a = 1;
for (int i = x; i <= y; i++){prime[a] = i; a++; }
prime[0] = a; return 0;
}
Dobre rozwiązanie, które wykorzystuje leki generyczne:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
Następnie po prostu zadzwoń, arraysize(_Array);aby uzyskać długość tablicy.
constexprjest poprawką. inlinenie jest. constexprjest jednak dość nowoczesny. Czy jesteś pewien, że twój program testowy nie używa innej nowoczesnej funkcji, w której możesz zadeklarować tablicę lokalną, której długość jest określona przez zmienną? Wypróbuj z dwiema globalnymi tablicami.
W przypadku starego kompilatora g ++ możesz to zrobić
template <class T, size_t N>
char (&helper(T (&)[N]))[N];
#define arraysize(array) (sizeof(helper(array)))
int main() {
int a[10];
std::cout << arraysize(a) << std::endl;
return 0;
}
Podaję tutaj trudne rozwiązanie:
Zawsze możesz przechowywać lengthw pierwszym elemencie:
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
Koszt jest konieczny --arrprzy wywołaniufree
arrjest typu zgodnego z, inta tablica nie jest dłuższa niż maksymalna wartość tego typu. Np. Łańcuchy Pascal są w rzeczywistości tablicami bajtowymi używającymi tej sztuczki; maksymalna długość ciągów znaków w Pascal wynosi 255 znaków.
długość tablicy można znaleźć, wykonując następujące czynności:
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
Możesz po prostu użyć tego fragmentu:
#include <iostream>
#include <string>
#include <array>
using namespace std;
int main()
{
array<int,3> values;
cout << "No. elements in valuea array: " << values.size() << " elements." << endl;
cout << "sizeof(myints): " << sizeof(values) << endl;
}
a tutaj jest odniesienie: http://www.cplusplus.com/reference/array/array/size/
Unikaj używania tego typu wraz z sizeof, as sizeof(array)/sizeof(char) nagle ulegnie uszkodzeniu, jeśli zmienisz typ tablicy.
W studiu wizualnym masz równoważne, jeśli sizeof(array)/sizeof(*array). Możesz po prostu pisać_countof(array)
Osobiście sugerowałbym (jeśli z jakiegokolwiek powodu nie jesteś w stanie pracować ze specjalistycznymi funkcjami), aby najpierw rozszerzyć kompatybilność typu tablic poza to, co normalnie byś go używał (gdybyś przechowywał wartości ≥ 0:
unsigned int x[] -> int x[]
niż uczyniłbyś element tablicy 1 większym, niż potrzebujesz. Dla ostatniego elementu umieściłbyś jakiś typ, który jest zawarty w specyfikatorze typu rozwiniętego, ale którego normalnie nie użyłbyś, np. Używając poprzedniego przykładu, ostatnim elementem byłby -1. Umożliwia to (za pomocą pętli for) znalezienie ostatniego elementu tablicy.
Jednym z najczęstszych powodów, dla których byś tego szukał, jest to, że chcesz przekazać tablicę do funkcji i nie musisz przekazywać kolejnego argumentu dotyczącego jej wielkości. Zasadniczo chciałbyś również, aby rozmiar tablicy był dynamiczny. Ta tablica może zawierać obiekty, a nie prymitywy, a obiekty mogą być tak złożone, że size_of () nie jest bezpieczną opcją do obliczania liczby.
Jak sugerują inni, rozważ użycie std :: vector lub list, itp. Zamiast prymitywnej tablicy. Jednak w starych kompilatorach nadal nie miałbyś ostatecznego rozwiązania, które prawdopodobnie chciałbyś zrobić, po prostu robiąc to, ponieważ wypełnienie kontenera wymaga kilku brzydkich linii push_back (). Jeśli jesteś podobny do mnie, potrzebujesz rozwiązania jednoliniowego z anonimowymi obiektami.
Jeśli korzystasz z kontenera STL alternatywnego do prymitywnej tablicy, ten post SO może być dla Ciebie przydatny do sposobów jego inicjalizacji: Jaki jest najłatwiejszy sposób na zainicjowanie standardowego wektora na elementy na stałe?
Oto metoda, której używam do tego, która będzie działać uniwersalnie na kompilatorach i platformach:
Utwórz struct lub klasę jako kontener dla swojej kolekcji obiektów. Zdefiniuj funkcję przeciążenia operatora dla <<.
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
Możesz tworzyć funkcje, które przyjmują strukturę jako parametr, np .:
someFunc( MyObjectList &objects );
Następnie możesz wywołać tę funkcję w następujący sposób:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
W ten sposób możesz budować i przekazywać dynamicznie wielkościowy zbiór obiektów do funkcji w jednym czystym wierszu!
Powiedzmy, że masz globalną tablicę zadeklarowaną na górze strony
int global[] = { 1, 2, 3, 4 };
Aby dowiedzieć się, ile elementów jest (w c ++) w tablicy, wpisz następujący kod:
sizeof(global) / 4;
Sizeof (NAME_OF_ARRAY) / 4 da ci liczbę elementów dla podanej nazwy tablicy.