Bir dizinin uzunluğunu nasıl bulabilirim?


539

Bir dizinin kaç değerine sahip olduğunu bulmanın bir yolu var mı? Bir dizinin sonuna ulaşıp ulaşmadığımı saptamak da işe yarar.


22
Dizi nereden geliyor? Genellikle dizileri alan işlevler de bu sorunla başa çıkmak için bir length parametresi alır.
Michael Myers

2
Peki, tüm metni içeren bir dizi ve bir kullanıcının doldurmak zorunda isimler / fiil yerleri olan bir "deli libs" programı yapıyorum. Ben üzerinden çalıştırmak için bir işlev kullanmak istiyorum "[isim]" ve "[fiil]" değerlerini kullanıcı tarafından girilen metinle değiştirerek.
Maxpm


5
C dizilerinde nesne veya yapı olmadığını lütfen unutmayın. Bu nedenle, varsayılan olarak hiçbir yerde saklanan uzunluk parametresi yoktur. Onlarla C ++ 'da nesne olarak çalışmak isterseniz, C ++ nesnelerini std :: vector veya mümkünse std :: dizi C ++ 11 kullanın. İşaretçiler kullanmanız gerekiyorsa, dizinin uzunluğunu her zaman onunla çalışan her işleve ikinci parametre olarak iletin.
13'te Pihhan

C ++ 20 kullanıyorsanız, bunun için de cevap ekledim. Burada çok fazla cevap olduğu için kolayca gözden kaçabilir.
gprathour

Yanıtlar:


511

C tarzı bir diziyi kastediyorsanız, şöyle bir şey yapabilirsiniz:

int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;

Bu işaretçiler üzerinde çalışmaya değil (yani o olmaz Aşağıdakilerden biri için iş):

int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;

veya:

void func(int *p)
{
    std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}

int a[7];
func(a);

C ++ 'da, bu tür bir davranış istiyorsanız, bir kapsayıcı sınıfı kullanıyor olmalısınız; muhtemelen std::vector.


86
Diziyi farklı bir işleve geçirirseniz ve orada yapmaya çalışırsanız da işe yaramaz :)
San Jacinto

23
@San Jacinto: Hayır, hangi fonksiyonda olursanız olun ( dizilerde ) çalışır . Değişken uzunlukta bir diziyi bir fonksiyona parametre olarak geçirmek imkansızdır (bir işaretçiye bozulur) - ancak dizinin içinde bir yapı varsa, bu beklendiği gibi çalışır.
eq-

1
@OliverCharlesworth ayrıca diziyi değere göre başka bir işleve geçip orada denediyseniz, çalışmaz, değil mi? Soru neden
A_Matar

5
@A_Matar - Bir diziyi C veya C ++ ile değere geçiremezsiniz.
Oliver Charlesworth

1
@yusha - onlar aynı şey.
Oliver Charlesworth

142

Diğerlerinin söylediği gibi, kullanabilirsiniz, sizeof(arr)/sizeof(*arr)ancak bu diziler olmayan işaretçi türleri için yanlış cevap verecektir.

template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }

Bu dizi olmayan türler için derleme başarısız güzel özelliği vardır (görsel stüdyo bunu _countofyapar). Bunu constexprderleme zamanı ifadesi yapar, böylece makro üzerinde herhangi bir dezavantajı yoktur (en azından hiçbirini bilmiyorum).

Ayrıca kullanarak düşünebiliriz std::arraybir doğal C dizisi üzerinde hiçbir ek yük ile uzunluğunu ortaya 11 C ++ dan.

C ++ 17 sahip std::size()olarak <iterator>aynı işi yapar ve çok STL taşıyıcı (sayesinde çalışır başlığının @Jon C ).


3
@yau Eğer bir yazma nasıl bir diziye atıfta , bu cevaba bakınız . Parametre kullanılmadığından parametrenin adını dışarıda bıraktığım için sürümüm biraz farklı görünüyor, sadece türü gerekiyor. Bir adla olurdu T(arg&)[N].
Motti

1
Teşekkürler Motti! Dışarıda bırakılan parametre adı benim için zaten belliydi. Ama görünüşe göre daha önce diziler için hiçbir refs / işaretçi kullanmamıştım . Ve muhtemelen gelecekte olmayacak, çünkü bu tür diziler daha da ölüyor.
yau


