web-dev-qa-db-ja.com

配列の長さを調べるにはどうすればいいですか?

配列が持つ値の数を見つける方法はありますか?配列の終わりに達したかどうかを検出することもできます。

457
Maxpm

Cスタイルの配列の場合は、次のようにすることができます。

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

ただし、これはポインタに対しては機能しません。つまり、 はしません は、次のいずれかに対して機能します。

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

または

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

int a[7];
func(a);

C++では、この種の動作が必要な場合は、コンテナクラスを使用する必要があります。おそらく std::vector です。

429

他の人が言ったようにあなたはsizeof(arr)/sizeof(*arr)を使うことができますが、これは配列ではないポインタ型のためにあなたに間違った答えを与えるでしょう。

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

これには、配列ではない型のコンパイルに失敗するというNiceプロパティがあります(Visual Studioには、これを行う _countof )があります。 constexpr はこれをコンパイル時の式にするので、マクロを超える欠点はありません(少なくとも私が知っているものはありません)。

ネイティブのC配列にオーバーヘッドをかけずにその長さを公開するC++ 11のstd::arrayを使用することも検討できます。

C++ 17 <iterator>ヘッダーに std::size() を持っています。これは同じことをし、STLコンテナにも働きます( @Jon C のおかげで)。

115
Motti

sizeof( myArray )を実行すると、その配列に割り当てられた合計バイト数がわかります。その後、配列内の1つの要素のサイズで除算することによって、配列内の要素数を調べることができます。sizeof( myArray[0] )

73
MahlerFive

配列が持つ値の数を見つける方法はありますか? 

はい!

sizeof(array)/sizeof(array[0])を試す

配列の終わりに達したかどうかを検出することもできます。

あなたの配列が文字の配列(すなわち文字列)でない限り、私はこれのための方法を見ません。

P.S:C++では、常にstd::vectorを使用してください。いくつかの作り付けの機能と拡張機能があります。

49
Prasoon Saurav

これは古い質問ですが、答えをC++ 17に更新する価値があります。標準ライブラリには、テンプレート関数 std::size() があります。これは、stdコンテナまたはCスタイルの配列の両方の要素数を返します。例えば:

#include <iterator>

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

std::vectorには、ベクトル内の要素数を返すメソッドsize()があります。

(はい、これは頬の答えです)

25
eq-
#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;
}
24
JukkaP

C++ 11以降、いくつかの新しいテンプレートが導入され、配列の長さを扱うときの手間が省けました。それらはすべてヘッダー<type_traits>で定義されています。 

  • std::rank<T>::value

    Tが配列型の場合は、その配列の次元数に等しいメンバ定数値を指定します。他のタイプの場合、値は0です。

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

    Tが配列型の場合、Nが[0、std::rank<T>::value)にある場合は、配列のN番目の次元に沿った要素数に等しいメンバ定数値を指定します。他の型の場合、またはTが最初の次元に沿って境界が不明な配列で、Nが0の場合、valueは0です。

  • std::remove_extent<T>::type

    TX型の配列の場合は、メンバーtypedef typeがXと等しく、それ以外の場合はtypeはTです。 Tが多次元配列の場合、最初の次元だけが削除されます。

  • std::remove_all_extents<T>::type

    Tが何らかのX型の多次元配列である場合は、Xと等しいメンバーtypedef typeを提供し、それ以外の場合はtypeはTです。

多次元配列の任意の次元の長さを取得するために、decltypeを使用してstd::extentと組み合わせることができます。例えば:

#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、多次元配列内の要素の総数を取得する:

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

あるいはそれを関数テンプレートに入れる:

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

それらを使用する方法のより多くの例はリンクをたどることによって見つけられるかもしれません。

21
Jaege

TR1/C++ 11/C++ 17の方法もあります(それを見てください) Live on Colir):

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
17
metal

組み込みの配列関数akaを使う代わりに、

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

あなたは配列クラスと配列テンプレートを使うべきです。試してください:

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

そのため、配列の長さを調べたい場合は、配列クラスのsize関数を使用するだけです。

Name_of_Array.size();

そしてそれは配列の要素の長さを返すべきです。

9
Mr. Foots

C++では、std :: arrayクラスを使用して配列を宣言すると、配列のサイズと最後の要素も簡単に見つけることができます。

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

実際、配列クラスには他にもたくさんの関数があり、それらを使って配列を標準のコンテナにすることができます。
C++への参照1 std :: array class
std :: array classのリファレンス2
参考文献の例は役に立ちます。

6
Tarun Maganti

C++/CXの場合(たとえば、Visual StudioでC++を使用するUWPアプリを作成するとき)、size()関数を使用することで配列内の値の数を見つけることができます。

