最も頻度の高い筆記試験問題strcpyの使い方
タイトル:既知のstrcpy関数の原型は:char*strcpy(char*strDest,const char*strSrc); 1.ライブラリ関数を呼び出さずstrcpy関数を実装します. 2.なぜchar*に戻るのかを説明します.解説:1.strcpyの実装コード
誤ったやり方:[1](A)ポインタの有効性をチェックせず,解答者がコードの頑丈性を重視しないことを示す.(B)ポインタの有効性をチェックするときに(((!strDest)‖(!strSrc))または(!(strDest&&strSrc))を使用すると,解答者がC言語におけるタイプの暗黙的な変換を深く認識していないことを示す.この例ではchar*をboolに変換するタイプの暗黙的な変換であり、この機能は柔軟であるが、エラー確率の増大とメンテナンスコストの上昇を招くことが多い.したがって、C++はbool、true、falseの3つのキーワードを追加し、より安全な条件式を提供します.(C)ポインタの有効性をチェックするときに使用する((strDest==0)|(strSrc==0))ことは,回答者が定数を使うメリットを知らないことを示す.字面定数(本例では0)をそのまま使用するとプログラムの保守性が低下する.0は簡単であるが、プログラム中にポインタに対するチェックが多く発生する可能性があり、万が一ペンミスが発生した場合、コンパイラは発見できず、生成されたプログラムには論理エラーが含まれており、排除しにくい.一方、0の代わりにNULLを使用すると、スペルミスが発生した場合、コンパイラがチェックされる.[2](A)return new string("Invalid argument(s)");,回答者は戻り値の用途を全く知らず、メモリの漏洩にも警戒していないことを示しています.関数から関数内に割り当てられたメモリを返すのは危険な方法で、彼はメモリを解放する義務を知らない呼び出し者に投げて、ほとんどの場合、呼び出し者はメモリを解放しないで、メモリの漏れを招きます. (B)return 0;,回答者が異常なメカニズムを把握していないことを説明します.呼び出し元は戻り値のチェックを忘れてしまう可能性があります.呼び出し元は戻り値をチェックできないこともある(後述のチェーン式参照).戻り値に正しい値と異常値を返す二重の機能を負わせようと妄想したが、その結果、両方の機能が失効することが多い.戻り値の代わりに異常を投げ出すべきであり、呼び出し元の負担を軽減し、エラーが無視されないようにプログラムのメンテナンス性を向上させることができる.[3](A)元のstrDest値を保存することを忘れて、解答者の論理的な思考が厳密ではないことを説明します.[4](A)サイクルはwhile(*strDest+=*strSrc+);同じ[1](B).(B)ループはwhile(*strSrc!='/0')*strDest+=*strSrc++;,解答者が境界条件の検査に力がないことを説明する.ループが終了するとstrDest文字列の末尾に'/0'が正しく付加されません. 2.strDestの元の値を返すと、関数はチェーン式をサポートし、関数の「追加値」が増加します.同様の機能の関数は,合理的に可用性を向上させることができれば,自然とより理想的である.チェーン式の形式は、int iLength=strlen(strcpy(strA,strB);また、char*strA=strcpy(new char[10]、strB);strSrcの元の値を返すのはエラーです.1つは、ソース文字列が既知であることに違いありません.返す意味がありません.二つ目は、第2の例のような表現をサポートすることはできません.三つ目は、ソース文字列を保護するために、strSrcが指す内容をconstで限定し、const char*をchar*として返し、タイプが一致せず、コンパイルが間違っている.
char * strcpy(char * strDest,const char * strSrc)
{
if ((strDest==NULL)||(strSrc==NULL)) //[1]
throw "Invalid argument(s)"; //[2]
char * strDestCopy=strDest; //[3]
while ((*strDest++=*strSrc++)!='/0'); //[4]
return strDestCopy;
}
誤ったやり方:[1](A)ポインタの有効性をチェックせず,解答者がコードの頑丈性を重視しないことを示す.(B)ポインタの有効性をチェックするときに(((!strDest)‖(!strSrc))または(!(strDest&&strSrc))を使用すると,解答者がC言語におけるタイプの暗黙的な変換を深く認識していないことを示す.この例ではchar*をboolに変換するタイプの暗黙的な変換であり、この機能は柔軟であるが、エラー確率の増大とメンテナンスコストの上昇を招くことが多い.したがって、C++はbool、true、falseの3つのキーワードを追加し、より安全な条件式を提供します.(C)ポインタの有効性をチェックするときに使用する((strDest==0)|(strSrc==0))ことは,回答者が定数を使うメリットを知らないことを示す.字面定数(本例では0)をそのまま使用するとプログラムの保守性が低下する.0は簡単であるが、プログラム中にポインタに対するチェックが多く発生する可能性があり、万が一ペンミスが発生した場合、コンパイラは発見できず、生成されたプログラムには論理エラーが含まれており、排除しにくい.一方、0の代わりにNULLを使用すると、スペルミスが発生した場合、コンパイラがチェックされる.[2](A)return new string("Invalid argument(s)");,回答者は戻り値の用途を全く知らず、メモリの漏洩にも警戒していないことを示しています.関数から関数内に割り当てられたメモリを返すのは危険な方法で、彼はメモリを解放する義務を知らない呼び出し者に投げて、ほとんどの場合、呼び出し者はメモリを解放しないで、メモリの漏れを招きます. (B)return 0;,回答者が異常なメカニズムを把握していないことを説明します.呼び出し元は戻り値のチェックを忘れてしまう可能性があります.呼び出し元は戻り値をチェックできないこともある(後述のチェーン式参照).戻り値に正しい値と異常値を返す二重の機能を負わせようと妄想したが、その結果、両方の機能が失効することが多い.戻り値の代わりに異常を投げ出すべきであり、呼び出し元の負担を軽減し、エラーが無視されないようにプログラムのメンテナンス性を向上させることができる.[3](A)元のstrDest値を保存することを忘れて、解答者の論理的な思考が厳密ではないことを説明します.[4](A)サイクルはwhile(*strDest+=*strSrc+);同じ[1](B).(B)ループはwhile(*strSrc!='/0')*strDest+=*strSrc++;,解答者が境界条件の検査に力がないことを説明する.ループが終了するとstrDest文字列の末尾に'/0'が正しく付加されません. 2.strDestの元の値を返すと、関数はチェーン式をサポートし、関数の「追加値」が増加します.同様の機能の関数は,合理的に可用性を向上させることができれば,自然とより理想的である.チェーン式の形式は、int iLength=strlen(strcpy(strA,strB);また、char*strA=strcpy(new char[10]、strB);strSrcの元の値を返すのはエラーです.1つは、ソース文字列が既知であることに違いありません.返す意味がありません.二つ目は、第2の例のような表現をサポートすることはできません.三つ目は、ソース文字列を保護するために、strSrcが指す内容をconstで限定し、const char*をchar*として返し、タイプが一致せず、コンパイルが間違っている.