1
C ++ 11 kullanımı std :: kapsamı değilse daha iyi bir çözüm ???? en.cppreference.com/w/cpp/types/extent
Isaac Pascual

2
@IsaacPascual Ben aşina değildim, extentşimdi ona bakmak için yukarıdaki fonksiyondan daha az kullanışlı olan iki özellik var (bu kullanım için). (1) İşaretçiler için sıfır döndürür (bir derleme hatası yerine). (2) Bir tür parametresi gerektirir, bu yüzden bir değişkeni kontrol etmek için yapmanız gerekirdecltype
Motti

86

Bunu sizeof( myArray )yaptığınızda, o dizi için ayrılan toplam bayt sayısı elde edilir. Daha sonra dizideki bir öğenin boyutuna bölerek dizideki öğelerin sayısını öğrenebilirsiniz:sizeof( myArray[0] )


3
Bu, asırlık bir problemin üstesinden gelmek için çok basit ve kolay bir çözümdür.

4
Bir işaretçi tarafından tutulan C ++ "yeni" diziler için çalışmaz. Gerekirse işaretçinin boyutunu (4 bayt) veya ilk öğesinin boyutunu alırsınız.
DragonLord

1
@DragonLord evet, yeni anahtar kelimeyi kullanarak dizinin boyutunu bildiren herkes çalışma zamanında dizinin boyutunu zaten bilecek olsa da, bu durumda dizinin boyutunu bulmak için sizeof operatörünü kullanmaya gerek yoktur. Bunu bildiğine eminim. Bu sadece yapmayan herkesin yararınadır.
Martyn Shutt

@surega Düşmeyecek
CITBL

60

Bu eski bir soru olsa da, cevabı C ++ 17'ye güncellemeye değer. Standart kitaplıkta artık std::size()hem std kapsayıcıdaki hem de C stili dizideki öğelerin sayısını döndüren geçici işlev var . Örneğin:

#include <iterator>

uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4

58

Bir dizinin kaç değerine sahip olduğunu bulmanın bir yolu var mı?

Evet!

Deneyin sizeof(array)/sizeof(array[0])

Bir dizinin sonuna ulaşıp ulaşmadığımı saptamak da işe yarar.

Diziniz bir dizi karakter (yani dize) olmadığı sürece bunun için herhangi bir yol görmüyorum.

PS: C ++ her zaman kullanın std::vector. Birkaç dahili işlev ve genişletilmiş işlevsellik vardır.


Bu, değişken bireysel dizi boyutları için işe yaramaz
Don Larynx

4
Vektörler için +1. Eski stil C ++ dizilerini kullanmak için çok az güçlü durum var. Dizinin boyutu hiçbir zaman değişmezse, ancak o zaman bile, bunun yerine dizi kapsayıcı sınıfını kullanmalısınız. Dinamik dizi depolama için vektör gibi bir kap sınıfı kullanmak daha iyidir. Konteyner sınıflarını kullanmanın artıları, kendi hafızanızı yönetmek zorunda kalmanın eksilerini aşar.
Martyn Shutt

@MartynShutt Gamedev'de olduğu gibi önbelleğe bağlı olduğunuzda, bazen bir vektör kullanmayı göze alamazsınız.
Tara

30

std::vectorsize()vektördeki eleman sayısını döndüren bir metoda sahiptir.

(Evet, bu yanak dilidir)


10
Dil yanakta olabilir, ama neredeyse kesinlikle doğru yaklaşım.
Jerry Coffin

neden yanağındaki dil diyorsun? bana (c ++ acemi) doğru cevap gibi görünüyor.
dbliss

6
@dbliss Yanaktaki dil, çünkü OP bir dizinin uzunluğunu sordu ve onlara C ++ 'da farklı bir şey olan bir vektörün uzunluğunu nasıl elde edeceklerini anlatıyor . Bununla birlikte, daha derin bir seviyede doğrudur, çünkü çalışma zamanında uzunluğu almanız gerekiyorsa, bir vektör çok daha iyi bir seçimdir .
poolie

