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.
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.
Yanıtlar:
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
.
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 _countof
yapar). Bunu constexpr
derleme zamanı ifadesi yapar, böylece makro üzerinde herhangi bir dezavantajı yoktur (en azından hiçbirini bilmiyorum).
Ayrıca kullanarak düşünebiliriz std::array
bir 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 ).
T(arg&)[N]
.
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
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] )
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
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.
std::vector
size()
vektördeki eleman sayısını döndüren bir metoda sahiptir.
(Evet, bu yanak dilidir)
#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;
}
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>
.
Bir T
dizi 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.
Bir T
dizi N
tü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 T
ilk boyutu boyunca bilinmeyen bir dizi varsa ve N
0 ise, değer 0'dır.
Eğer T
bazı 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 T
tü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, decltype
birleş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.
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
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.
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.
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'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'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
.
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.
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;
İşte biri uygulamasıdır ArraySize
gelen 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.
int nombres[5] = { 9, 3 };
bu işlev 5
yerine döner 2
.
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:cout
size_of_array
>>> 4
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);
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.
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;
}
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 .
constexpr
düzeltmedir. inline
değil. constexpr
rağ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.
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;
}
Burada zor bir çözüm sağlıyorum:
Her zaman length
ilk öğede saklayabilirsiniz :
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
Maliyet, --arr
çağırırken yapmanız gerekenfree
arr
türüyle uyumlu bir türdeyse int
ve 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.
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;
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/
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)
Ş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.
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!
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.