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)
char *my_strncpy(char *s,const char *ct,size_t n) { assert(s!=NULL&&ct!=NULL); int i=0; while(i<n&&ct[i]!=NULL) { 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<n;i++,j++) s[i]=ct[j]; s[i]='\0'; return s; }5.int strcmp(cs,ct)
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相比较。当cs<ct时,返回一个负数;当cs=ct时,返回0;当cs>ct时,返回一个正数。
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<n)) { cs++; ct++; i++; } return *cs-*ct; }7.char *strchr(cs,c)
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)
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||s>(ct+n-1)) { while(i<n) { *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; }