一、memset函数说明
还是贴上cplusplus的网址!
函数总结:
-
功能:
memset
函数将指定的值填充到内存块中。这个值被解释为无符号字符(unsigned char
),并且连续地设置内存块的前num
个字节。
-
参数:
ptr
: 指向要填充的内存块的指针。value
: 要设置的值。虽然这个值以int
类型传递,但实际填充时会将其转换为无符号字符。num
: 要设置的字节数,使用size_t
类型,这是一个无符号整型。
-
返回值:
- 函数返回
ptr
,即指向被填充内存块的原始指针。
- 函数返回
-
特点:
memset
通常用于初始化或清零内存区域。例如,它可以快速将一个结构体或数组的所有字节设置为0。
-
注意事项:
- 由于
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函数说明
函数总结:
-
功能:
- 比较两个内存块。
memcmp
函数比较由ptr1
和ptr2
指向的内存块中的前num
个字节。
- 比较两个内存块。
-
参数:
ptr1
: 指向第一个要比较的内存块的指针。ptr2
: 指向第二个要比较的内存块的指针。num
: 要比较的字节数。
-
返回值:
- 如果两个内存块完全相同,返回
0
。 - 如果在比较的字节中,
ptr1
中的某个字节小于ptr2
中的相应字节(以无符号字符值比较),返回一个负值。 - 如果在比较的字节中,
ptr1
中的某个字节大于ptr2
中的相应字节(以无符号字符值比较),返回一个正值。
- 如果两个内存块完全相同,返回
-
特点:
- 与
strcmp
函数不同,memcmp
不会因为遇到空字符('\0'
)而停止比较,它会一直比较指定的num
个字节。
- 与
-
注意事项:
- 由于
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;
}
-
自定义
my_memcmp
函数:int my_memcmp(void* arr1, void* arr2, size_t num) { assert(arr1 && arr2); // 确保传入的两个指针不为空
my_memcmp
函数接受三个参数:两个void
类型的指针arr1
和arr2
,以及一个size_t
类型的num
,表示要比较的字节数。 -
指针类型转换:
char* p1 = (char*)arr1; char* p2 = (char*)arr2;
将输入的
void
指针转换为char
类型的指针,以便按字节访问内存。 -
内存比较循环:
for (size_t i = 0; i < num; ++i) { if (p1[i] != p2[i]) { return (int)(p1[i] - p2[i]); } }
使用
for
循环遍历num
个字节。如果arr1
和arr2
中的相应字节不相同,函数将返回两个字节的差值。如果差值是正数,表示arr1
中的字节较大;如果是负数,表示arr2
中的字节较大,如果所有比较的字节都相同,函数返回0
。 -
main
函数:int main() { int arr1[] = { 1, 2, 3 }; int arr2[] = { 1, 3, 3 }; size_t num = sizeof(arr1);
在
main
函数中定义了两个整型数组arr1
和arr2
,并计算了arr1
的大小(以字节为单位)。 -
调用
my_memcmp
函数:int ret = my_memcmp(arr1, arr2, num);
调用
my_memcmp
函数,传入两个数组和它们的大小。 -
输出结果:
使用
printf
函数输出my_memcmp
函数的返回值。这个值将指示两个数组在比较的字节范围内是否相同,以及它们的第一个不同字节的大小关系。
本期内容到此结束,我们下期再见!