Jak znaleźć długość tablicy?

539

Czy istnieje sposób na sprawdzenie, ile wartości ma tablica? Sprawdzanie, czy osiągnąłem koniec tablicy, również by działało.

Maks
źródło
22
Skąd pochodzi tablica? Zwykle funkcje zajmujące tablice również biorą parametr długości, aby poradzić sobie z tym problemem.
Michael Myers
2
Cóż, tworzę program „szalonych bibliotek”, który ma tablicę z całym tekstem, a także lokalizacje rzeczowników / czasowników, które użytkownik musi wypełnić. Chciałbym użyć funkcji do uruchomienia przez cała tablica, zastępując wartości „[rzeczownik]” i „[czasownik]” tekstem wprowadzonym przez użytkownika.
Maxpm
możliwy duplikat Obliczeniowej długości macierzy
Maks.
5
Należy pamiętać, że w C tablice nie są obiektami ani strukturami. Jako takie nie mają domyślnie zapisanego parametru długości. Jeśli chcesz pracować z nimi jako obiektami w C ++, użyj obiektów C ++ std :: vector lub std :: tablica C ++ 11, jeśli możesz. Jeśli musisz użyć wskaźników, zawsze przekaż długość tablicy jako drugi parametr do każdej funkcji, która z nią działa.
Pihhan
Jeśli używasz C ++ 20, to również dodałem odpowiedź na to pytanie. Można go łatwo przeoczyć, ponieważ jest tutaj tak wiele odpowiedzi.
gprathour

Odpowiedzi:

511

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.

Oliver Charlesworth
źródło
86
Nie działa również, jeśli przekażesz tablicę innej funkcji i spróbujesz to zrobić :)
San Jacinto,
23
@San Jacinto: Nie, to działa (na tablicach ) bez względu na to, w jakiej funkcji się znajdujesz. Przekazywanie tablicy o zmiennej długości do funkcji jako parametru jest jednak niemożliwe (rozkłada się na wskaźnik) - ale jeśli podasz tablicę wewnątrz struktury, to działa zgodnie z oczekiwaniami.
eq-
1
@OliverCharlesworth również, jeśli przekazałeś tablicę wartości do innej funkcji i wypróbowałeś ją tam, nie zadziała, prawda? Pytanie brzmi, dlaczego
A_Matar
5
@A_Matar - Nie można przekazać tablicy według wartości w C lub C ++.
Oliver Charlesworth,
1
@yusha - są tym samym.
Oliver Charlesworth,
142

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 ).

Motti
źródło
3
@ yau to jak piszesz odwołanie do tablicy , zobacz tę odpowiedź . Moja wersja wygląda nieco inaczej, ponieważ pominąłem nazwę parametru, ponieważ parametr nie jest używany, potrzebny jest tylko jego typ. Miałoby to nazwę T(arg&)[N].
Motti
1
Dzięki Motti! Nazwa pominiętego parametru była już dla mnie jasna. Ale niewiarygodne, że najwyraźniej nigdy wcześniej nie użyłem referencji / wskaźników do tablic . I prawdopodobnie nie będzie w przyszłości, ponieważ takie tablice wymierają jeszcze bardziej.
yau
1
Jeśli użycie C ++ 11 nie jest std :: scope lepszym rozwiązaniem ???? en.cppreference.com/w/cpp/types/extent
Isaac Pascual
2
@IsaacPascual Nie byłem zaznajomiony 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
Motti,
86

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] )

MahlerFive
źródło
3
Jest to bardzo proste i łatwe rozwiązanie w celu przezwyciężenia problemu, który wydaje się być odwieczny.
4
Nie działa dla „nowych” tablic C ++ utrzymywanych przez wskaźnik. Otrzymasz rozmiar wskaźnika (4 bajty) lub rozmiar jego pierwszego elementu, jeśli go odrzucisz.
DragonLord,
1
@DragonLord tak, chociaż każdy, kto deklaruje rozmiar tablicy za pomocą słowa kluczowego new, już zna rozmiar tablicy w czasie wykonywania, więc nie ma potrzeby używania operatora sizeof w celu znalezienia rozmiaru tablicy w takim przypadku. Jestem pewien, że o tym wiesz. Jest to z korzyścią dla każdego, kto tego nie robi.
Martyn Shutt
@surega To się nie zawiesi
CITBL
60

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
Jon C.
źródło
58

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.

Prasoon Saurav
źródło
Nie działałoby to dla różnych rozmiarów tablic indywidualnych
Don Larynx,
4
+1 dla wektorów. Niewiele jest mocnych przypadków, aby używać starych tablic C ++. Chyba że rozmiar tablicy nigdy się nie zmieni, ale nawet wtedy powinieneś użyć klasy kontenera tablic. Lepiej jest użyć klasy kontenera, takiej jak wektor, do dynamicznego przechowywania macierzy. Zalety korzystania z klas kontenerów znacznie przewyższają wady związane z zarządzaniem własną pamięcią.
Martyn Shutt
@MartynShutt Kiedy jesteś związany pamięcią podręczną, tak jak w gamedev, nie możesz sobie pozwolić na użycie wektora.
Tara
30

std::vector ma metodę size() która zwraca liczbę elementów w wektorze.

(Tak, to odpowiedź na język)

