前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C语言】超详解memset&&memcpy&&memmove&&memcmp的使⽤

【C语言】超详解memset&&memcpy&&memmove&&memcmp的使⽤

作者头像
学习起来吧
发布2024-05-11 08:13:08
870
发布2024-05-11 08:13:08
举报
文章被收录于专栏:学习C/++学习C/++

📝前言

库函数网址查询:https://legacy.cplusplus.com/reference/cstring/memcmp/ 库函数memsetmemcpymemmovememcmp都存在库函数<cstring> (string.h)中,使用需要使用#include <string.h>

🌠 memset

memset()是C语言中一个常用的标准库函数,它的作用是将一块内存区域的值设置为指定的值。 语法:

代码语言:javascript
复制
void * memset ( void * ptr, int value, size_t num );
str: 要设置的内存区域的起始地址。
value: 要设置的值,通常是一个无符号字符。
num: 要设置的字节数。

memset() 函数会将从 str 开始的 num 个字节的内存区域都设置为值 value。返回值是指向 str 的指针。 通常使用方法:

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

int main()
{
	char str[] = "almost very programmer should know memset!";
	memset(str, '-', 6);
	printf("%s\n", str);

	return 0;
}

我们使用memset()str数组前5个字符都设置为字符‘ - ’

  1. 初始化结构体:
代码语言:javascript
复制
typedef struct
{
	int id;
	char name[20];
	float score;
}Student;

int main()
{
	Student s;
	memset(&s, 0, sizeof(Student));
	printf("Student info:\n");
	printf("ID: %s\n", s.id);
	printf("Name: %s\n", s.name);
	printf("Score: %.2f\n", s.score);

	return 0;
}

,我们使用 memset()Student 结构体变量 s 的所有字段都初始化为 0。这样可以确保结构体中的所有成员都被初始化为默认值。

  1. 初始化动态分配的内存:
