一篇文章教你自己动手实现C语言库函数
作者:大桑树保安队
memmove
函数声明
void * memmove ( void * destination, const void * source, size_t num );
函数作用
将num字节的值从source指向的位置复制到destination指向的内存块。复制就像使用了中间缓冲区一样进行,从而允许目标和源重叠。
该函数不检查source中是否有任何终止的空字符——它总是精确地复制num字节。
为了避免溢出,目标和源参数所指向的数组的大小必须至少为num字节。
返回destination。
实现memmove
#include <stdio.h> #include <string.h> #include <assert.h> //实现memmove void* my_memmove(void* dst, const void* src, size_t n) { assert(dst && src); char* dst_temp = (char*)dst; char* src_temp = (char*)src; if (src_temp<dst_temp && src_temp + n>dst_temp)//src在dst前,两者交错,需从后往前复制 { while (n) { *(dst_temp + n - 1 )= *(src_temp + n - 1); n--; } } else { while (n--) { *dst_temp++ = *src_temp++; } } return dst; } int main() { int a[10] = { 0,1,2,3,4,5,6,7,8,9 }; my_memmove(a+2, a, 4*sizeof(int)); for (int i = 0; i < 10; ++i) { printf("%d ", a[i]); } return 0; }
memcpy
函数声明
void * memcpy ( void * destination, const void * source, size_t num );
函数作用
将num个字节的值从source所指向的位置开始直接复制到destination所指向的内存块。
该函数不检查source中是否有任何终止的空字符——它总是精确地复制num字节。
为了避免溢出,目标和源参数所指向的数组的大小必须至少为num字节,并且不能重叠(对于重叠的内存块,memmove是一种更安全的方法)。
返回destination。
实现memcpy
//实现memcpy void* my_memcpy(void* dst, const void* src, size_t n) { assert(dst && src); char* dst_temp = (char*)dst; char* src_temp = (char*)src; while (n--) { *dst_temp++ = *src_temp++; } return dst; } int main() { int a[10] = { 0,1,2,3,4,5,6,7,8,9 }; my_memcpy(a+2, a, 4*sizeof(int)); for (int i = 0; i < 10; ++i) { printf("%d ", a[i]); } return 0; }
重叠的区间将会被提前破坏。
strstr
函数声明
char * strstr (char * str1, const char * str2 );
函数作用
查找子字符串
返回一个指向str1中第一次出现的str2的指针,如果str2不是str1的一部分,则返回一个空指针。
匹配过程不包括结束空字符,但它在此停止。
实现strstr
/实现strstr char* my_strstr(const char* mom,const char* son) { char* cp=mom; char* i, *j; if (*son == '\0') { return mom; } while (*cp != '\0') { i = cp; j = son; while (i && *i == *j) { i++; j++; if (*j == '\0') return cp; } cp++; } return NULL; } int main() { char mom[] = "abcdefghijk"; char son[] = "ghi"; printf("%s\n",my_strstr(mom, son)); return 0; }
strcat
函数声明
char * strstr (char * str1, const char * str2 );
函数作用
连接字符串
将source字符串的副本粘贴追加到目标字符串。destination中的结束空字符被source中的第一个字符覆盖,并且在由destination中的两个字符串联形成的新字符串的末尾包含一个空字符。
目标和源不应重叠。
返回destionation。
实现strcat
/实现strstr char* my_strstr(const char* mom,const char* son) { char* cp=mom; char* i, *j; if (*son == '\0') { return mom; } while (*cp != '\0') { i = cp; j = son; while (i && *i == *j) { i++; j++; if (*j == '\0') return cp; } cp++; } return NULL; } int main() { char mom[] = "abcdefghijk"; char son[] = "ghi"; printf("%s\n",my_strstr(mom, son)); return 0; }
strcmp
函数声明
char * strcat ( char * destination, const char * source );
函数作用
比较字符串str1和字符串str2。
这个函数开始比较每个字符串的第一个字符。如果它们彼此相等,则继续执行下面的对,直到字符不同或到达一个终止的空字符为止。
返回值
1)<0 第一个不匹配的字符在ptr1中的值比在ptr2中的值低
2)=0 两个字符串的内容相等
3)>0 第一个不匹配的字符在ptr1中的值大于ptr2中的值
实现strcmp
char* my_strcat(char* dst,const char* src) { assert(dst && src); int len1 = strlen(dst); char* start = dst + len1; while (*start++ = *src++) { ; } return dst; } int main() { char mom[26] ="abcdefg"; char son[] = "hijk"; printf("%s\n",my_strcat(mom, son)); return 0; }
strcpy
函数声明
int strcmp ( const char * str1, const char * str2 );
函数作用
复制字符串
将source指向的字符串复制到destination指向的数组中,包括终止空字符(并在此点停止)。
为了避免溢出,destination指向的数组的大小应该足够长,以包含与source相同的字符串(包括结束的null字符),并且不应该在内存中与source重叠。
返回destination。
实现strcpy
//实现strcpy char* my_strcpy(char* dst, const char* src) { char* start = dst; assert(dst && src); while (*dst++ = *src++); return start; } int main() { char mom[26] ="abcdefg"; char son[] = "abq"; my_strcpy(mom, son); printf("%s\n",mom); return 0; }
strlen
函数声明
size_t strlen ( const char * str );
函数作用
获取字符串长度
返回C字符串str的长度。
C字符串的长度由结束空字符决定:C字符串的长度等于字符串开头和结束空字符之间的字符数(不包括结束空字符本身)。
char mystr[100]="test string";
定义了一个长度为100个字符的字符数组,但是用于初始化mystr的C字符串长度只有11个字符。因此,当sizeof(mystr)计算为100时,strlen(mystr)返回11。
实现strlen
//实现strlen size_t my_strlen(const char* str) { size_t len = 0; while (*str++) { len++; } return len; } int main() { char mom[26] ="abcdefg"; printf("%d\n",my_strlen(mom)); return 0; }
output:7
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!