1

重複の可能性:
Cプログラミング言語の配列のサイズ?

charの配列があり、それを関数で処理したいので、次のようなコードを試しました。

int main(){
    char *word = new char [5];      
    /*here we make this word
    ....
    */

    process(word);
    puts(word);
}

void process(char *word){
    int sizeOfWord = sizeof(word)-1;
    /* here is cycle that process the word, I need it lenght to know how long cycle must be
    .....
    */
}

しかし、。で配列の長さを取得することはできませんsizeof。なんで?そして、どうすればそれを取得できますか?

4

9 に答える 9

3

できません。ポインタでは、サイズを知る方法はありません。

あなたがすべきことは、あなたの長さもwordあなたに渡すことprocessです。


配列とポインタには違いがあることを知っておく必要があります。配列は確かに要素の数であるためsizeof、配列のサイズ(バイト単位)を示します。一方、ポインタは単なるアドレスです。配列を指していない場合もあります。演算子はコンパイル時に計算されるためsizeof(可変長配列を除く)、意味がわかりません。

この例を考えてみてください。

void process(char *word);

int main(){
    char *word = new char [5];
    char *word2 = new char [10];

    process(word);
    process(word2);
    /* ... */
}

void process(char *word){
    int sizeOfWord = sizeof(word)-1;  // what should this be?
    /* ... */
}

さて、sizeofこの場合はコンパイル時に計算されることを知っているので、どのような値を取得する必要があると思いますか?510


補足:この配列を文字列として使用しているようです。その場合、でその長さを簡単に取得できますstrlen

于 2012-06-15T08:39:30.627 に答える
2

代わりにUを使用する必要がありますstrlen()

編集word:あなたが最後にある有効な単語であると仮定します\0

とにかく、使用するc++ので、のようなコンテナを使用する必要がありますstd::string

于 2012-06-15T08:39:40.170 に答える
2

配列が常にchar*またはconst char*であり、nullで終了する文字列が含まれている場合は、を使用するか、クラスとその適切なメソッドをstrlenさらに簡単に使用できます。std::string

それがnullで終了する文字列でない場合(たとえば、プレーンバイト配列、または質問が配列全般に関するものであり、これcharは単なる例でした)、std::vector<char>またはを使用してそれらのメソッドstd::array<char, 5>を呼び出します。.size()

于 2012-06-15T08:41:48.340 に答える
0

いいえ、機能しません。sizeofポインタは、配列のサイズではなく、ポインタ型のサイズのみを返します。配列をパラメーターとして関数に渡すと、配列はポインターに減衰します。つまり、コンパイラーは、配列が正確に何を指しているのか、配列の場合はどのくらいの長さになるのかを知ることができなくなります。関数内でそれを知る唯一の方法は

  • 追加パラメータとして長さを渡す、または
  • 配列にターミネータ要素を追加します。

CおよびC++の配列はサイズをまったく格納しないため、それを念頭に置いてそれに応じてプログラムする必要があるのはプログラマーであることに注意してください。上記のコードでは、の実際のサイズは5であることがわかりますaが、コンパイラー(およびランタイム)にはそれを知る方法がありません。配列として宣言した場合、つまり

char[] word = new char [5];

コンパイラーはそのサイズを追跡しsizeof、この宣言のスコープ内にある間、このサイズ(バイト単位)を返します。これにより、よく知られているイディオムを適用して、配列の実際のサイズを取得できます。

int size = sizeof(a) / sizeof(char);

ただし、これも、コンパイラが実際に配列であることを認識している場合にのみ機能するため、(ポインタ)パラメータとして渡されるa関数呼び出し内では不可能です。a

于 2012-06-15T08:38:48.760 に答える
0

配列は、このようなコードの最初の要素へのポインターに「減衰」するため、できません。ポインタは、ポインタが指すメモリブロックの大きさを「認識」していません。サイズを個別に渡す必要があります。例:

void process(char *word, size_t length);
于 2012-06-15T08:39:46.263 に答える
0

C / C ++で配列の長さを知る唯一の方法は、すでに知っていることです。配列の長さを別のパラメーターとして渡す必要があります。

文字列について具体的に話している場合は、配列内のnull文字を検索し、そのインデックス+ 1を長さとして使用します(これは基本的にstrlen()関数が行うことです)。

それ以外の場合は、代わりにstd :: stringを使用して、その長さプロパティを取得できますか?

于 2012-06-15T08:40:48.823 に答える
0

配列の長さをprocess関数に渡すか、null(\0)文字を使用して終了をマークする必要があります。

後者を使用できると仮定すると

void process(char *word)
{
  while (*word)
  {
    //do stuff with the character *word
    ++word;
   }
}
于 2012-06-15T08:41:21.973 に答える
0

Windowsには_msize、ヒープに割り当てられたメモリサイズをバイト単位で取得する関数があります。VS2005およびVS2008では、メモリの割り当てnewに使用されていたため、演算子と完全に連携していました。malloc私は注意する必要があります:

これは標準的な方法ではないため、使用しないでください。

Object * addr = new Object[xxx];
size_t number_of_objects = _msize(addr) / sizeof(Object);
于 2012-06-15T08:45:08.017 に答える
0

他の回答では、古典的なC配列のサイズを取得できない理由について詳しく説明していますが、次の点を指摘しておきます。

あなたの例には欠けています

delete [] word;

メインの終わりに。そうしないと、メモリリークが発生します。

これは、C ++で配列を操作するための好ましい方法が、std::vectorまたは(固定長の場合は)新しいstd::array文字列の場合は文字列を使用することである理由を示していますstd::string。コンパイラが基盤となるストレージを管理します。これらのクラスはすべてsize関数を提供します。

于 2012-06-15T09:27:18.823 に答える