C语言库函数的实现是笔试面试常考的题目。这两天有一个很宝贵的面试机会,决定补一补这方面的知识。我假定读者已经基本了解了这些函数的基本用法,所以不再做这方面的详细讲解。函数的定义参考自《The C Programming Language》。
一、字符串
1.char *strcpy(s,ct)
将字符串ct(包括'\0')复制到字符串s中,并返回s。
char *my_strcpy(char *s,const char *ct)
{
assert(s!=NULL&&ct!=NULL);
int i=0;
while((s[i]=ct[i])!='\0') i++;
}
2.char *strncpy(s,ct,n)
将字符串ct中最多n个字符复制到字符串s中,并返回s。如果ct中少于n个字符,则用'\0'填充。
char *my_strncpy(char *s,const char *ct,size_t n)
{
assert(s!=NULL&&ct!=NULL);
int i=0;
while(i
{
s[i]=ct[i];
i++;
}
s[i]='\0';
return s;
}
3.char *strcat(s,ct)
将字符串ct连接到s的尾部,并返回s。
char *my_strcat(char *s,const char *ct)
{
assert(s!=NULL&&ct!=NULL);
int i,j;
for(i=0;s[i]!='\0';i++);
for(j=0;ct[j]!='\0';i++,j++) s[i]=ct[j];
s[i]='\0';
return s;
}
4.char *strncat(s,ct,n)
将字符串ct中最多前n个字符连接到字符串s的尾部,并以'\0'结束;该函数返回s。
char *my_strncat(char *s,const char *ct,size_t n)
{
assert(s!=NULL&&ct!=NULL);
int i,j;
for(i=0;s[i]!='\0';i++);
for(j=0;ct[j]!='\0'&&j
s[i]='\0';
return s;
}
5.int strcmp(cs,ct)
比较字符串cs和ct;当csct时,返回一个正数。
int my_strcmp(const char *cs,const char *ct)
{
assert((cs!=NULL)&&(ct!=NULL));
while(*cs&&*ct&&(*cs==*ct))
{
cs++;
ct++;
}
return *cs-*ct;
}
6.int strncmp(cs,ct,n)
将字符串cs中至多前n个字符与字符串ct相比较。当csct时,返回一个正数。
int my_strncmp(const char *cs,const char *ct,size_t n)
{
assert((cs!=NULL)&&(ct!=NULL));
int i=1;
while(*cs&&*ct&&(*cs==*ct)&&(i
{
cs++;
ct++;
i++;
}
return *cs-*ct;
}
7.char *strchr(cs,c)
返回指向字符c在在字符串cs中第一次出现的位置的指针;如果cs中不包含c,则该函数返回NULL。
char *my_strchr(const char *cs,int c)
{
assert(cs!=NULL);
const char *p=cs;
while(*p!='\0')
{
if(*p==c) return (char *)p;
else p++;
}
return NULL;
}
8.char *strrchr(cs,c)
返回指向字符c在字符串cs中最后一次出现的位置的指针;如果cs中不包含c,则该函数返回NULL。
char *my_strrchr(const char *cs,int c)
{
assert(cs!=NULL);
const char *p=cs;
while(*p!='\0') p++;
while(p!=cs-1&&*p!=c) p--;
if(p!=cs-1) return (char *)p;
else return NULL;
}
9.char *strstr(cs,ct)
返回一个指针,它指向字符串ct第一次出现在字符串cs中的位置;如果cs中不包含字符串ct,则返回NULL。
char *my_strstr(const char *cs,const char *ct)
{
assert(cs!=NULL&&ct!=NULL);
const char *s=cs;
const char *t=ct;
for(;*cs!='\0';++cs)
{
for(s=cs,t=ct;*t!='\0'&&*s==*t;++s,++t);
if(*t=='\0') return (char *)cs;
}
return NULL;
}
10.size_t strlen(cs)
返回字符串cs的长度。
size_t my_strlen(const char *cs)
{
assert(cs!=NULL);
int i=0;
while(cs[i]!='\0') i++;
return i;
}
二、内存使用
1.void *memcpy(s,ct,n)
将字符串ct中的n个字符拷贝到s中,并返回s。
void *my_memcpy(void *s,const void *ct,size_t n)
{
assert(s!=NULL&&ct!=NULL);
unsigned char *temps=(unsigned char*)s;
unsigned char *tempct=(unsigned char*)ct;
while(n-->0)
{
*temps=*tempct;
temps++;
tempct++;
}
return s;
}
2.void *memove(s,ct,n)
该函数的功能与memcpy类似,所不同的是,当对象重叠时,该函数仍能正确执行。
void* my_memmove(void *s,void *ct,size_t n)
{
assert(s!=NULL&&ct!=NULL);
unsigned char *temps=(unsigned char*)s;
unsigned char *tempct=(unsigned char*)ct;
int i=0;
if(s(ct+n-1))
{
while(i
{
*temps++=*tempct++;
i++;
}
}
else
{
i=n;
temps+=n;
tempct+=n;
while(i>0)
{
*temps--=*tempct--;
i--;
}
}
return s;
}
三、数值转换
1.int atoi(const char *s)
将字符串s转换为int类型。
int my_atoi(const char *s)
{
int sign=1;
int integer=0;
assert(s!=NULL);
while(isspace(*s)) s++;
if(*s=='-') sign=-1;
if(*s=='-'||*s=='+') s++;
while(*s>='0'&&*s<='9')
{
integer=integer*10+*s-'0';
s++;
}
integer=sign*integer;
return integer;
}