标签:部分函数功能的实现
1:strcpy的实现
函数功能:把从src地址处开始的字符串拷贝到以dest为开始地址的空间里,
其中包含src字符串结尾处的‘\0‘。
代码实现:
#include<stdio.h>//模拟实现strcpy
#include<assert.h>
void my_strcpy(char *dest, const char *src)/*函数不需要返回*/
{
assert(dest);
assert(src);
while(*src)/*把src的字符从前到后往dest里拷贝*/
{
*dest=*src;
dest++;
src++;
}
*dest=‘\0‘;/*拷贝上最后的‘\0‘,因为strcpy有将src里的‘\0‘拷贝到dest里的功能*/
{
char str1[15];
char str2[]="hello world";
my_strcpy(str1, str2);
printf("%s\n",str1);
return 0;
}
运行结果:
2:strcmp的实现
函数功能:字符串大小的比较,如果有str1,str2两个字符串则有两种结果,相等 ,str1大,str2大。
让str1的第一个元素和str2第一个元素相比较它们的ASCII值,若当比较到两个字符最后还没分出大小则返回0,如果没有比较到‘\0‘的位置就分出大小则也返回相应的值。如的str1当前元素大于str2的当前元素则返回整数,否则返回负数。
代码实现:
#include<stdio.h>//模拟实现strcmp
#include<assert.h>
int my_strcmp(const char *str1, const char *str2)/*str1和str2都不需要改变*/
{
assert(str1);
assert(str2);
while(*str1==*str2)
{
if(*str1==‘\0‘)/*可以表示此时的str1和str2比较到了最后,且都为‘\0‘*/
{
return 0;
}
str1++;/*如果str1和str2相等但是没到字符串末尾则让str1和str2往后移动,再次比较*/
str2++;
}
return *str1-*str2;/*如果两个不相等则用ASCII相减返回*/
}
int main()
{
int ret=0;
char str1[]="aac";
char str2[]="abc";
ret=my_strcmp(str1,str2);
if(ret==0)
{
printf("str1和str2相等\n");
}
else if(ret>0)
{
printf("str1大于str2\n");
}
else if(ret<0)
{
printf("str1小于str2\n");
}
return 0;
}
运行结果:
3:改进上次strstr,strcat,strncat的实现(三个函数返回的均是地址。strcat和strncat是返回dest的地址,可以实现链式访问)
#include<stdio.h>//模拟实现strcat
#include<assert.h>
char *my_strcat(char *dest, const char *src)
{
char *address=dest;
assert(dest);
assert(src);
while(*dest)
{
dest++;
}
while(*src)
{
*dest=*src;
dest++;
src++;
}
*dest=‘\0‘;
return address;
}
int main()
{
char str1[15]="hello";
char str2 [] ="world";
printf("%s\n",my_strcat(str1, str2));
return 0;
}
*/
/*
#include<stdio.h>//模拟实现strncat
#include<assert.h>
char *my_strncat(char *dest, const char *src)
{
int n,i;
char *address=dest;
scanf("%d",&n);
while(*dest)
{
dest++;
}
for(i=0;i<n;i++)
{
*(dest+i)=*(src+i);
}
*(dest+i+1)=‘\0‘;
return address;
}
int main()
{
char str1[15]="hello";
char str2 [] ="world";
printf("%s\n",my_strncat(str1, str2));
return 0;
}
*/
/*
#include<stdio.h>//模拟实现strstr
#include<string.h>
char *my_strstr(char *str1,char *str2)
{
int i,j;
int len1=strlen(str1);
int len2=strlen(str2);
for(i=0;i<len1;i++)
{
for(j=0;j<len2;j++)
{
if(str1[i]==str2[j])
return &str1[i];
}
}
return NULL;
}
int main()
{
char str1[]="he is good teacher";
char str2[]="good";
printf("%s\n",my_strstr(str1,str2));
return 0;
}
*/
4:strlen的实现
函数功能:strlen完成一个计数的功能,从后到前扫描字符串直到遇到‘\0‘停止,最后计数的结果不包括‘\0‘。
代码有三种实现方式,计数器法,地址运算法,递归函数法:
*/
#include<stdio.h>//模拟实现strlen 计数器法
#include<assert.h>
int my_strlen(const char *str)
{
int count=0;
assert(str);
while(*str)
{
count++;
str++;
}
return count;
}
int main()
{
int ret=0;
char str[]="abcdefg";
ret=my_strlen(str);
printf("%d\n",ret);
return 0;
}
#include<stdio.h>//模拟实现strlen 地址运算法
#include<assert.h>
int my_strlen(const char *str)
{
char *tmp=str;
assert(str);
while(*str)
{
str++;
}
return str-tmp;/*地址相减得到中间的元素的个数*/
}
int main()
{
char str[]="abcdefg";
printf("%d\n",my_strlen(str));
return 0;
}
#include <stdio.h>//模拟实现strlen 用递归方法
#include <assert.h.>
int my_strlen (const char *str)
{
assert(str);
if(*str==‘\0‘)
return (0);
else
{
return my_strlen(str+1)+1;
}
}
int main()
{
int ret=0;
char str[]="abcdefg";
ret=my_strlen(str);
printf("%d\n",ret);
return 0;
}
5:memcpy函数
内存拷贝函数,是将src所指内存地址的起始位置拷贝count个字节到目标dest
所指向内存处的空间,是从dest第一的位置开始覆盖,一共用src里的n个字节的信息覆盖。
函数原型:void *memcpy(void *dest, const void *src,int count)
代码实现:
#include<stdio.h>//模拟实现momcpy
#include<assert.h>
void* my_momcpy(void *buf1,const void *buf2, int count )/*空类型的指针,所以buf1,buf2可以接收任何类型的数组*/
{
char *ret=buf1;/*要*返回dest的地址,以便输出*/
char *dest=(char*)buf1;/*将指针强制类型转化成字符型,以便于一个一个字节地拷贝*/
char *src =(char*)buf2;
assert(buf1);
assert(buf2);
while(count--)
{
*dest=*src;
dest++;
src++;
}
return ret;
}
int main()
{
char str[]="hello world";
char arr[10];
printf("%s\n",my_momcpy(arr, str, 6));/*拷贝6个字节地信息到arr[10]里*/
return 0;
}
memcpy和strcpy的区别:
strcpy只能对字符串进行操作,且内存里有0时strcpy有可能会误以为是‘\0‘,结束拷贝工作,这样就会造成拷贝操作的局限性;memcpy是内存拷贝函数,可以对任何类型的数组进行拷贝,它是将一个一个字节的信息从src拷贝到dest里,也可以跨类型进行拷贝。 (ASI标准不规定memcpy实现内存重叠拷贝,但有的编译器会实现此功能)
6:memmove函数
函数功能:将src所指向内存区域复制count个字节信息到dest里,可以实现内存不重叠的拷贝工作,也能实现内存重叠处的拷贝工作
函数原型:void *memmove( void *dest, const void *src, Int count)
代码实现:
#include<stdio.h>//模拟实现mommove
#include<assert.h>
void* my_mommove(void *buf1,const void *buf2 ,int count)/*空类型的指针接收数组名,以便于一次性将所有可能性的类型强制类型转换成char* */
{
char *ret=buf1;
char *dest=(char*)buf1;/*强制类型转换成char*,这样可以一个字节一个一个字节地将信息拷贝*/
char *src =(char*)buf2;
assert(buf1);
assert(buf2);
if((dest<(src+count))&&dest>src)/*内存重时叠*/
{
while(count--)
{
*(dest+count)=*(src+count);
}
}
else/*内存不重叠时*/
{
while(count--)
{
*dest=*src;
dest++;
src++;
}
}
return ret;
}
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,0};
int i;
my_mommove(arr+5,arr+2,16);/*将3 4 5 6 拷贝到 6 7 8 9的位置,4个元素16个字节 */
for(i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
运行结果:
(本次实现了strcmp,strcpy,strlen,memcpy,memmove,另外改进了strstr,strcat,strncat)
本文出自 “anser” 博客,转载请与作者联系!
标签:部分函数功能的实现
原文地址:http://674353165.blog.51cto.com/10786549/1718319