C语言库函数实现 【微软面试100题 第八十三题】

题目要求

  1.strcpy/memcpy/memmove;

  2.memset函数;

  3.字符串处理函数。

题目分析  

  1.接口定义:

    char * strcpy(char * dest, const char * src);
    void *memcpy(void *memTo, const void *memFrom, size_t size);
    void *memmove(void *dst,const void *src,size_t n);

    函数区别:

    -->strcpy 和 memcpy主要有以下三方面的区别:
      i)复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符串、整型、结构体、类等。
      ii)复制的方法不同。strcpy不需要指定长度,它遇到被复制字符串的结束符"\0”才结束,所以容易溢出。memcpy则是根据第3个参数决定复制的长度。
      iii)用途不同。通常在复制字符串时用strcpy,而需要复制其它类型的数据是用memcpy。

    -->memcpy和memmove区别:当内存发生局部重叠的时候,memmove保证拷贝的结果是正确的,memcpy不保证拷贝的结果的正确。

  C语言库函数实现 【微软面试100题 第八十三题】

代码实现

char * strcpy(char * dest, const char * src) // 实现src到dest的复制
{
if ((src == NULL) || (dest == NULL)) //判断参数src和dest的有效性
{
return NULL;
}
char *strdest = dest; //保存目标字符串的首地址
while ((*strDest++ = *strSrc++)!='\0'); //把src字符串的内容复制到dest下
return strdest;
}
void *memcpy(void *memTo, const void *memFrom, size_t size)
{
if((memTo == NULL) || (memFrom == NULL)) //memTo和memFrom必须有效
return NULL;
char *tempTo = (char *)memTo; //保存memTo首地址
while(size -- > 0) //循环size次,复制memFrom的值到memTo中
*tempTo++ = * memFrom ++ ;
return memTo;
}
void *memmove(void *dst,const void *src,size_t n)
{
char *dp = (char *)dst;
char *sp = (char *)src;
if(dst==NULL || src==NULL)return NULL;
//非重叠
//dp < sp
//dp > (sp+n)
if(sp>dp||(sp+n)<dp)
{
while(n--)
*(dp++) = *(sp++);
}
else if(sp<dp)//重叠 (此时条件 sp<dp<(sp+n))如果sp==dp则快速的返回
{//反向拷贝
sp += n;
dp += n;
while(n--)
*(--dp) = *(--sp);
}
return dst;
}
void * myMemset(void *ptr,int c,size_t count)
{
void * start = ptr;
if(ptr==NULL)
return NULL;
while(count--)
{
*( char *)ptr = (char )c;
ptr = ( char *)ptr + ; //不转换的话,加1就不清楚就加多少了
}
return start;
}
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h> int mystrlen(const char *str); int main(void)
{
char *b = "hellp"; printf("%d\n",mystrlen(b));
return ;
}
int mystrlen(const char *str)
{
int len;
assert(str != NULL);
len = ;
while (*str ++ != '\0')
++ len;
return len;
}
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h> char *mystrcat(char *strDes, const char *strSrc); int main(void)
{
char *b = "hellp";
char *a = (char *)malloc(sizeof(char)*);
strcpy(a,"haha"); printf("%s\n",mystrcat(a,b));
return ;
}
char *mystrcat(char *strDes, const char *strSrc)
{
char *address;
assert((strDes != NULL) && (strSrc != NULL));
address = strDes;
while (*strDes != '\0')
++strDes;
while ((*strDes++ = *strSrc++) != '\0');
return address;
}
#include <stdio.h>
#include <stdlib.h>
#include <assert.h> int mystrcmp(const char *s, const char *t); int main(void )
{
char a[],c[];
char *b = "hellp" ,*d = "help"; printf( "%d\n",mystrcmp(b,d));
return ;
}
int mystrcmp(const char *s, const char *t)
{
assert(s != NULL && t != NULL);
while (*s && *t && *s == *t)
{
++ s;
++ t;
}
return (*s - *t);
}
//查找字符串s 中首次出现字符c 的位置
#include <stdio.h>
#include <stdlib.h>
#include <assert.h> char *strchr(const char *str, int c); int main(void )
{
char a[],c[];
char *b = "hellp" ; printf( "%c\n",*(strchr(b,'l' )));
return ;
}
char *strchr(const char *str, int c)
{
assert(str != NULL);
for (; *str != (char )c; ++ str)
if (*str == '\0' )
return NULL;
return str;
}
#include <stdio.h>
#include <stdlib.h>
#include <assert.h> char *mystrncpy(char *strDes, const char *strSrc, unsigned int count); int main(void )
{
char a[],c[];
char *b = "hellp" ; printf( "%s\n",mystrncpy(a,b,));
printf( "%s\n",mystrncpy(c,mystrncpy(a,b,),));
return ;
}
char *mystrncpy(char *strDes, const char *strSrc, unsigned int count)
{
char *address;
assert(strDes != NULL && strSrc != NULL);
address = strDes;
while (count-- && *strSrc != '\0' )
*strDes++ = *strSrc++;
*strDes = '\0';
return address;
}
#include <stdio.h>
#include <stdlib.h>
#include <assert.h> char *myStrCopy(char *strDest,const char *strSrc); int main(void )
{
char a[],c[];
char *b = "hellp" ; printf( "%s\n",myStrCopy(a,b));
printf( "%s\n",myStrCopy(c,myStrCopy(a,b)));
return ;
}
//有返回值是为了链式操作
//源字符串用const,是在接口保证不会改变 strSrc里的值
char *myStrCopy(char *strDest,const char *strSrc)
{
char *start = strDest;
if(strDest==strSrc)// 源和目的重叠
return strDest;
assert(strDest!=NULL || strSrc!=NULL); //判断是否为空
while((*start++ = *strSrc++) != '\0' );
return strDest;
}
#include <stdio.h>

const char *my_strstr(const char *str, const char *sub_str)
{
if(str==NULL || sub_str==NULL)
return NULL;
for(int i = ; str[i] != '\0'; i++)
{
int tem = i; //tem 保留主串中的起始判断下标位置
int j = ;
while(str[tem++] == sub_str[j++])
{
if(sub_str[j] == '\0' )
{
return &str[i];
}
}
} return NULL;
} int main()
{
char *s = "1233345hello" ;
char *sub = "" ;
printf( "%s\n", my_strstr(s, sub));
return ;
}

  

上一篇:Java——深入理解Java异常体系


下一篇:Java异常体系概述