web-dev-qa-db-ja.com

関数に渡された場合、配列のサイズを決定します

配列が別の関数に渡された場合(サイズが渡されなかった場合)、配列のサイズを判別することはできますか?配列はint array [] = {XXX} ..のように初期化されます。

ポインタのサイズを返すため、sizeofを実行できないことを理解しています。理由は、配列が渡される他の関数内でforループを実行する必要があるためです。私は次のようなことを試しました:

for( int i = 0; array[i] != NULL; i++) {
........
}

しかし、配列の近くで、array [i]に758433のようなガベージ値が含まれていることがあります。これは、配列の初期化で指定された値ではありません。

36
Charles Khunt

他の答えは、c ++の1つの機能を見落としています。参照で配列を渡し、テンプレートを使用できます。

template <typename T, int N>
void func(T (&a) [N]) {
    for (int i = 0; i < N; ++i) a[i] = T(); // reset all elements
}

その後、これを行うことができます:

int x[10];
func(x);

ただし、これはarraysでのみ機能し、ポインターでは機能しません。

ただし、他の回答が指摘しているように、std::vectorの方が適しています。

53
Evan Teran

コントロール内にある場合は、配列ではなくベクターや両端キューなどのSTLコンテナーを使用します。

14
Fred Larson

いいえ、それは不可能です。

1つの回避策:認識できるように、配列の最後の値に特別な値を配置します。

9
tekBlues

1つの明白な解決策は、STLを使用することです。それが可能でない場合は、配列の長さを明示的に渡すことをお勧めします。この特定のケースでは、センチネル値のトリックを使用することに懐疑的です。 NULLは番兵にとって適切な値であるため、ポインタの配列を使用するとうまく機能します。整数の配列では、それはそれほど簡単ではありません-「魔法の」センチネル値が必要ですが、これは良くありません。

補足:配列が次のように定義され、初期化されている場合

 int array[] = { X, Y, Z };

ループと同じスコープで

sizeof(array)は、ポインタのサイズではなく、実際のサイズをバイト単位で返します。配列の長さは次のように取得できます

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

ただし、一般に、配列をポインタとして取得した場合、このトリックは使用できません。

6
Igor Krivokon

ターミネーターをint配列に追加してから、配列を手動でステップ実行して、メソッド内のサイズを見つけることができます。

#include<iostream>
using namespace std;

int howBigIsBareArray(int arr[]){
    int counter = 0;
    while (arr[counter] != NULL){
        counter++;
    }
    return counter;
}
int main(){
    int a1[6] = {1,2,3,4,5,'\0'};
    cout << "SizeOfMyArray: " << howBigIsBareArray(a1);
}

このプログラムは以下を出力します:

SizeOfMyArray: 5

これはO(n)時間の複雑な操作です。これは悪いことです。配列のサイズを確認するためだけに配列をステップ実行することはできません。

4
Ali

サイズを渡すことができない場合は、最後に区別可能なsentinel値が必要です(そして、自分でそこに置く必要があります-ご存じのように、C++を信頼することはできません。あなたのために自動的にそれをしてください!)それが渡されず、明示的で信頼性のあるセンチネルが使用されていない場合、呼び出された関数に魔法のようにサイズを神聖にする方法はありません。

3
Alex Martelli

Null文字を追加してみてください\0を配列に送信して送信しますか?そうすれば、ループで\ 0をチェックするだけで済みます。

1

実際にチャックのリスト

for(int i = 0; array [i]!= NULL; i ++){........}

各呼び出しの前のsizeofは無駄であり、何を取得するかを知るために必要です。

配列の最後にNULLを置くとうまくいきます。

なぜ??組み込み設計では、各ルーチンでsizeofを渡すと、各配列のNULLと比較して、各呼び出しが非常に大きくなります。私は2K PIC16F684チップを使用しており、アレイと一緒に渡されたsizeofを使用して12回の呼び出しでチップの最大10%を使用します。配列と、各配列のNULLを含むチャックコードだけで、4%が必要になります。

真実の例は..ありがとうチャック良い呼び出し。

1
Saturn5tony