文字列レプリケーション関数strcpyおよびmemcpy関数の作成


Strcpyとmemcpyの2つの関数の経典の実現、ははは、しかし、私が書いたのではありません!^^......
 
char *strcpy(char *des, const char *src){
       assert((des != NULL) && (src != NULL));
       char *add = des;
       while ((*des = *src ) != ‘/0’) ;
return add;
}
 
void  *memcpy(void *pvTo, const void *pvFrom, size_t size) {
       assert((pvTo != NULL) && (pvFrom != NULL));     //アサーションの使用
       byte *pbTo = (byte *) pvTo;        //pvToのアドレス変更防止
       byte*pbFrom=(byte*)pvFrom;//pvFromのアドレス変更防止
       while(size --> 0 )
              *pbTo = *pbFrom ;
       return pvTo;
}
 
 
 
古典的な問題:
strcpy関数の原型はchar*strcpy(char*strDest,const char*strSrc)であることが知られている.1.ライブラリ関数を呼び出さずstrcpy関数を実装する2.なぜchar*を返すのかを説明する.
1.strcpyの実装コードchar*strcpy(char*strDest,const char*strSrc){ if((strDest == NULL) || (strSrc == NULL))//[1]  throw "Invalid Arguments";//[2] char* strDestCopy = strDest;//[3] while((*strDest = *strSrc ) != '/0')//[4]  ; return strDestCopy;}
[1](A)ポインタの有効性をチェックせず、設計者がプログラムの頑丈性を重視しないことを説明(B)ポインタの有効性をチェックする際に使用する((!strDest)‖(!strSrc))または(!(strDest&&strSrc))は、C言語におけるタイプ暗黙変換について深く認識していないことを説明し、この例ではchar*をboolに変換するタイプ暗黙変換であり、この機能は柔軟であるが、しかし,より多くはエラー確率の増大とメンテナンスコストの増大(C)ポインタの有効性を検査する際の使用((strDest=0)|(strSrc=0))は,解答者が定数の使用を知らない利点を説明する.この例の0のような字面定数を直接使用すると、プログラムのメンテナンス性が低下します.0は簡単ですが、プログラムにはポインタのチェックが多く発生する可能性があります.万が一、誤記が発生した場合、コンパイラは発見できません.生成されたプログラムには論理的なエラーが含まれており、排除しにくいです.0の代わりにNULLを使用すると、スペルミスが発生するとコンパイラがチェックされます.[2](A)return new string("Invalid arguments");,回答者は返す価値があることを全く知らず、メモリの漏洩にも警戒心がなく、関数体から関数体内に割り当てられたメモリを返すのは非常に危険な方法であり、メモリを解放する義務を知らない呼び出し者に投げつけ、ほとんどの場合、呼び出し者はメモリを解放せず、メモリ漏洩(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*として返し、タイプが一致せず、コンパイルが間違っている.
 
 
strcpyとmemcpyの違い
ポイント:文字列コピーとメモリコピーの違い.出現頻度:★★★解析strcpyとmemcpyには主に以下の3つの違いがある.コピーの内容が違います.strcpyは文字列のみをコピーできますが、memcpyは文字配列、整数、構造体、クラスなど、任意の内容をコピーできます.コピーの仕方が違います.strcpyは長さを指定する必要はありません.文字列の終端記号「/0」に遭遇すると終了します.memcpyは,その3番目のパラメータに基づいてコピーの長さを決定する.用途が違う.通常、文字列をコピーするときはstrcpyを使用しますが、他のタイプのデータをコピーする必要がある場合はmemcpyを使用します.    以下はより詳細なstrcpyとmemcpy関数の作成と応用である:strcpy関数をプログラミングして実現する.ポイント:文字列コピーの実装.出現頻度:★既知strcpy関数のプロトタイプは:
char * strcpy(char * strDest,const char * strSrc);

要求は以下の通り.(1)ライブラリ関数を呼び出さずstrcpy関数を実現する;(2)なぜchar*を返すのかを説明する.解析プログラムのコードは次のとおりです.
1     #include <stdio.h>
2
3    char * strcpy(char * strDest, const char * strSrc) // strSrc strDest
4    {
5        if ((strDest == NULL) || (strSrc == NULL)) // strDest strSrc
6        {
7            return NULL;
8        }
9        char *strDestCopy = strDest;        //
10       while ((*strDest++ = *strSrc++)!='/0'); // strSrc strDest
11  
12       return strDestCopy;
13   }
14  
15   int getStrLen(const char *strSrc)         // strSrc
16   {
17       int len = 0; //
18       while(*strSrc++ != '/0')             // '/0'
19       {
20           len++;
21       }
22  
23       return len;
24   };
25  
26   int main()
27   {
28       char strSrc[] = "Hello World!";       //
29       char strDest[20];                  //
30       int len = 0;                       //
31      
32       len = getStrLen(strcpy(strDest, strSrc)); // ,
33       printf("strDest: %s/n", strDest);
34       printf("Length of strDest: %d/n", len);
35  
36       return 0;
37   }

(1)strcpy関数の実装説明.コード5〜7行目は、入力されたパラメータstrDestおよびstrSrcがNULLであるか否かを判断し、そうであればNULLを返す.コード9行目はstrDestの値をstrDestCopyポインタに保存します.コード10行目はstrSrcとstrDestの2つのポインタを循環移動し、strSrcメモリの値をstrDestメモリにコピーし続けます.strDestポインタの値が保存されているため、ここではstrDestCopyの値を返すだけで、関数呼び出しが完了するとstrDestの値が返されます.(2)strcpy関数がchar*タイプを返すのは,チェーン式を使用できるためである.まずstrcpyを呼び出してstrDestポインタにstrSrcのメモリデータをコピーさせ、getStrLen関数を呼び出してstrDest文字列の長さを取得します.これにより、呼び出しが便利になるだけでなく、プログラム構造が簡潔明瞭になります.プログラムの出力結果は以下の通りです:strDest:Hello World!Length of strDest: 12   プログラミングはmemcpy関数を実現します.ポイント:メモリレプリケーションの実現.出現頻度:★★★回答プログラムコードは以下の通りです.
1     #include <stdio.h>
2    #include <assert.h>
3   
4    void *memcpy2(void *memTo, const void *memFrom, size_t size)
5    {
6        assert((memTo != NULL) && (memFrom != NULL)); //memTo memFrom
7        char *tempFrom = (char *)memFrom;             // memFrom
8        char *tempTo = (char *)memTo;                  // memTo
9       
10       while(size -- > 0)                // size , memFrom memTo
11           *tempTo++ = *tempFrom++ ;
12  
13       return memTo;
14   }
15  
16   int main()
17   {
18       char strSrc[] = "Hello World!";    //
19       char strDest[20];               //
20      
21       memcpy2(strDest, strSrc, 4);    // strSrc 4 strDest
22       strDest[4] = '/0';                // strDest 5 '/0'
23       printf("strDest: %s/n", strDest);
24  
25       return 0;
26   }

memcpyの実現は以下の通りである.strcpyとは異なり、memcpyはパラメータsizeでコピーする文字数を決定します(strcpyは終了記号「/0」で終了します).メインプログラムではstrSrcの最初の4文字(コード22行目)しかコピーされていないため、プログラム出力は以下の通りである.
strDest: Hell