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

  

代码实现

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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   tractorman  阅读(754)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?

导航

统计

点击右上角即可分享
微信分享提示