C言語ライブラリ関数の実現
5167 ワード
1.Cライブラリにおけるstrcmpの実装コード
方法1:
なぜunsigned charを使うのですか?これはcharの表示範囲が-128~127、unsigned charの表示範囲が0~255であるためである.unsigned charを使用しないと、転送ASCIIに問題は発生しませんが、転送拡張ASCIIコードに問題が発生します.文字列は文字配列(最後の文字は'0')なので、文字列'hello'メソッド2:
2.C言語ライブラリ関数strcpyの実装char*strcpy(char*strDest,char*strSrc){assert((strDest!=NULL)&&(strSrc!=NULL);char*address=strDest;while((*strDest+=*strSrc++)!=’0’);return address;}
3.メモリコピー関数memcpy注意すべきことは、ANSI(American National Standards Institute)規格では、voidポインタをアルゴリズム操作することはできません.すなわち、voidポインタをp++などの操作はできないので、char*などの具体的なタイプのポインタに変換して操作する必要があります.
4.メモリ操作memmove関数
プログラムから、pToとpFromが指す領域が重複していない場合、2つの関数がまったく同じで、メモリが重複していない条件は、pTo<=pFrom|(char)pTo>=(char)pFrom+sizeであることがわかる.そうでなければmemcpyは正常に動作しませんが、memmoveは正常に動作します.
方法1:
int strcmp(char *str1,char *str2)
{
for(;*str1==*str2;str1++,str2++)
{
if(*str1=='\0')
return 0;
}
return (*(unsigned char *)str1unsigned char *)str2 ?-1:1);
}
なぜunsigned charを使うのですか?これはcharの表示範囲が-128~127、unsigned charの表示範囲が0~255であるためである.unsigned charを使用しないと、転送ASCIIに問題は発生しませんが、転送拡張ASCIIコードに問題が発生します.文字列は文字配列(最後の文字は'0')なので、文字列'hello'メソッド2:
int strcmp(char *str1,char *str2)
{
assert((str1!=NULL)&&(str2!=NULL));
int ret=0;
while(!(ret!=*(unsigned char*)str1-*(unsigned char*)str2) && *str2)
{
str1++;
str2++;
}
if(ret>0)
ret=1;
else if(ret<0)
ret=-1;
return ret;
}
2.C言語ライブラリ関数strcpyの実装char*strcpy(char*strDest,char*strSrc){assert((strDest!=NULL)&&(strSrc!=NULL);char*address=strDest;while((*strDest+=*strSrc++)!=’0’);return address;}
3.メモリコピー関数memcpy注意すべきことは、ANSI(American National Standards Institute)規格では、voidポインタをアルゴリズム操作することはできません.すなわち、voidポインタをp++などの操作はできないので、char*などの具体的なタイプのポインタに変換して操作する必要があります.
void * memcpy(void *pTo,const void *pFrom,size_t count)
{
//memcpy pTo pFrom
void *ret=pTo;
while(count--)
{
*(char *)pTo=*(char *)pFrom;
pTo=(char *)pTo+1;
pFrom=(char *)pFrom+1;
}
return ret;
}
4.メモリ操作memmove関数
void* memcpy(void *pTo,const void *pFrom,size_t size)
{
if(pTo==NULL || pFrom==NULL)
return ;
void *ret=pTo;
// ,
if(pTo <=pFrom ||(char*)pTo >=(char *)pFrom +size)
{
while(size--)
{
*(char *)pTo=*(char *)pFrom;
pTo=(char *)pTo+1;
pFrom=(char *)pFrom+1;
}
}
else// ,
{
pFrom=(char *)pFrom +size-1;
pTo=(char *)pTo +size-1;
while(size--)
{
*(char *)pTo=*(char *)pFrom;
pTo=(char *)pTo-1;
pFrom=(char *)pFrom-1;
}
}
return ret;
}
プログラムから、pToとpFromが指す領域が重複していない場合、2つの関数がまったく同じで、メモリが重複していない条件は、pTo<=pFrom|(char)pTo>=(char)pFrom+sizeであることがわかる.そうでなければmemcpyは正常に動作しませんが、memmoveは正常に動作します.