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不保证拷贝的结果的正确。

  

代码实现

 

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; //不转换的话,加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 0;
}
int mystrlen(const char *str)
{
    int len;
    assert(str != NULL);
    len = 0;
    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)*100);
    strcpy(a,"haha");

    printf("%s\n",mystrcat(a,b));
    return 0;
}
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[10],c[10];
    char *b = "hellp" ,*d = "help";

    printf( "%d\n",mystrcmp(b,d));
    return 0;
}
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[10],c[10];
    char *b = "hellp" ;

    printf( "%c\n",*(strchr(b,'l' )));
    return 0;
}
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[10],c[10];
    char *b = "hellp" ;

    printf( "%s\n",mystrncpy(a,b,3));
    printf( "%s\n",mystrncpy(c,mystrncpy(a,b,3),2));
    return 0;
}
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[10],c[10];
    char *b = "hellp" ;

    printf( "%s\n",myStrCopy(a,b));
    printf( "%s\n",myStrCopy(c,myStrCopy(a,b)));
    return 0;
}
//有返回值是为了链式操作
//源字符串用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 = 0; str[i] != '\0'; i++)
    {
        int tem = i; //tem 保留主串中的起始判断下标位置
        int j = 0;
        while(str[tem++] == sub_str[j++])
        {
            if(sub_str[j] == '\0' )
            {
                return &str[i];
            }
        }
    }

    return NULL;
}

int main()
{
    char *s = "1233345hello" ;
    char *sub = "345" ;
    printf( "%s\n", my_strstr(s, sub));
    return 0;
}

 

  

 

posted on 2014-11-25 22:21  tractorman  阅读(751)  评论(0编辑  收藏  举报

导航