atoi,itoa,strcpy,strcp,memcpy的实现

1、memcpy、memmove、memset源码

  定义函数:    void *memcpy(void *dest, const void *src, size_t n)
  函数说明:    memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。 与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'\0'而结束

memcpy memmove区别和实现

memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。

memmove的处理措施:

(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝

(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

-- memcpy实现

void* memcpy(void* dest, const void* src, size_t n)    //注意参数类型
{
    char* d = (char*) dest;
    const char*  s = (const char*) src;
    while(n--) 
       *d++ = *s++;
    return dest;
}

-- memmove实现

void* memmove(void* dest, const void* src, size_t n)
{
    char* d  = (char*) dest;
    const char*  s = (const char*) src;
  
    if (s>d) 
    {
         // start at beginning of s
         while (n--)
            *d++ = *s++;
    }
    else if (s<d)
    {
        // start at end of s
        d = d+n-1;
        s = s+n-1;
  
        while (n--)
           *d-- = *s--;
    }
    return dest;
}

原型: void *memset(void *buffer, int c, int count);
用法:#include <string.h>
功能:把buffer 所指内存区域的前count个字节设置成字符c。
说明:返回指向buffer的指针。
源码实现:
void *memset(void *src, int c, size_t count)
{
 assert(src!=NULL);
 char *tmpsrc=(char*)src;
 while(count--)
  *tmpsrc++ =(char)c;
 return src;
}


2、strcpy、strcat等源码

strcat:*char strcat(dst, src) - concatenate (append) one string to another

char * __cdecl strcat ( char * dst, const char * src )
{
        char * cp = dst;
        while( *cp )
                cp++;                   /* find end of dst */
        while( *cp++ = *src++ ) ;       /* Copy src to end of dst */
        return( dst );                  /* return dst */
}

strcpy: char *strcpy(dst, src) - copy one string over another,后面的字符串将覆盖前面的

char * __cdecl strcpy(char * dst, const char * src)
{
        char * cp = dst;
        while( *cp++ = *src++ )
                ;               /* Copy src over dst */
        return( dst );
}
当src到达 '\0’时,*cp被赋值为'\0’,整个表达式的值即为'\0’,对应的ASC码值为0     =>while退出

strcmp: - compare two strings, returning less than, equal to, or greater than

*Exit:
*       returns -1 if src <  dst
*       returns  0 if src == dst
*       returns +1 if src >  dst

int __cdecl strcmp ( const char * src,  const char * dst)
{
        int ret = 0 ;
 
        while( ! (ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst) //直到src和dst当前数值不相等或dst为\0时退出while
                ++src, ++dst;
 
        if ( ret < 0 )
                ret = -1 ;
        else if ( ret > 0 )
                ret = 1 ;
        return( ret );
}

3、atoi和itoa源码:

atoi源码:

long long core(char *str,bool minus);
int _atoi(char *str)
{
	long long num=0;
	long long sum=0;
	if(str!=NULL &&str!='\0')
	{
		bool minus = false;
		if(*str=='+')
			str++;
		else if(*str=='-')
		{
			minus=true;
			str++;
		}
		sum=core(str,minus);
	}
	return (int)sum;

}
long long core(char *str,bool minus)
{
	long long num=0;
	while(*str!='\0')
		{
			if(*str >='0' && *str <='9')
			{
				num=num*10+(*str-'0');
				if((!minus && num>0x7fffffff )|| (minus &&(0-num)<(signed int)0x80000000))
				{
					num=0;
					break;
				}
				str++;
			}
			else
			{
				num=0;
				break;
			}
		}
	return num;
}

atoi源码:

char* _itoa(int value, char* string, int radix)
{
	char tmp[33];
	char* tp = tmp;
	int i;
	unsigned v;
	int sign;
	char* sp;
	if (radix > 36 || radix <= 1)
	{
		__set_errno(EDOM);
		return 0;
	}
	sign = (radix == 10 && value < 0);
	if (sign)
		v = -value;
	else
		v = (unsigned)value;
	while (v || tp == tmp)
	{
		i = v % radix;
		v = v / radix;
		if (i < 10)
			*tp++ = i+''0'';
		else
			*tp++ = i + ''a'' - 10;
	}
	if (string == 0)
		string = (char*)malloc((tp-tmp)+sign+1);
	sp = string;
	if (sign)
		*sp++ = ''-'';
	while (tp > tmp)
		*sp++ = *--tp;
	*sp = 0;
	return string;
}

整数字符串的转化

1、直接采用现有函数

(1)直接采用itoa实现整数到字符串的转换

  函数形式为:char *itoa(int value, char *string, int radix);

  该函数包含在头文件stdlib.h中。int value 被转换的整数,char *string 转换后储存的字符数组,int radix 转换进制数,如2,8,10,16 进制等。

  具体实现为:

#include<stdlib.h>
#include<stdio.h>
void main()
{
    int a=123;
    char string[10];
    itoa(a,string,10);
    printf("整数:%d\n字符串:%s",a,string);
}

(2)直接采用atoi实现字符串到整数的转换

  函数形式为: int atoi(const char *nptr);

    函数说明: 参数nptr字符串,如果 第一个非空格字符不存在或者不是数字也不是正负号则返回零,否则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停止转换,返回整型数。
  具体实现为:
#include<stdlib.h>
#include<stdio.h>
void main()
{
    int a;
    char string[10]="123";
    a=atoi(string);
    printf("转换后的整数:%d",a);
}

2、不采用现有的itoa和atoi函数

(1)整数到字符串的转换

  具体实现为:

#include<stdlib.h>
#include<stdio.h>
void main()
{
    int i,j=0,a=123456;
    char temp[10],string[10];
    while(a)
    {
        i=a%10+'0';
        temp[j++]=i;
        a=a/10;
    }
    i=0;
    j--;
    while(j>=0)
        string[i++]=temp[j--];
    string[i]='\0';
    printf("转换成的字符串为:%s",string);
}

(2)字符串到整数的转换

  具体实现为:

#include<stdlib.h>
#include<stdio.h>
#include<string>
void main()
{
    char temp[10],string[10]="123456";
    int i=0,j,a=0;
    strcpy(temp,string);
    while(temp[i])
    {
        a=a*10+(temp[i]-'0');
        i++;
    }
    printf("转换为整数:%d",a);
}

字符数组和strcpy

(1)面试题1

  strcpy字符串拷贝函数的实现

  strcpy的原型为:char*strcpy(char *strDest,const char *strSrc)

  具体实现为:

#include<stdlib.h>
#include<stdio.h>
char *strcpy1(char *strDest,char *strSrc)
{
    char *temp=strDest;
    while((*strDest=*strSrc)!='\0')
    {
        strDest++;
        strSrc++;
    }
    return temp;
}

void main()
{
    char str[]="123iamhappy!";
    char strDest[50];
    strcpy1(strDest,str);
    printf("最终的结果为:%s\n",strDest);    
}

(2)面试题3

  编写一个函数,把一个char组成的字符串循环右移n位

  具体实现为:

  方法1:自己实现的

//(1)形参和实参均为数组名
#include<stdio.h>
#include<string.h>
void loopmove(char temp[],int n)
{
    int i=0,j,len;
    char c;
    len=strlen(temp);
    for(i=0;i<n;i++)
    {
        c=temp[len-1];
        for(j=len-2;j>=0;j--)
            temp[j+1]=temp[j];
        temp[0]=c;
    }
}
void main()
{
    char s[]="123456789";
    int steps=2;
    loopmove(s,steps);
    printf("%s\n",s);
}
//--------------------------------------------------------------------------
//(2)形参为指针变量,实参为数组名
#include<stdio.h>
#include<string.h>
void loopmove(char *p,int n)
{
    int i,j,len;
    char *q, temp;
    len=strlen(p);
    printf("%d\n",len);

    for(i=0;i<n;i++)
    {
        q=p;
        temp=*(p+len-1);
        for(j=len-2;j>=0;j--)
        {
            *(p+j+1)=*(p+j);
        }
        *p=temp;
    }
}    
void main()
{
    char s[]="123456789";
    int steps=2;
    loopmove(s,steps);
    printf("%s\n",s);
}
//--------------------------------------------------------------------------
(3)//形参为指针变量,实参也为指针变量
#include<stdio.h>
#include<string.h>
void loopmove(char *p,int n)
{
    int i,j,len;
    char *q, temp;
    len=strlen(p);
//    printf("%d\n",len);

    for(i=0;i<n;i++)
    {
        q=p;
        temp=*(p+len-1);
        for(j=len-2;j>=0;j--)
        {
            *(p+j+1)=*(p+j);
        }
        *p=temp;
    }
}    
void main()
{
    char *p,s[]="123456789";
    int steps=2;
    p=s;
    loopmove(p,steps);
    printf("%s\n",p);
}
//------------------------------------------------------------------------
(4)//形参为数组名,实参为指针变量
#include<stdio.h>
#include<string.h>
void loopmove(char temp[],int n)
{
    int i=0,j,len;
    char c;
    len=strlen(temp);
    for(i=0;i<n;i++)
    {
        c=temp[len-1];
        for(j=len-2;j>=0;j--)
            temp[j+1]=temp[j];
        temp[0]=c;
    }
}
    
void main()
{
    char *p,s[]="123456789";
    int steps=2;
    p=s;
    loopmove(p,steps);
    printf("%s\n",p);
}
 方法2:利用strcpy函数
#include<stdio.h>
#include<string.h>
#define max 100
void loopmove(char*pstr,int steps)
{
    char temp[max];
    int n=strlen(pstr)-steps;
    strcpy(temp,pstr+n);
    strcpy(temp+steps,pstr);
    *(temp+strlen(pstr))='\0';
    strcpy(pstr,temp);
}
void main()
{
    char *p,s[]="123456789";
    int steps=2;
    p=s;
    loopmove(p,steps);
    printf("%s\n",p);
}


原文链接:http://www.cnblogs.com/lpshou/


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值