C++面试,实现memcpy,strcpy这2个函数的功能
`strcpy`和`memcpy`都是用于内存复制的函数,但它们之间有几个关键的区别:
1. **复制的对象**:
- `strcpy`主要用于复制字符串,它将从源字符串的起始位置开始复制字符,直到遇到源字符串的空字符('\0'),然后将空字符也复制到目标字符串中,表示字符串的结束。
- `memcpy`则是通用的内存复制函数,它可以复制任意类型的数据,不仅限于字符串。它将源内存区域中的字节逐个复制到目标内存区域,不考虑空字符或其他特殊字符。
2. **参数类型**:
- `strcpy`的参数是`char*`类型的指针,用于操作字符串。
- `memcpy`的参数是`void*`类型的指针,可以用于操作任意类型的数据。
3. **结束标志**:
- `strcpy`在复制字符串时会自动在目标字符串的末尾添加空字符,以标识字符串的结束。
- `memcpy`不会在复制数据后添加任何结束标志,它只是简单地按字节复制数据。
4. **安全性**:
- `strcpy`不会检查目标内存区域是否足够大来容纳源字符串,如果目标内存区域不够大,可能会导致内存溢出的问题。
- `memcpy`不做任何大小检查,需要确保目标内存区域足够大来容纳源内存区域的数据,否则可能会导致内存溢出。
因此,如果要复制字符串,通常使用`strcpy`更方便和安全。而如果需要复制非字符串数据,或者需要更灵活地控制复制过程,可以使用`memcpy`。
memcpy 的实现:
#include <iostream> void* my_memcpy(void* destination, const void* source, size_t num) { // 强制类型转换为char*类型以实现字节级别的操作 char* dest = static_cast<char*>(destination); const char* src = static_cast<const char*>(source); // 使用循环逐字节复制数据 for (size_t i = 0; i < num; ++i) { dest[i] = src[i]; } return destination; } // 定义一个结构体类型 struct Person { int id; char name[20]; double salary; }; int main() { // 创建一个Person结构体对象 Person source = {123, "John Doe", 50000.0}; // 创建一个Person结构体对象作为目标 Person destination; // 使用自定义的my_memcpy函数拷贝结构体 my_memcpy(&destination, &source, sizeof(Person)); // 输出目标结构体的内容 std::cout << "ID: " << destination.id << std::endl; std::cout << "Name: " << destination.name << std::endl; std::cout << "Salary: " << destination.salary << std::endl; return 0; }
strcpy的实现:
#include <iostream> #include <stdlib.h> #include <string> #include <assert.h> using namespace std; char* strcpy(char* strDest, const char* strSrc) { assert(strDest != NULL && strSrc != NULL); const char* ptrSrc = strSrc; char* ptrDest = strDest; while (ptrSrc != NULL && *ptrSrc != '\0') { *ptrDest++ = *ptrSrc++; } *ptrDest = '\0'; return strDest; } int main() { char *strSrc = "Test string.何亮到此一游.20191102."; char *strDest = new char[strlen(strSrc) + 1]; strcpy(strDest, strSrc); cout << strDest << endl; cout << endl; system("pause"); return 0; }