C语言第15讲:C语言内存函数
1. memcpy
使用和模拟实现
1.1 函数定义
void * memcpy(void *dest, const void *src, size_t n);
1.2 功能
将源内存块 src
的前 n
个字节复制到目标内存块 dest
。
1.3 注意事项
- 目标区域与源区域不能重叠。若存在重叠,应使用
memmove
。 - 这个函数在遇到
'\0'
的时候并不会停下来。 - 返回值:返回
dest
指针。
1.4 示例代码
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "Hello, World!";
char dest[20];
memcpy(dest, src, strlen(src) + 1); // 复制包括结束符'\0'
printf("Copied string: %s\n", dest);
return 0;
}
输出:
Copied string: Hello, World!
1.5 模拟实现
void * memcpy ( void * dst, const void * src, size_t count)
{
void * ret = dst;
assert(dst);
assert(src);
/*
* copy from lower addresses to higher addresses
*/
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
return(ret);
}
2. memmove
使用和模拟实现
2.1 函数定义
void *memmove(void *dest, const void *src, size_t n);
2.2 功能
与 memcpy
类似,但支持 重叠区域 的安全复制。
2.3 注意事项
- 当
dest
和src
有重叠时,确保数据不会被破坏。 - 返回值:返回
dest
指针。
2.4 示例代码
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "abcdef";
memmove(str + 2, str, 4); // 将前4个字符移动到位置2开始
printf("After memmove: %s\n", str); // 输出 "ababcd"
return 0;
}
输出:
After memmove: ababcd
2.5 模拟实现
void * memmove ( void * dst, const void * src, size_t count)
{
void * ret = dst;
if (dst <= src || (char *)dst >= ((char *)src + count))
{
/*
* Non-Overlapping Buffers
* copy from lower addresses to higher addresses
*/
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
}
else
{
/*
* Overlapping Buffers
* copy from higher addresses to lower addresses
*/
dst = (char *)dst + count - 1;
src = (char *)src + count - 1;
while (count--)
{
*(char *)dst = *(char *)src;
dst = (char *)dst - 1;
src = (char *)src - 1;
}
}
return(ret);
}
3. memset
函数的使用
3.1 函数定义
void * memset(void *s, int c, size_t n);
3.2 功能
将内存块 s
的前 n
个字节设置为值 c
(以无符号字符解释)。
3.3 注意事项
- 通常用于初始化内存或清零操作。
- 返回值:返回
s
指针。
3.4 示例代码
#include <stdio.h>
#include <string.h>
int main() {
char buffer[10];
memset(buffer, '*', sizeof(buffer) - 1); // 用'*'填充
buffer[9] = '\0'; // 添加字符串结束符
printf("Buffer: %s\n", buffer);
return 0;
}
输出:
Buffer: *********
3.5 模拟实现
void *my_memset(void *s, int c, size_t n) {
unsigned char *p = (unsigned char *)s;
int i;
for (i = 0; i < n; i++) {
p[i] = (unsigned char)c;
}
return s;
}
4. memcmp
函数的使用
4.1 函数定义
int memcmp(const void *s1, const void *s2, size_t n);
4.2 功能
比较两块内存的前 n
个字节。
- 返回值:
0
:两块内存相等。<0
:s1
小于s2
。>0
:s1
大于s2
。
4.3 注意事项
- 按字节逐一比较。
- 常用于比较数组或内存块。
4.4 示例代码
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "abcdef";
char str2[] = "abcdeg";
int result = memcmp(str1, str2, 6);
if (result == 0) {
printf("str1 and str2 are equal.\n");
} else if (result < 0) {
printf("str1 is less than str2.\n");
} else {
printf("str1 is greater than str2.\n");
}
return 0;
}
输出:
str1 is less than str2.
4.5 模拟实现
int my_memcmp(const void *s1, const void *s2, size_t n) {
const unsigned char *p1 = (const unsigned char *)s1;
const unsigned char *p2 = (const unsigned char *)s2;
int i;
for (i = 0; i < n; i++)
{
if (p1[i] != p2[i]) {
return p1[i] - p2[i];
}
}
return 0;
}
5. 总结
memcpy
:高效复制,但不支持重叠区域。memmove
:支持重叠区域复制。memset
:初始化或设置内存。memcmp
:比较两块内存的内容。
以上函数均以字节为单位操作,灵活且高效。在实际开发中,注意确保指针合法性和内存边界,以避免未定义行为。
—完—