1、memcpy、memmove、memset源码
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);
#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/