ソースコード:

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

coutsize_of_arrayにすると、出力は次のようになります。

>>> 4
3
Arslan Ahmad
 length = sizeof(array_name)/sizeof(int);
2
David Gladson

これは Google Protobuf からのArraySizeの実装です。

#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)(配列のバイト数)およびsizeof(*(arr))(1つの配列要素のバイト数)を調べることによって機能します。前者が後者で割り切れるならば、おそらくarrは確かに配列であり、その場合、除算結果は配列の要素の数です。そうでなければ、arrはおそらく配列になることはできず、コードのコンパイルを妨げるためにコンパイラエラーが発生します。

Boolのサイズはインプリメンテーション定義なので、最終的な結果が確実にtypeになるようにするために!(sizeof(a)&sizeof(*(a)))をsize_tにキャストする必要がありますsize_t.

このマクロは、特定のポインタ、つまりポインタサイズが指示先サイズで割り切れるポインタを誤って受け入れるため、完全ではありません。すべてのコードは32ビットコンパイラを通過する必要があるため、ポインタは4バイトです。これは、サイズが3または4より大きい型へのすべてのポインタが(正当に)なることを意味します。拒否されました。

2
zangw

総称を使用した良い解決策:

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

それから単にarraysize(_Array);を呼び出して配列の長さを取得します。

出典

古いg ++コンパイラの場合は、これを実行できます。

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

私はここでトリッキーな解決策を提供します: 

最初の要素にはいつでもlengthを格納できます。

// malloc/new

arr[0] = length;
arr++;

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

free(--arr); 

コストは、freeを呼び出すときに--arrする必要がある

1
陳 力

配列の型を変更すると、sizeof(array)/sizeof(char)のようにsizeofと一緒に型を使用するのは避けてください。

ビジュアルスタジオでは、sizeof(array)/sizeof(*array)。の場合と同等です。単に_countof(array)と入力することもできます。

0
Johan Jönsson

私は個人的に(何らかの理由で特殊な関数を扱うことができない場合)、最初に通常使用するものを超えて配列型の互換性を拡張することをお勧めします(0以上の値を保存している場合:

unsigned int x[] -> int x[]

配列1の要素を必要以上に大きくするよりも。最後の要素には、展開された型指定子に含まれるが通常は使用しない型を配置します。前の例を使用すると、最後の要素は-1になります。これにより、(forループを使用して)配列の最後の要素を見つけることができます。

0

次のようにして、配列の長さを見つけることができます。

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

このスニペットを使うことができます。

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

}

そしてここに参照があります: http://www.cplusplus.com/reference/array/array/size/

0
Amado Saladino

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;
0
Ito

ちょっと考えただけで、カウンタ変数を作成し、配列サイズをposition [0]に格納することにしました。関数内にあるコードの大部分を削除しましたが、ループを抜けた後、prime [0]には 'a'の最終値が割り当てられます。私はベクトルを使ってみましたが、VS Express 2013はそれほど好きではありませんでした。 [0]の上書きを避けるために 'a'は1から始まり、エラーを避けるために最初から初期化されています。私は専門家ではありません、ちょうど私が共有すると思った。 

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

これを探すことになる最も一般的な理由の1つは、配列を関数に渡したいのですが、そのサイズに別の引数を渡さなくてもよいからです。また、一般的に配列サイズを動的にしたいと思うでしょう。その配列はプリミティブではなくオブジェクトを含んでいるかもしれず、size_of()がカウントを計算するための安全ではないオプションであるようにオブジェクトは複雑かもしれません。 

他の人が示唆しているように、プリミティブ配列の代わりにstd :: vectorやlistなどを使うことを検討してください。しかし、古いコンパイラでは、コンテナーを生成するには醜いPush_back()行が多数必要になるため、それだけではおそらく最終的な解決策は得られません。あなたが私のような人であれば、匿名のオブジェクトを含む単一行のソリューションが必要です。

プリミティブ配列の代わりにSTLコンテナを使用する場合は、このSOポストを使用して初期化することができます。 stdを初期化する最も簡単な方法は何ですか。 :ハードコードされた要素を持つベクトル?

これが私がこのために使っている方法で、コンパイラやプラットフォームを越えて普遍的に機能します。

オブジェクトのコレクションのコンテナとして構造体またはクラスを作成します。 <<の演算子オーバーロード関数を定義します。

class MyObject;

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

あなたはあなたの構造体をパラメータとして取る関数を作成することができます。例えば: 

someFunc( MyObjectList &objects );

そして、このようにその関数を呼び出すことができます。

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

このようにして、動的にサイズ設定されたオブジェクトのコレクションを構築し、1つのクリーンな行で関数に渡すことができます。

0
BuvinJ