Implementación de la función C/C++ strcpy()
El prototipo de la función strcpy() conocida es:
char * strcpy(char * strDest,const char * strSrc);
1. La función strcpy se implementa sin llamar a la función de biblioteca.
char* myStrcpy(cahr * dest, const char * src){
if(dest == nullptr || src == nullptr || dest == src){
return dest;
}
char * temp = dest;
while(*src != '\0'){
*dest++ = *src++;
}
*dest = *src; // 拷贝'\0'
return temp; // 返回原首地址
}
mejoramiento:
#include <assert.h>
char* myStrcpy(char * dest, const char * src){
assert(dest != nullptr && src != nullptr); // assert 断言,括号内为真时跳过,否则退出程序
if(dest == src) return dest;
char * temp = dest;
while(*dest++ = *src++){
// while((*dest++ = *src++) != '\0')
;
}
return temp; // 返回原首地址
}
2. Explique por qué se devuelve char *
Para que strcpy() implemente expresiones encadenadas , comoint length = strlen( strcpy( strDest, “hello world”) );
3. Considere el caso de la superposición de memoria.
Para strcpy, esta función no considera el problema de superposición de memoria , por ejemplo
char s[10] = "hello";
strcpy(s, s+1); // 返回ello
// strcpy(s+1, s); // 应返回 hhello,但实际会报错,因为 dest 与 src 重叠了,把'\0'覆盖了
La llamada superposición de memoria significa que la parte no procesada de src ha sido cubierta por destino, solo hay un caso:
src <= dest <= src + strlen(src)
es decir, la primera dirección del destino está en el medio del segmento de dirección de origen .
La función C memcpy tiene su propia función de detección de superposición de memoria. La implementación de memcpy my_memcpy se detalla a continuación. Cuando se detecta superposición de memoria, atraviesa y asigna valores de direcciones altas a direcciones; de lo contrario, asigna valores de direcciones bajas a Direcciones altas.
#include <assert.h>
#include <cstring>
#include <iostream>
using namespace std;
char* mymemcpy(char* dest, const char* src, int len){
// 内存复制,因此对于字符串,长度len应包含'\0'结束符
assert(dest != nullptr && src != nullptr);
if(dest == src) return dest;
char* temp = dest;
// 当检测到内存重叠时,从高地址开始往地址遍历赋值,否则从低地址到高地址赋值
if(dest > src && dest <= src + len - 1){
cout << "high to low addr" << endl;
dest = dest + len - 1; // 最高地址开始
src = src + len - 1;
while(len--){
*dest-- = *src--;
}
}else{
while(len--){
*dest++ = *src++;
}
}
return temp;
}
char* myStrcpy(char * dest, const char * src){
assert(dest != nullptr && src != nullptr); // assert 断言,括号内为真时跳过,否则退出程序
if(dest == src) return dest;
char * temp = dest;
// while(*dest++ = *src++){ // while((*dest++ = *src++) != '\0') // 不带重叠检测,从低到高地址复制
// ;
// }
mymemcpy(dest, src, strlen(src) + 1); // 带内存重叠检测,长度为 strlen(src) + 1
return temp; // 返回原首地址
}
int main(){
char s1[10] = "hello";
char s2[10] = "123";
cout << myStrcpy(s1 + 2, s1) << endl;
return 0;
}