非常经典的 C 语言面试题 ✅
strcpymemcpy 虽然都是“拷贝数据”的函数,但它们的用途、拷贝单位、终止条件、适用场景完全不同。下面是详细对比。


🧠 一、函数原型与定义

// 头文件:<string.h>

char *strcpy(char *dest, const char *src);
void *memcpy(void *dest, const void *src, size_t n);

📋 二、核心区别对比表

对比项 strcpy memcpy
功能 拷贝字符串 拷贝任意内存块
终止条件 遇到 \0 结束 拷贝指定字节数 n
参数类型 char* void*(可用于任意类型)
返回值 返回目标字符串首地址 返回目标内存首地址
是否拷贝 \0 会拷贝源字符串的 \0 不会自动拷贝 \0,除非计入 n
安全性风险 可能越界(若源字符串未以 \0 结尾) 需确保目标和源不重叠
适用场景 字符串操作 内存数据、结构体、数组、缓冲区
效率 较低(逐字节检测 \0 较高(按字节或字块直接复制)

🔍 三、举例说明

strcpy 示例(拷贝字符串)

#include <string.h>
#include <stdio.h>

int main() {
    char src[] = "hello";
    char dest[10];
    strcpy(dest, src);   // 自动拷贝包括 '\0'
    printf("%s\n", dest); // 输出: hello
    return 0;
}

⚠️ 若 src 没有 \0 结尾,strcpy 会一直读到非法内存区,造成 越界或段错误


memcpy 示例(拷贝任意数据)

#include <string.h>
#include <stdio.h>

int main() {
    int a[3] = {1, 2, 3};
    int b[3];
    memcpy(b, a, sizeof(a)); // 拷贝 12 字节(3个int)
    printf("%d %d %d\n", b[0], b[1], b[2]);
    return 0;
}

memcpy 只是单纯复制二进制内容,不关心数据类型或终止符。


🚫 四、常见错误与陷阱

❌ 错误示例 1:把 memcpystrcpy

char src[] = "hello";
char dest[10];
memcpy(dest, src, strlen(src)); // ❌ 忘记拷贝 '\0'
printf("%s", dest); // 输出乱码或崩溃

✅ 正确做法:

memcpy(dest, src, strlen(src) + 1); // +1 复制 '\0'

❌ 错误示例 2:目标和源内存重叠

char str[] = "abcdef";
memcpy(str + 2, str, 4); // ❌ 源和目标区域重叠,结果未定义

✅ 正确做法:

memmove(str + 2, str, 4); // 使用 memmove 处理重叠

⚙️ 五、内存层级差异

函数 操作粒度 检测终止符 可处理数据类型
strcpy 字符级 是 (\0) 仅字符字符串
memcpy 字节级 任意数据类型

✅ 六、面试回答总结模板

strcpy is used to copy a null-terminated string, and it stops when it meets '\0'.
It can only handle string data.

memcpy copies a fixed number of bytes, regardless of content, and can be used for any type of memory such as arrays or structures.
It’s faster but must ensure memory regions do not overlap.

In short, strcpy depends on '\0', while memcpy depends on n.


🧩 七、记忆口诀

🔹 strcpy → “string copy” → 以 \0 结尾
🔹 memcpy → “memory copy” → 按字节长度


并且:指针自加(如 p++)时,移动的字节数取决于指针所指向的数据类型,而不是固定的 4 个字节
同时对指针操作时要确保其已经初始化,否则为野指针,出现未定义行为。