いくつかの質問を含む宿題があります。1 つは、strcpy() 関数が CString の参照演算子による呼び出しを必要としない理由を尋ねることです。私はこの本を何度も読み返しましたが、一生答えを見つけることができません。誰かが私にこれを説明するのを助けることができますか?
これは並べ替えの配列なので、参照による呼び出しが必要になると思います。
strcpy()
charへのポインターを取ります。
したがって、「文字列」をパラメーターとして渡すのではなく、最初の文字のアドレスのみを渡します。
したがって、基本的には次のようなものがあります。
void func(const char* str);
const char* str = "abc";
func(str); // Here str isn't passed by reference but since str is a pointer to the first character ('a' here), you don't need a reference.
ポインターの受け渡しは高速です。32 ビット アーキテクチャでは、ポイントされた文字列の長さに関係なく、ポインターは 32 ビットを使用します。
あなたが意味する場合class CString
、言い換えれば、質問はあなたに尋ねます:
なぜこれがコンパイルされるのですか?
CString sExample;
char buffer[LARGE_ENOUGH];
strcpy(buffer, sExample);
答えは、 は演算子 const char* を定義しているため、の 2 番目の引数のclass CString
型に変換できるためです。strcpy
これがあなたの言いたいことかどうかはわかりません。
これは主に用語の問題です。
「オブジェクト」(私はこの用語を「RAM のチャンク」を設計するときに使用します) は、呼び出された関数がチャンクのコピーを取得するときに値渡しされます。呼び出された関数が唯一のチャンクにアクセスする方法を取得すると、参照によって渡されます。
このことを考慮:
void f(int x)
{
x = 42;
}
void g()
{
int y = 54;
f(y);
// here "y" still has value 54
}
ここで、関数f()
は を変更しますx
が、それはそれ自身のx
であり、 の変数の内容のコピーを含むy
変数ですg()
。f()
そのと何をするかは、のが含むx
ものには影響しません。その後、変数は値によって渡されます。y
g()
C++ には、次のような参照の概念があります。
void f(int& x)
{
x = 42;
}
void g()
{
int y = 54;
f(y);
// here "y" now has value 42
}
ここで、特別な構造 (" &
" を使用) は、C++ コンパイラにいくつかの隠されたトリックを実行するように指示します。これにより、x
既知の byは、実際には、によって使用される変数f()
の一種のエイリアスになります。変数は 1 つだけです。とは RAM の同じチャンクを指定します。ここでは、変数は参照によって渡されます。y
g()
x
y
ここで、「C 文字列」を考えてみましょう。C (および C++) では、文字列は単なる値の集まりでありchar
、最後の値は 0 です (これは従来の文字列ターミネータです)。コードは文字列を直接処理しません。ポインタを使用します。ポインターは、実際に RAM 内の配置を指定する値です。ポインタは文字列ではありません。ポインタは一種の数値 (通常は 32 ビットまたは 64 ビットで、プロセッサの種類とオペレーティング システムによって異なります) であり、RAM のどこがchar
文字列の最初であるかを示します。したがって、呼び出すstrcpy()
ときに実際にポインターを渡します (宛先バッファー用に 1 つ、ソース文字列用に 1 つ)。これらのポインターは変更されません。ソース文字列と宛先バッファーはプロセスで移動されません。中身だけの文字列が宛先バッファにコピーされます。
したがって、strcpy()
呼び出し元コードのポインターを含む変数にアクセスする必要はありません。strcpy()
デスティネーション バッファとソース文字列が RAM 内のどこにあるかを知る必要があるだけです。ポインタ値のコピーを与えるstrcpy()
だけで十分です。したがって、これらのポインターは値によって渡されます。
ポインタが存在する場合、考慮すべきオブジェクトが2 つあります。ポインタを含む変数と、ポイントされる RAM のチャンクです。ポインター自体は値渡しされます (strcpy()
宛先バッファーへのポインターを含む変数の独自のコピーを受け取ります)。ポイントされた RAM のチャンク (デスティネーション バッファ) は、プロセス内で複製されず、呼び出された関数 ( strcpy()
) によって変更される可能性があるため、「参照によって渡される」と言えます。ここでのポイントは、「参照」という用語には2 つの異なる意味があるということです。
C++ 構文の意味: 「参照」は、上で説明した「 」を使用して特別な構造を示し&
ます。
言語理論の正式な意味: 「参照」は、呼び出し元と呼び出し先が異なる名前で RAM の同じチャンクにアクセスできるように、値を間接的に指定する方法を指定します。その意味で、呼び出された関数へのポインターを値渡しすることは、ポインターが指す RAM のチャンクを参照渡しすることと同じです。
C++ の「参照」(最初の意味) は、「参照によって」(2 番目の意味) 変数を渡す構文上の方法です。
c-strings (char*) を意味する場合は、文字列自体がポインターであるため、参照による呼び出しは必要ありません。したがって、文字列のコピーは、文字列をコピーする場所と場所を知っています。
自動型変換は、彼らが探していると思う答えです。そのターンアップを見ると、いくつかの助けになるかもしれません。
strcpy はポインターである char* で動作するためです。ポインターは値で渡され、strcpy はそのポインターを使用してターゲット文字列内の個々の文字にアクセスし、それらを変更します。これを整数を値で渡す場合と比較してください。関数は元の整数を変更できません。
char* 文字列がどのように整数に似ていないかを理解することは、C++ コースで夢中にならないために不可欠です。あなたの教授があなたにそれに直面させてくれたのはよくやった。
C では、関数を呼び出すときに配列が最初の要素のアドレスとして渡されるため、参照による呼び出しと同じです。
Peter Van Der Linden Expert C プログラミング、Deep secrets book を参照してください。