库函数的模拟实现(memset、memcmp)

一、memset函数说明

还是贴上cplusplus的网址!

 函数总结:

  1. 功能:

    • memset函数将指定的值填充到内存块中。这个值被解释为无符号字符(unsigned char),并且连续地设置内存块的前num个字节。
  2. 参数:

    • ptr: 指向要填充的内存块的指针。
    • value: 要设置的值。虽然这个值以int类型传递,但实际填充时会将其转换为无符号字符。
    • num: 要设置的字节数,使用size_t类型,这是一个无符号整型。
  3. 返回值:

    • 函数返回ptr,即指向被填充内存块的原始指针。
  4. 特点:

    • memset通常用于初始化或清零内存区域。例如,它可以快速将一个结构体或数组的所有字节设置为0。
  5. 注意事项:

    • 由于memset操作很快,但它不检查内存对齐,因此在使用时需要注意目标内存的对齐要求。 

二、memset函数使用

#include <stdio.h>
#include <string.h> // 引入标准库中的字符串处理函数

int main() {
    char buffer[100]; // 定义一个字符数组,大小为100字节
    int value = 0; // 定义要填充的值,这里设置为0,用于清零

    // 使用memset函数将buffer数组的前50个字节设置为0
    // 参数1: 要填充的内存块的指针
    // 参数2: 要设置的值,这里传入0,对应无符号字符的0
    // 参数3: 要设置的字节数
    memset(buffer, value, 50);

    // 输出buffer数组的前几个字节,验证是否清零
    printf("First 10 bytes of buffer after memset:\n");
    for (int i = 0; i < 10; ++i) {
        printf("%d ", buffer[i]); // 打印数组的前10个字节
    }
    printf("\n");

    // 再次使用memset函数,这次将buffer数组的剩余50个字节设置为非0值,例如255
    memset(buffer + 50, 255, 50); // 从buffer的第51个字节开始设置

    // 输出buffer数组的全部100个字节,验证填充结果
    printf("All bytes of buffer after second memset:\n");
    for (int i = 0; i < 100; ++i) {
        printf("%d ", buffer[i]); // 打印整个数组的字节
    }
    printf("\n");

    return 0;
}

  

三、memset模拟实现

void* my_memset(void* ptr, int value, size_t num)
{
	assert(ptr);
	void* ret = ptr;
	while (num--)
	{
		*(char*)ptr = value;
		ptr = (char*)ptr + 1;
	}
	return ret;
}

用一个while循环,循环num次,每次设置一个字节,直至把num个字节的内容设置成参数value的值,返回指向内存块的指针ptr。我们来看看实现效果。 

  

四、memcmp函数说明

 函数总结: 

  1. 功能:

    • 比较两个内存块。memcmp函数比较由ptr1ptr2指向的内存块中的前num个字节。
  2. 参数:

    • ptr1: 指向第一个要比较的内存块的指针。
    • ptr2: 指向第二个要比较的内存块的指针。
    • num: 要比较的字节数。
  3. 返回值:

    • 如果两个内存块完全相同,返回0
    • 如果在比较的字节中,ptr1中的某个字节小于ptr2中的相应字节(以无符号字符值比较),返回一个负值。
    • 如果在比较的字节中,ptr1中的某个字节大于ptr2中的相应字节(以无符号字符值比较),返回一个正值。
  4. 特点:

    • strcmp函数不同,memcmp不会因为遇到空字符('\0')而停止比较,它会一直比较指定的num个字节。
  5. 注意事项:

    • 由于memcmp比较的是原始内存,它不会对数据进行任何解释或转换,只是简单地按字节比较。

五、memcmp函数使用

#include <stdio.h>
#include <string.h> // 引入标准库中的字符串处理函数

