您的位置:首页 > 职场人生

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

2016-03-29 21:35 681 查看
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

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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  面试 字符串