eq-
źródło
10
Język może być w policzek, ale prawie na pewno jest to właściwe podejście.
Jerry Coffin,
dlaczego mówisz, że to język w policzek? dla mnie (początkującego c ++) wydaje się, że to właściwa odpowiedź.
dbliss
6
@dbliss Mówi to z przymrużeniem oka, ponieważ OP zapytał o długość tablicy i eq- mówi im, jak uzyskać długość wektora , co jest inną rzeczą w C ++. Jest to jednak poprawne na głębszym poziomie, ponieważ jeśli potrzebujesz uzyskać długość w czasie wykonywania, wektor jest znacznie lepszym wyborem .
poolie
Możesz także użyć std :: list lub innych kontenerów, które uważam.
BuvinJ
1
Co jest szczególnie świetne w tej odpowiedzi, to to, że możesz zainicjować wektor lub listę za pomocą literału tablicowego.
BuvinJ
26
#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;
}
JukkaP
źródło
10
Uważam, że ten działa tylko dla zmiennych lokalnych, które są na stosie.
DragonLord,
To najlepsza odpowiedź. @DragonLord, działa również dla vars członków. Zobacz cpp.sh/92xvv .
Shital Shah
24

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>.

  • std::rank<T>::value

    Jeśli Tjest typem tablicy, zapewnia stałą wartość elementu równą liczbie wymiarów tablicy. Dla każdego innego typu wartość wynosi 0.

  • std::extent<T, N>::value

    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.

  • std::remove_extent<T>::type

    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.

Jaege
źródło
18

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
metal
źródło
9

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.

Mr. Foots
źródło
6

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.

Tarun Maganti
źródło
2
Miły; Widzę, że masz wiele umiejętności; i ... świetne podejście. Myślę, że sam też powinienem napisać więcej odpowiedzi na tak znane pytania ;-)
GhostCat
5

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ź.

C ++ 20

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;
}

C ++ 17

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 .

Stary

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.

gprathour
źródło
4

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;
Ja do
źródło
3

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.

zangw
źródło
z tablicą liczb całkowitych takich jak poniżej: int nombres[5] = { 9, 3 };funkcja zwraca 5zamiast 2.
Anwar
GOOGLE_ARRAYSIZE(new int8_t)zwraca 8mój test env, zamiast zgłaszania błędu. Część odlewana wydaje się zbędna, nie wspominając o krzyku makra C. sizeof(a) / sizeof(*a)działa wystarczająco jako starsze rozwiązanie.
3

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
Arslan Ahmad
źródło
3

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);
David Gladson
źródło
Ten fragment kodu może rozwiązać problem, ale nie wyjaśnia, dlaczego ani w jaki sposób odpowiada na pytanie. Dołącz wyjaśnienie swojego kodu, ponieważ to naprawdę pomaga poprawić jakość Twojego postu. Pamiętaj, że odpowiadasz na pytanie dla czytelników w przyszłości, a ci ludzie mogą nie znać powodów Twojej sugestii kodu
Balagurunathan Marimuthu
3

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.

Bob Warner
źródło
Nie potrzeba do tego przestarzały i podatny na błędy podejścia w 2019 stackoverflow.com/a/59109106/560648 Również to tylko dupe istniejących odpowiedzi.
Wyścigi lekkości na orbicie
Jest jednak prosty, elokwentny, szybki, mało wymagający, niezależny od platformy i eliminuje potrzebę dołączania wektora lub wskaźników. Jeśli chodzi o kopiowanie innych odpowiedzi, wydaje się, że istnieje tylko jedna inna odpowiedź z tym samym algorytmem, i ta nie daje żadnego wyjaśnienia co do podstawowej mechaniki problemu, jak moja odpowiedź. Z szacunkiem sugeruję, że zamiast podatności na błędy, jest dość solidny.
Bob Warner
1

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;
}
Das_Newb
źródło
1

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.

Źródło

Menelaos Kotsollaris
źródło
@bobbogo Działa z inline lub constexpr, może masz wbudowane off lub jest opcjonalne? ideone.com/VxogJ4
QuentinUK
@QentinUK 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.
bobbogo,
1

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;
}
Scy
źródło
To jest poprawna odpowiedź. Bardzo przenośny wśród wersji C ++, nie działa ze wskaźnikami, a odpowiedź jest dostępna w czasie kompilacji
bobbogo
1

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

陳 力
źródło
2
Działa to tylko wtedy, gdy 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.
Palec
Podejrzewam, że można zarezerwować powiedzmy 8 bajtów na początku każdej tablicy i użyć długiego znaku bez znaku, jeśli chcemy przechowywać obiekty. Myślę, że wektor jest prawdopodobnie łatwiejszy. Ale zdecydowanie dobre rozwiązanie dla systemów wbudowanych.
aj.toulan
1

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;
Rezoanul Alam Riad
źródło
Upraszcza do (& arr) [1] - arr;
QuentinUK
1

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/

Amado Saladino
źródło
0

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)

Johan Jönsson
źródło
0

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.

Raymond Iacobacci
źródło
0

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!

BuvinJ
źródło
-4

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.

miksiii
źródło
8
sizeof (int) zależy od platformy. Nie ma gwarancji, że będzie to 4 (choć jest to najczęstszy przypadek)
zwycięzca
Dziękuję za dodanie.
miksiii
Magiczne liczby !!
Wyścigi lekkości na orbicie