-2
void myfunc(char* passedArray)
{
    cout << sizeof(passedArray) << endl; // prints 4
}

int main(void)
{
    char charArray[] = "abcdefghiklmop";

    cout << sizeof(charArray) << endl; // prints 15
    myfunc(charArray);
    cout << sizeof(charArray) << endl; // prints 15
}

その関数内に15を出力する必要があると思います...

4

7 に答える 7

9

これは、ポインターと配列の古典的な問題です。問題は、ご覧のとおり、配列がポインターに減衰することです。ポインター型は、指す型のサイズを除いて、指すデータに関するメタデータを保持しません。配列の長さなど、他のすべてのメタデータは失われます。

したがって、問題は、配列へのポインターをmyfunc使用して呼び出したことです。配列に関するすべてのメタデータは、関数から見えなくなりmyfuncます。これにより、演算子の微妙な違いがトリガーsizeofされます。つまり、ポインターに適用されると、配列の長さではなく、ポインター型のサイズが得られます。ただし、配列に適用すると、関数でわかるように、配列の長さが得られますmain

短い修正strlenです。代わりに使用してください。

于 2013-02-18T10:04:00.277 に答える
4

配列を として定義しましたが、char charArray[]を取る関数に渡すと、 は最初の要素へのポインターに変換されるため、関数の本体で呼び出すと、ポインターのサイズが出力されます (これは32 ビット マシンでは 4 バイト) 期待どおりです。char*charArraysizeof

関数がchar passedArray[]引数として受け取ったとしても、オリジナルcharArrayは最初の要素へのポインターに崩壊し、呼び出しによってこの配列のサイズを取得する機能はsizeof失われます。(配列の減衰とは?を参照してください)。

したがってstrlen()、この C スタイルの文字列のサイズを取得するために呼び出すことができますが、C++ コードを記述しているため、最も合理的な解決策はstd::stringC スタイルの文字列の代わりに使用することです。

于 2013-02-18T10:07:11.033 に答える
4

まず、あなたは何を期待していますか?ポインタとして定義passedArrayしたのでsizeof(passedArray)、マシン上のポインタのサイズを返します。他に何ができるでしょうか?あなたの機能が次の場合、私はいくつかの混乱を理解できました:

void myFunc( char passedArray[15] )

この場合、合理的な人は 15 であると予想できsizeof(passedArray)ます (しかし、配列がパラメーターとして使用され、配列がコンパイラーによってポインターに変換され、この定義があなたのものとまったく同じであるため、彼は間違っているでしょう)。

これらすべてに対する答えは、次を使用することstd::stringです。

void
myFunc( std::string const& passedValue )
{
    std::cout << passedValue.size() << std::endl;
}

とは異なりchar[]std::string実際に動作します。文字列として使用されるかどうかにかかわらず、C スタイルの配列は壊れており、静的な有効期間と初期化の問題の順序を持​​つオブジェクトに主に関連する非常に限られたケースでのみ使用する必要があります。

于 2013-02-18T10:12:42.017 に答える
2

文字列の長さを取得するには、strlen()ではなくを使用します。sizeof()

C では、文字列は単なる 0 で終わる文字配列です。StringC には特別な型はありません。strlen()は、終端の 0 バイトまでの文字数をカウントする関数です。

sizeof()変数またはデータ型のサイズを決定するために使用できる演算子です。あなたの場合、ポインターsizeof()のサイズを返しchar*ます(プラットフォームでは4バイトのようです)。

于 2013-02-18T10:03:11.417 に答える
1

関数内では、これ

cout << sizeof(passedArray) << endl;

のサイズを印刷しています。passedArrayこれはchar*です。お使いのプラットフォームでは、ポインターのサイズは 4 です。関数にポインターを渡す場合、関数は固定サイズの配列の最初の要素を指していることを知る方法がありません。固定配列のサイズが必要な場合は、ポインターではなく配列を渡します。

template< class T, size_t N >
void myfunc( const T (&passedArray)[N] )
{
  std::cout << N << "\n";
}
于 2013-02-18T10:03:45.200 に答える
1

sizeof(char*)指す文字列ではなく、ポインターのサイズを指定します。

あなたが本当に欲しいのはstrlen.

文字列のサイズを指定する理由は、ではなく (コンパイル時にサイズがわかっている配列)main()として定義されているためです。char[]char*

于 2013-02-18T10:03:57.527 に答える
0

sizeof(passedArray)passedArrayは、タイプのポインタのサイズを返しchar *ます。システムでは、明らかに 4 バイトです。

strlen代わりに使用する、または使用するstd::string

于 2013-02-18T10:04:13.810 に答える