目录
字符(串)函数可以专门对字符或字符串操作,同时,若要对其他类型数据进行这些操作,就可以借助内存函数直接对内存操作,接下来介绍的几个内存函数就是极其常用的。
memcpy函数
- void* memcpy( void* destination , const void* source, size_t num);
- 从source的位置开始拷贝numge个字节的数据到destination的内存位置;
- 所有类型的数据都可以拷贝,所以返回值是void* 类型;
- 遇到 ' \0 ' 的时候不会停下来;
- 对自己内容的一部分拷贝给自己是无效的;
使用实例:
#include<stdio.h>
#include<string.h>
int main()
{
int source[10] = { 1,2,3,4,5,6,7,8,9,10 };
int destination[5] = { 0 };
memcpy(destination, source, 5 * sizeof(int));
return 0;
}
模拟实现:
关键思路:
既然返回类型和形参类型都是void* ,那对于不同的类型数据怎么保证全部拷贝呢?
可以强转为char*型,这样就可以不放过每个字节对应的数据了;
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memcpy(void* destination, const void* source, size_t num)
{
assert(destination && source);
void* start = destination;
while (num--)
{
*((char*)destination)++ = *((char*)source)++;
}
//warning C4716 : “my_memcpy”: 必须返回一个值
return start;
}
int main()
{
int source[10] = { 1,2,3,4,5,6,7,8,9,10 };
int destination[5] = { 0 };
my_memcpy(destination, source, 5 * sizeof(int));
for (int i = 0; i < 5; i++)
{
printf("%d ", destination[i]);
}
return 0;
}
注意点:
memmove函数
- void * memmove ( void * destination, const void * source, size_t num );
和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的; 如果源空间和目标空间出现重叠,就得使用 memmove 函数处理。
使用实例:
对于上述第二点:
模拟实现:
关于该函数的模拟实现也就有的研究了。
比如:对于数组arr自身要实现移动:必须考虑数据覆盖问题
如果要移动的数据的起始位置在目标位置之前:就应该依次先移动最后面的数据(从后往前);
如果要移动的数据的起始位置在目标位置之后:就应该依次先移动前面的数据(从前往后);
秘诀:其实就是从它们相交的位置开始移动
#include<stdio.h>
#include<string.h>
#include<assert.h>
void* my_memmove(void* destination, const void* source, size_t num)
{
assert(destination && source);
void* ret = destination;
//前 -> 后
//dest < src
if (destination < source)
{
while (num--)
{
*(char*)destination = *(char*)source;
destination = (char*)destination + 1;
source = (char*)source + 1;
}
}
//后 -> 前
//dest > src
else
{
while (num--)
{
*((char*)destination + num) = *((char*)source + num);
}
}
return ret;
}
int main()
{
int source[10] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(source, source + 5, 5 * sizeof(int));
return 0;
}
memcmp函数
- int memcmp ( const void * ptr1, const void * ptr2, size_t num );
- 比较ptr1和ptr2各自后面num个字节的数据是否相同;
- 先遇到谁的小谁的就小;
- 特点:可以作用于任何类型的数据;
- 返回值:
使用实例:
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[5] = { 1,2,3,4,5 };
int arr2[5] = { 1,2,3,3,5 };
int ret = memcmp(arr1, arr2, 5 * sizeof(int));
printf("%d\n", ret);
return 0;
}
模拟实现:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_memcmp(const void* ptr1, const void* ptr2, size_t num)
{
assert(ptr1 && ptr2);
int ret = 0;
while (num--)
{
ret = *((char*)ptr1) - *((char*)ptr2);
ptr1 = (char*)ptr1 + 1;
ptr2 = (char*)ptr2 + 1;
if (ret != 0)
{
return ret;
}
}
return 0;
}
int main()
{
int arr1[5] = { 1,2,3,4,5 };
int arr2[5] = { 1,2,3,3,5 };
int ret = my_memcmp(arr1, arr2, 5 * sizeof(int));
printf("%d\n", ret);
return 0;
}
memset函数
- Sets buffers to a specified character.
- void *memset( void *dest, int value, size_t count );
Return Value :memset returns the value of dest.
使用实例:
#include<stdio.h>
#include<string.h>
int main()
{
char arr[20] = { "hello world" };
memset(arr + 6, 'x', 6 * sizeof(char));
return 0;
}
注意:
memset函数的赋值是按照字节为单位的(见下图4),赋值1,实则是在内存中全部放了0x010101010101....... 这个数刚好是10进制的16843009
因此:该函数不能对整形数组赋除 0 和 -1 之外的数;
本文含有隐藏内容,请 开通VIP 后查看