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 2014-11-25 22:21 tractorman 阅读(754) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 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,谁才是开发者新宠?