Ayrıca std :: list veya inandığım diğer bazı kapları da kullanabilirsiniz.
BuvinJ

1
Bu cevapta özellikle harika olan şey, bir vektörü veya listeyi dizi değişmeziyle başlatabilmenizdir.
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;
}

10
Bence bu sadece yığın üzerindeki yerel değişkenler için çalışıyor.
DragonLord

Bu en iyi cevap. @DragonLord, üye vars için de çalışır. Bkz. Cpp.sh/92xvv .
Shital Shah

24

C ++ 11'den beri, dizi uzunluğu ile uğraşırken ağrıyı azaltmaya yardımcı olmak için bazı yeni şablonlar sunulmaktadır. Hepsi başlıkta tanımlanmıştır <type_traits>.

  • std::rank<T>::value

    Bir Tdizi türüyse, üye sabit değerini dizinin boyut sayısına eşit olarak sağlar. Diğer herhangi bir tür için değer 0'dır.

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

    Bir Tdizi Ntürüyse, N[0, std::rank<T>::value) içindeyse, dizinin th boyutu boyunca öğe sayısına eşit üye sabit değerini sağlar . Diğer herhangi bir tür için veya Tilk boyutu boyunca bilinmeyen bir dizi varsa ve N0 ise, değer 0'dır.

  • std::remove_extent<T>::type

    Eğer Tbazı tip bir dizidir X, eşit için yazın Typedef elemanı içerir X, aksi türüdür T. Eğer Not Tçok boyutlu bir dizisi, sadece ilk boyut kaldırılır.

  • std::remove_all_extents<T>::type

    Bir Ttürden çok boyutlu bir dizi ise X, üye typedef türüne eşit X, aksi halde type is sağlar T.

Çok boyutlu bir dizinin herhangi bir boyutunda uzunluk elde etmek için, decltypebirleştirmek için kullanılabilir std::extent. Örneğin:

#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, çok boyutlu bir dizideki toplam öğe sayısını elde etmek için:

constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);

Veya bir işlev şablonuna yerleştirin:

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

Bunların nasıl kullanılacağına dair daha fazla örnek, bağlantıları takip ederek bulunabilir.


18

Ayrıca TR1 / C ++ 11 / C ++ 17 yolu var (bakın 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

9

Yerleşik dizi işlevini aka kullanmak yerine:

 int x[3] = {0, 1, 2};

dizi sınıfını ve dizi şablonunu kullanmalısınız. Deneyin:

#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};

Şimdi dizinin uzunluğunu bulmak istiyorsanız, tek yapmanız gereken dizi sınıfındaki size işlevini kullanmaktır.

Name_of_Array.size();

ve bu, dizideki öğelerin uzunluğunu döndürmelidir.


6

C ++ 'da, bir diziyi bildirmek için std :: array sınıfını kullanarak, bir dizinin boyutunu ve son öğeyi kolayca bulabilirsiniz.

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

Aslında, dizi sınıfının dizi standart bir kap kullanmamıza izin veren birçok başka işlevi vardır.
Referans 1 - C ++ std :: dizi sınıfı
Referans 2 - std :: dizi sınıfı Referanslardaki
örnekler yardımcı olur.


2
Güzel; Görüyorum ki birçok yeteneğin var; ve ... harika bir yaklaşım. Bence bu ünlü sorulara kendim için daha fazla cevap
yazmalıyım

5

Bu oldukça eski ve efsanevi bir soru ve orada zaten birçok şaşırtıcı cevap var. Ancak zamanla dillere yeni işlevler ekleniyor, bu yüzden mevcut yeni özelliklere göre bir şeyler güncellemeye devam etmeliyiz.

Daha önce hiç kimsenin C ++ 20 hakkında bahsetmediğini fark ettim. Bu yüzden cevap yazmayı düşündüm.

C ++ 20

C ++ 20'de, dizinin uzunluğunu bulmak için standart kitaplığa eklenen yeni bir daha iyi yol vardır std:ssize(). Bu işlev a döndürür signed value.

#include <iostream>

int main() {
    int arr[] = {1, 2, 3};
    std::cout << std::ssize(arr);
    return 0;
}

C ++ 17

C ++ 17'de std::size()tanımlandığı gibi daha iyi bir yol vardı (o zaman) 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 Bu yöntem vector .

Eski

Bu geleneksel yaklaşım, diğer birçok cevapta zaten belirtilmiştir.

#include <iostream>

int main() {
    int array[] = { 1, 2, 3 };
    std::cout << sizeof(array) / sizeof(array[0]);
    return 0;
}

Dizi başka bir işleve geçtiğinde neden bu yaklaşımın işe yaramadığını merak ediyorsanız, sadece FYI . Sebebi,

C ++ 'da bir dizi değere göre geçirilmez, bunun yerine diziye işaretçi iletilir. Bazı durumlarda olduğu gibi tüm dizileri geçmek pahalı bir işlem olabilir. Bunu diziyi bir işleve geçirerek test edebilir ve orada dizide bazı değişiklikler yapabilir ve ardından diziyi tekrar ana olarak yazdırabilirsiniz. Güncellenmiş sonuçlar alırsınız.

Ve zaten bildiğiniz gibi, sizeof() fonksiyon bayt sayısını verir, bu nedenle diğer fonksiyonda tüm dizi yerine işaretçi için ayrılan bayt sayısını döndürür. Yani bu yaklaşım işe yaramıyor.

Ama eminim bunu yapmak için iyi bir yol bulabilirsiniz, sizin ihtiyacına göre.

Mutlu Kodlama.


4

Bir C dizisi boyutu elde etmek için kullanılacak birçok seçeneğiniz var.

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;

3

İşte biri uygulamasıdır ArraySizegelen 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), sizeof (arr) (dizideki bayt sayısı) ve sizeof (* (arr)) (bir dizi öğesindeki bayt sayısı) incelenerek çalışır. Birincisi ikincisi tarafından bölünebiliyorsa, belki de arr gerçekten bir dizidir, bu durumda bölme sonucu dizideki öğelerin # sayısıdır. Aksi takdirde, arr muhtemelen bir dizi olamaz ve kodun derlenmesini önlemek için bir derleyici hatası oluştururuz.