代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() 
{
    int *arr = (int *)malloc(10 * sizeof(int));
    memset(arr, 0, 10 * sizeof(int));

    for (int i = 0; i < 10; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n");

    free(arr);
    return 0;
}

我们动态分配了一个包含 10 个整数的数组,然后使用 memset() 将所有元素初始化为 0。这样可以确保数组中的所有元素都被初始化为默认值。

注意:memset() 函数通常用于初始化内存,而不是用于复制或移动内存区域。如果需要复制或移动内存区域,应该使用 memcpy()memmove() 函数。

🌉memcpy

memcpy() 是 C 语言中一个常用的标准库函数,它的作用是将一块内存区域的内容复制到另一块内存区域。 语法:

代码语言:javascript
复制
void *memcpy(void *dest, const void *src, size_t n);
dest: 目标内存区域的起始地址。
src: 源内存区域的起始地址。
n: 要复制的字节数。

memcpy() 函数会将从 src 开始的 n 个字节的内容复制到从 dest 开始的内存区域。返回值是指向 dest 的指针。 举个例子:

代码语言:javascript
复制
struct 
{
	char name[40];
	int age;
}person,person_copy;

int main()
{
	char myname[] = "Pierre de Fermat";
	memcpy(person.name, myname, strlen(myname) + 1);
	person.age = 88;

	memcpy(&person_copy, &person, sizeof(person));

	printf("person_copy: %s,%d\n", person_copy.name, person_copy.age);
	return 0;
}

memmove() 函数不同的是,memcpy() 函数不能处理源内存区域和目标内存区域重叠的情况。 如果源内存区域和目标内存区域重叠,并且是同一个字符串,可能会导致数据损坏。 因此,在处理可能重叠的内存区域时,应该使用 memmove() 函数。

代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

int main() 
{
    char buffer[10] = "abcdefghi";
    memcpy(buffer + 2, buffer, 5);
    printf("%s\n", buffer); 
    return 0;
}

🌉memmove

memmove() 是 C 语言中另一个常用的标准库函数,它的作用是将一块内存区域的内容复制到另一块内存区域memmove() 函数的定义:

代码语言:javascript
复制
void *memmove(void *dest, const void *src, size_t n);
dest: 目标内存区域的起始地址。
src: 源内存区域的起始地址。
n: 要复制的字节数。

memmove() 函数会将从 src 开始的 n 个字节的内容复制到从 dest 开始的内存区域。返回值是指向 dest 的指针。 示例:

代码语言:javascript
复制
int main()
{
	char buffer[10] = "abcdefghi";
	memmove(buffer + 2, buffer, 5);
	printf("%s\n", buffer);

	return 0;
}

我们使用 memmove()buffer 数组中从下标 0 开始的 5 个字节复制到从下标 2 开始的位置。这样可以实现将字符串向右移动 2 个位置的效果。

memcpy() 函数不同的是,memmove() 函数可以处理源内存区域和目标内存区域重叠的情况。这是因为 memmove() 函数会先将整个源内存区域复制到一个临时缓冲区,然后再从缓冲区复制到目标内存区域。这样可以避免在复制过程中出现数据损坏的问题。

🌠memcmp

memcmp() 是 C 语言中一个常用的标准库函数,它的作用是比较两块内存区域的内容。

代码语言:javascript
复制
int memcmp(const void *s1, const void *s2, size_t n);
s1: 要比较的第一块内存区域的起始地址。
s2: 要比较的第二块内存区域的起始地址。
n: 要比较的字节数。

memcmp() 函数会比较从 s1s2 开始的 n 个字节的内容 返回以下结果:

  • 如果两块内存区域的内容完全相同,返回 0
  • 如果第一个不同的字节在 s1 中的值小于 s2 中的值,返回一个负值。
  • 如果第一个不同的字节在 s1 中的值大于 s2 中的值,返回一个正值。
代码语言:javascript
复制
#include <stdio.h>
#include <string.h>

int main() 
{
    char buffer1[10] = "abcdef";
    char buffer2[10] = "abcdeG";
    int result = memcmp(buffer1, buffer2, 6);
    if (result < 0) 
    {
        printf("buffer1 is less than buffer2\n");
    } 
    else if (result > 0) 
    {
        printf("buffer1 is greater than buffer2\n");
    } 
    else 
    {
        printf("buffer1 is equal to buffer2\n");
    }
    return 0;
}

memcmp()strncmp() 函数都是用于比较字符串的函数,区别:

  1. 比较对象:
    • memcmp() 比较的是两块内存区域的内容,可以比较任意类型的数据。
    • strncmp() 比较的是两个以null字符结尾的字符串,只能比较字符串。
  2. 比较方式:
    • memcmp() 按字节比较,直到遇到第一个不同的字节或比较完指定的字节数。
    • strncmp() 按字符比较,直到遇到null字符或比较完指定的字符数。
  3. 返回值:
    • memcmp() 返回一个整数,表示比较结果。
    • strncmp() 返回一个整数,表示比较结果。
  4. 适用场景:
    • memcmp() 适用于需要比较任意类型数据的情况,如比较结构体、数组等。
    • strncmp() 适用于需要比较字符串的情况。

总结:memcmp() 更加底层和通用,可以用于比较任意类型的内存区域,而 strncmp() 则更适用于字符串比较的场景。在需要比较字符串时,使用 strncmp() 通常更加直观和方便。

例如比较结构体

代码语言:javascript
复制
typedef struct 
{
    int id;
    char name[20];
    float score;
} Student;

int main() 
{
    Student s1 = { 1, "Asen", 90.5 };
    Student s2 = { 1, "Asen", 90.5 };
    Student s3 = { 2, "Bob", 85.0 };

    // 比较 s1 和 s2
    if (memcmp(&s1, &s2, sizeof(Student)) == 0) 
    {
        printf("s1 and s2 are the same\n");
    }
    else 
    {
        printf("s1 and s2 are different\n");
    }

    // 比较 s1 和 s3
    if (memcmp(&s1, &s3, sizeof(Student)) == 0) 
    {
        printf("s1 and s3 are the same\n");
    }
    else 
    {
        printf("s1 and s3 are different\n");
    }

    return 0;
}

输出:

代码语言:javascript
复制
s1 and s2 are the same
s1 and s3 are different
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 📝前言
  • 🌠 memset
    • 🌉memcpy
      • 🌉memmove
      • 🌠memcmp
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档