int main() {
    char str1[20] = "Hello World"; // 定义并初始化第一个字符串
    char str2[20] = "Hello rld"; // 定义并初始化第二个字符串
    size_t num = sizeof(str1) - 1; // 计算要比较的字节数,减1是为了排除字符串结束符'\0'

    // 使用memcmp函数比较str1和str2的前num个字节
    // 参数1: 第一个要比较的内存块的指针
    // 参数2: 第二个要比较的内存块的指针
    // 参数3: 要比较的字节数
    int result = memcmp(str1, str2, num);

    // 根据memcmp的返回值输出比较结果
    if (result == 0) {
        printf("str1 和 str2 在前 %zu 个字节内完全相同。\n", num);
    }
    else if (result < 0) {
        printf("str1 在比较的字节中某处小于 str2。\n");
    }
    else {
        printf("str1 在比较的字节中某处大于 str2。\n");
    }

    // 修改str2中的一个字符,然后再次进行比较
    str2[0] = 'h'; // 将str2的第一个字符改为小写

    // 再次使用memcmp函数比较修改后的str2和str1的前num个字节
    result = memcmp(str1, str2, num);

    // 输出新的比较结果
    if (result == 0) {
        printf("修改后的 str1 和 str2 在前 %zu 个字节内仍然相同。\n", num);
    }
    else {
        printf("修改后的 str1 和 str2 在前 %zu 个字节内不同。\n", num);
    }

    return 0;
}

   

六、memcmp模拟实现

#include <stdio.h>
#include <assert.h>
#include <stddef.h> // 包含size_t的定义

int my_memcmp(void* arr1, void* arr2, size_t num) {
    assert(arr1 && arr2); // 确保两个指针都不为空

    // 将void指针转换为char指针
    char* p1 = (char*)arr1;
    char* p2 = (char*)arr2;

    // 遍历num个字节
    for (size_t i = 0; i < num; ++i) {
        if (p1[i] != p2[i]) {
            // 如果当前字节不相同,返回两个字符的差值
            return (int)(p1[i] - p2[i]);
        }
    }

    // 如果所有比较的字节都相同,返回0
    return 0;
}

int main() {
    int arr1[] = { 1, 2, 3 };
    int arr2[] = { 1, 3, 3 };
    size_t num = sizeof(arr1); // 应该比较整个数组的大小

    // 调用自定义的my_memcmp函数,并传入正确的参数
    int ret = my_memcmp(arr1, arr2, num);

    // 输出比较结果
    printf("%d", ret);
    return 0;
}
  1. 自定义my_memcmp函数:

    int my_memcmp(void* arr1, void* arr2, size_t num) { assert(arr1 && arr2); // 确保传入的两个指针不为空

    my_memcmp函数接受三个参数:两个void类型的指针arr1arr2,以及一个size_t类型的num,表示要比较的字节数。

  2. 指针类型转换:

    char* p1 = (char*)arr1; char* p2 = (char*)arr2;

    将输入的void指针转换为char类型的指针,以便按字节访问内存。

  3. 内存比较循环:

    for (size_t i = 0; i < num; ++i) { if (p1[i] != p2[i]) { return (int)(p1[i] - p2[i]); } }

    使用for循环遍历num个字节。如果arr1arr2中的相应字节不相同,函数将返回两个字节的差值。如果差值是正数,表示arr1中的字节较大;如果是负数,表示arr2中的字节较大,如果所有比较的字节都相同,函数返回0

  4. main函数:

    int main() { int arr1[] = { 1, 2, 3 }; int arr2[] = { 1, 3, 3 }; size_t num = sizeof(arr1);

    main函数中定义了两个整型数组arr1arr2,并计算了arr1的大小(以字节为单位)。

  5. 调用my_memcmp函数:

    int ret = my_memcmp(arr1, arr2, num);

    调用my_memcmp函数,传入两个数组和它们的大小。

  6. 输出结果:

    使用printf函数输出my_memcmp函数的返回值。这个值将指示两个数组在比较的字节范围内是否相同,以及它们的第一个不同字节的大小关系。

本期内容到此结束,我们下期再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值