Bool boyutu uygulama tarafından tanımlandığından, nihai sonucun size_t türüne sahip olduğundan emin olmak için! (Sizeof (a) & sizeof (* (a))) size_t öğesine dökmeliyiz.

Bu makro, belirli işaretçileri yanlış bir şekilde kabul ettiği için mükemmel değildir, yani işaretçi boyutunun nokta boyutu ile bölünebileceği yerler. Tüm kodumuz, bir işaretçinin 4 bayt olduğu bir 32 bit derleyiciden geçmesi gerektiğinden, boyutu 3 veya 4'ten büyük olan bir türe yönelik tüm işaretçiler (haklı olarak) reddedileceği anlamına gelir.


aşağıdaki gibi bir tamsayı dizisi ile: int nombres[5] = { 9, 3 };bu işlev 5yerine döner 2.
Anwar

GOOGLE_ARRAYSIZE(new int8_t)8hatayı artırmak yerine benim test env geri döner . Dökülen kısım çığlık C makrosundan bahsetmeden gereksiz görünüyor. sizeof(a) / sizeof(*a)eski çözüm olarak yeterince çalışır.

3

C ++ / CX için (örn. Visual Studio'da C ++ kullanarak UWP uygulamaları yazarken), bir dizideki değerlerin sayısını yalnızca size()işlevi kullanarak bulabiliriz .

Kaynak kodu:

string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);

Eğer çıkış olacaktır:coutsize_of_array

>>> 4

3

sizeof(array_name)tüm dizinin sizeof(int)boyutunu verir ve her dizi öğesinin veri türünün boyutunu verir.

Böylece, tüm dizinin boyutunu dizinin tek bir öğesinin boyutuna bölmek dizinin uzunluğunu verir .

 int array_name[] = {1, 2, 3, 4, 5, 6};
 int length = sizeof(array_name)/sizeof(int);

Bu kod snippet'i sorunu çözebilir, ancak soruyu neden veya nasıl yanıtladığını açıklamaz. Lütfen gönderinizin kalitesini artırmaya gerçekten yardımcı olduğu için kodunuz için bir açıklama ekleyin. Gelecekte okuyucular için soruyu cevapladığınızı unutmayın ve bu insanlar kod önerinizin nedenlerini bilmiyor olabilirler
Balagurunathan Marimuthu

