3

私はこれを読んでいました: const char * const vs const char *?

ではstring.hstrlenは次のように定義されます。

size_t strlen ( const char * str );

これを正しく理解していれば、strlen は const である char へのポインタを期待しています。そうではありませんか:

size_t strlen ( const char* const str );

これにより、strlen が別のポインターを指すようにポインターを変更できないようになります。

または、これは事実ですか:

str ポインターは値によって strlen に渡されるため、関数内でこのポインターを変更してもソース ポインターは変更されないため、問題ありません。

??

4

3 に答える 3

12

その議論を本当に読んだら、2番目constは関数の外部動作に影響を与えないことを理解する必要があります。のユーザーであるあなたにとって、またはパラメーターstrlenで宣言されているかどうかに違いはありません。あなたが正しく指摘したように、ポインターに行われる可能性のある変更は、内のポインターの内部のローカルコピーにのみ影響します。渡す引数ポインターは、パラメーターが秒で宣言されているかどうかに関係なく、変更されません。(引数ポインタは左辺値である必要さえありません。)const char *const char *conststrlenstrlenstrlenconst

2 つ目constは、関数内のローカル パラメーター変数の内部動作にのみ影響を与え、作成者がstrlenそのローカル変数を変更できないようにします。彼らがそのように自分自身を制限したいかどうかは、非公式に言えば、彼ら自身の問題です. のユーザーにはまったく関係ありませんstrlen

実際、最上位のconst修飾子は関数の型に影響を与えないため、通常、パラメーターを使用して関数を宣言しconst char *、パラメーターを使用して関数を定義することがconst char *constできます。コンパイラ (リンカー) は、これらの宣言を「一致」として扱います。これは、ライブラリの作成者が希望すれば、実際strlenconst char *constパラメータで定義できることを意味します。strlenこれは事実上実装の詳細または、つまり、知る必要のないものであるため、彼らは単にそれについてあなたに話していません。

于 2012-07-26T16:56:11.000 に答える
2

size_t strlen ( const char* const str );

これにより、strlen が別のポインターを指すようにポインターを変更できないようになります。

あなたは理由を自分で説明しました: strlen はポインタを変更できません... .

次のように、ポインター自体を変更しながら長さを計算するために使用できる、パラメーターに不必要な制限を課します。

 size_t len = 0;
 while(*str)
 {
   ++len;
   ++str; //error if `const char *const str` is used!
 }

ポインター自体を変更するstrlen()in glibcの実装を参照してください:変更可能なポインター型に割り当てることによって。

OpenBSD lib の実装も参照してください。

size_t strlen(const char *str)
{
    const char *s;

    for (s = str; *s; ++s)
        ;
    return (s - str);
}

s=strタイプの場合、ここstrでエラーになりますconst char * const!

于 2012-07-26T17:06:21.710 に答える
2

str ポインターは値によって strlen に渡されるため、関数内でこのポインターを変更してもソース ポインターは変更されないため、問題ありません。

はい。関数の内部処理の制限のみです。

これにより、strlen が別のポインターを指すようにポインターを変更できないようになります。

必要ありません。ポインタは値渡しです。

于 2012-07-26T16:58:04.983 に答える