下面对一些常见的关于字符的库函数进行实现,这些也是通常面试中所问的一些问题,需要注意的是有些看起来很简单,但是一定要考虑一些边界条件,否则很容易出错.
char* strcpy(char* dst,const char* src){
if(dst== nullptr||src== nullptr) //注意边界条件
return nullptr;
char* pdst =dst;
const char* psrc = src;
while(*psrc!='\0') { //这里不能写成psrc!='\0'
*pdst++ = *psrc++;
}
*pdst = '\0'; //注意结尾
return dst;
}
char* strncpy(char* dst,const char* src,size_t count) {
if(dst== nullptr||src== nullptr||count<=0)
return dst;
char* pdst =dst;
const char* psrc = src;
while(count--&&*psrc!='\0') {
*pdst++ = *psrc++;
}
*pdst = '\0'; //注意
return dst;
}
上述的两个关于拷贝的函数都有问题–其没有考虑到内存的重叠的问题,因此会有下面一个函数作为代替.
void* memmove(void *dst,const void *src,size_t n) {
//判断合法性
if (dst == NULL || src == NULL)
return NULL;
char* pdst = (char*)dst; //强制转换成char*
const char* psrc=(const char*)src;
//防止内存重叠的处理
if (pdstfor (size_t i = 0;ielse { //从后往前
pdst += n-1;
psrc += n-1;
for (size_t i = 0;i'\0';
return dst;
}
最常见的库函数了,下面是一种实现的方式
size_t mystrlen(const char* src) {
if(src== nullptr) return 0;
size_t count=0;
while(*src!='\0') {
src++;
count++;
}
return count;
}
这个函数是非常容易出错的,因为它是以字节为单位进行初始化的,因此如果对与int等别的类型进行初始化的时候要非常小心.
//其函数的形式就是标准的库函数形式
void* mymemset(void* src,int ch,size_t n){ //注意函数的形式
if(src== nullptr)
return src;
char* psrc = (char*)src;
while(n--){
*psrc++ = static_cast<char>(ch);
}
return src;
}
下面对上述的函数进行测试,看出其不同的地方:
#include
using namespace std;
char* strcpy(char* dst,const char* src){
if(dst== nullptr||src== nullptr)
return nullptr;
char* pdst =dst;
const char* psrc = src;
while(*psrc!='\0') {
*pdst++ = *psrc++;
}
*pdst = '\0';
return dst;
}
char* strncpy(char* dst,const char* src,size_t count) {
if(dst== nullptr||src== nullptr||count<=0)
return dst;
char* pdst =dst;
const char* psrc = src;
while(count--&&*psrc!='\0') {
*pdst++ = *psrc++;
}
*pdst = '\0';
return dst;
}
void* memmove(void *dst,const void *src,size_t n) {
//判断合法性
if (dst == NULL || src == NULL)
return NULL;
char* pdst = (char*)dst;
const char* psrc=(const char*)src;
//防止内存重叠的处理
if (pdstfor (size_t i = 0;ielse {
pdst += n-1;
psrc += n-1;
for (size_t i = 0;i'\0';
return dst;
}
size_t mystrlen(const char* src) {
if(src== nullptr) return 0;
size_t count=0;
while(*src!='\0') {
src++;
count++;
}
return count;
}
void* mymemset(void* src,int ch,size_t n){
if(src== nullptr)
return src;
char* psrc = (char*)src;
while(n--){
*psrc++ = static_cast<char>(ch);
}
return src;
}
int main() {
//两种情况会不同...有内存的重叠
char c1[]="hello,world";
char c2[]="hello,world";
memmove(c2+6,c2+5,5);
strncpy(c1+6,c1+5,5);
cout<cout<////////////////////////
char t[]="12345";
cout<//5
cout<<sizeof(t)<//6 , have '\0'
char* t1 ="12345";
cout<<sizeof(t1)<//8 ,pointer,64 machine
cout<//5
///////////////////////注意memeset函数的用法
char buf[10];
mymemset(buf,'1',sizeof(buf));
for(int i=0;i<sizeof(buf);i++)
cout<" ";
cout<int buf1[10];
mymemset(buf1,1,sizeof(buf1));
cout<<sizeof(buf1)<for(int i=0;i<sizeof(buf1)/sizeof(int);i++)
cout<" ";
cout<return 0;
}
…………to be continue