3

CEVAP :

int number_of_elements = sizeof(array)/sizeof(array[0])

AÇIKLAMA :

Derleyici, her veri türü için belirli bir boyutta bellek ayırdığından ve bir dizi bunlardan sadece bir grup olduğundan, dizinin boyutunu veri türünün boyutuna bölebilirsiniz. 30 dizeden oluşan bir dizim varsa, sistemim dizinin her öğesi (dize) için 24 bayt ayırır. 30 elementte toplam 720 bayt. 720/24 == 30 eleman. Bunun için küçük, sıkı algoritma:

int number_of_elements = sizeof(array)/sizeof(array[0]) bu eşittir

number_of_elements = 720/24

Özel bir veri türü olsa bile, dizinin hangi veri türünü bilmeniz gerekmediğini unutmayın.


2019'da bu antika ve hataya eğilimli yaklaşıma gerek yok. Stackoverflow.com/a/59109106/560648 Ayrıca mevcut cevapların sadece bir kopyası.
Yörüngedeki Hafiflik Yarışları

Bununla birlikte, basit, etkili, hızlı, düşük talepli, platformdan bağımsızdır ve vektör veya işaretçi ekleme ihtiyacını ortadan kaldırır. Diğer cevapları çoğaltmaya gelince, aynı algoritma ile sadece bir cevap daha var gibi görünüyor ve sorunun cevabının altta yatan mekaniği hakkında hiçbir açıklama yapmıyor. Saygılı bir şekilde, hataya eğilimli olmak yerine, oldukça sağlam olduğunu öneriyorum.
Bob Warner

1

Sadece bir düşünce, ama sadece bir sayaç değişkeni yaratmaya ve dizi boyutunu [0] pozisyonunda saklamaya karar verdim. İşlevde sahip olduğum kodun çoğunu sildim, ancak döngüden çıktıktan sonra göreceksiniz, asal [0] 'a' nın son değerini atar. Vektörleri kullanmayı denedim ama VS Express 2013 bundan pek hoşlanmadı. Ayrıca 'a' nın üzerine yazmaktan [0] başlayarak başladığını ve başlangıçta hataları önlemek için başlatıldığını unutmayın. Uzman değilim, sadece paylaşacağımı düşündüm.

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

1

Jenerik kullanan iyi bir çözüm:

template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }

Sonra arraysize(_Array);dizinin uzunluğunu almak için arayın .

Kaynak


@bobbogo Satıriçi veya constexpr ile çalışır, belki satıriçi sattınız veya isteğe bağlıdır? ideone.com/VxogJ4
QuentinUK

@QentinUK constexprdüzeltmedir. inlinedeğil. constexprrağmen oldukça modern. Test programınızın, uzunluğu bir değişken tarafından verilen yerel bir diziyi bildirebileceğiniz başka bir modern özellik kullanmadığından emin misiniz? İki küresel diziyle deneyin.
bobbogo

1

Eski g ++ derleyicisi için bunu yapabilirsiniz

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

Bu doğru cevap. C ++ sürümleri arasında çok taşınabilir, işaretçilerle çalışmaz, ayrıca cevap derleme zamanında kullanılabilir
bobbogo

1

Burada zor bir çözüm sağlıyorum:

Her zaman lengthilk öğede saklayabilirsiniz :

// malloc/new

arr[0] = length;
arr++;

// do anything. 
int len = *(arr-1);

free(--arr); 

Maliyet, --arrçağırırken yapmanız gerekenfree


2
Bu, yalnızca arrtürüyle uyumlu bir türdeyse intve dizi türün maksimum değerinden daha uzun olmadığında çalışır. Pascal dizeleri aslında bu hileyi kullanan bayt dizileridir; Pascal'daki dizelerin maksimum uzunluğu 255 karakterdir.
Palec

Biri her dizinin başında 8 bayt demek rezerv olabilir ve nesneleri saklamak istiyorlarsa imzasız uzun kullanabilirsiniz. Bir vektörün muhtemelen daha kolay olduğunu düşünüyorum. Ancak gömülü sistemler için kesinlikle iyi bir çözüm.
aj.toulan

1

bir Dizinin uzunluğunu aşağıdaki şekilde bulabilirsiniz:

int  arr[] = {1, 2, 3, 4, 5, 6}; 
int size = *(&arr + 1) - arr; 
cout << "Number of elements in arr[] is "<< size; 
return 0;

[&] [1] - arr;
QuentinUK

1

Bu pasajı kullanabilirsiniz:

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

}

ve işte referans: http://www.cplusplus.com/reference/array/array/size/


0

Türü sizeof ile birlikte kullanmaktan kaçının, sizeof(array)/sizeof(char)Dizinin türünü değiştirirseniz, aniden bozulduğunda .

Görsel stüdyoda, eşdeğeri varsa sizeof(array)/sizeof(*array). Yazmanız yeterlidir_countof(array)


0

Şahsen ben (normalde ne olursa olsun özel işlevlerle çalışamıyorsanız) dizileri tür uyumluluğunu normalde kullandığınız gibi (örneğin değerleri saklıyorsanız) geçecek şekilde genişletmenizi öneririm:

unsigned int x[] -> int x[]

dizi 1 öğesini yapmanız gerekenden daha büyük yaparsınız. Son öğe için, genişletilmiş tür belirticisine dahil edilen bir tür koyarsınız, ancak normalde örneğin önceki örneği kullanarak kullanmazsınız, son öğe -1 olur. Bu, (for döngüsü kullanarak) bir dizinin son öğesini bulmanızı sağlar.


0

Bunu aramanın en yaygın nedenlerinden biri, bir diziyi bir işleve geçirmek ve boyutu için başka bir argüman iletmek istememenizdir. Ayrıca genellikle dizi boyutunun dinamik olmasını istersiniz. Bu dizi, temel öğeler değil, nesneler içerebilir ve nesneler, size_of () sayısının hesaplanması için güvenli olmayan bir seçenek olacak şekilde karmaşık olabilir.

Diğerlerinin önerdiği gibi, ilkel dizi yerine std :: vector veya list, vb. Kullanmayı düşünün. Bununla birlikte, eski derleyicilerde, bunu basitçe yaparak muhtemelen istediğiniz son çözüme sahip olmazsınız, çünkü kabı doldurmak bir grup çirkin push_back () satırı gerektirir. Benim gibiyseniz, anonim nesnelerin yer aldığı tek satırlık bir çözüm isteyin.

İlkel bir diziye alternatif olarak STL kapsayıcısı ile giderseniz, bu SO post, onu başlatma yolları için size yardımcı olabilir: Sabit kodlanmış öğelerle bir std :: vector'u başlatmanın en kolay yolu nedir?

İşte bunun için derleyiciler ve platformlarda evrensel olarak çalışacak bir yöntem kullanıyorum:

Nesneleri toplamanız için kapsayıcı olarak bir yapı veya sınıf oluşturun. << için bir operatör aşırı yük fonksiyonu tanımlayın.

class MyObject;

struct MyObjectList
{
    std::list<MyObject> objects;
    MyObjectList& operator<<( const MyObject o )
    { 
        objects.push_back( o );
        return *this; 
    }
};

Yapınızı parametre olarak alan işlevler oluşturabilirsiniz, örneğin:

someFunc( MyObjectList &objects );

Ardından, bu işlevi şöyle çağırabilirsiniz:

someFunc( MyObjectList() << MyObject(1) <<  MyObject(2) <<  MyObject(3) );

Bu şekilde, dinamik olarak boyutlandırılmış bir nesne koleksiyonu oluşturabilir ve tek bir temiz satırda bir işleve geçirebilirsiniz!


-4

Sayfanın üstünde bildirilmiş bir küresel diziniz olduğunu varsayalım

int global[] = { 1, 2, 3, 4 };

Dizide kaç öğe olduğunu (c ++ ile) bulmak için aşağıdaki kodu yazın:

sizeof(global) / 4;

Sizeof (NAME_OF_ARRAY) / 4, verilen dizi adı için öğe sayısını size geri verecektir.


8
sizeof (int) platforma bağlıdır. 4 olacağının garantisi yoktur (bu en yaygın durum olsa da)
victor

Eklemek için senden daha.
miksiii

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.