建议可以先看一下往期的字符串函数,里面有些东西提到了,我在本期就没有提到。
目录
1、内存拷贝1——memcpy
要点:
1、函数memcpy从src的位置开始向后复制count个字节的数据到dest的内存位置
2、这个函数在遇到'\0'的时候并不会停下来
3、如果src和dest有任何的重叠,复制的结果都是未定义的
函数返回的是dest的起始地址
memcpy函数是不用来处理重叠的内存之间的数据的拷贝(但VS编译器下是可以的)
使用:
int main()
{
int a[20] = { 1,2,3,4,5,6,7,8,9 ,10};
int b[5] = { 6,7,8,9,10 };
int i = 0;
memcpy(a, b, 3*4);
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
模拟:
void* my_memcpy(void* dest, const void* sur,size_t count)
{
assert(dest && sur);
void* s = dest;
while (count--)
{
*(char*)dest = *(char*)sur;
dest = (char*)dest + 1;
sur = (char*)sur + 1;
}
return s;
}
int main()
{
int a[20] = { 1,2,3,4,5,6,7,8,9,10 };
int b[5] = { 6,7,8,9,10 };
int i = 0;
my_memcpy(a, b, 3*4);
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
分析:
1、为什么用void*接收?
拷贝内存里的内容到另一块内存中去,我们是无法得知内存中的内容是字符串还是整型或者是其他类型,我们无法得知,所以采用泛型的指针void*来接收
2、assert干嘛用?
——保证指针的有效性
3、为什么在复制时还要强制类型转换?
因为我们无法预知dest和src的指针类型,而我们又要满足各类数据的复制,因此我们把复制时的内容压到最小(char)。为什么?在这里我们复制的内容是整型,我们大可以直接强制类型转换为int类型的,复制更快,但是如果我们要复制的是char类型的呢?你一次复制了int的四个字节,那我们的char只需要复制一个字节呀,这是不是就会乱套了。所以我们得把力度放到最小,如果是int的,大不了多复制几次呗!
4、指针s作用?
这个函数返回的是dest的起始位置,我们在复制时改变了dest的指向,所以采用s来记住其起始位置
2、内存拷贝2——memmove
使用memmove函数来实现重叠内存之间的数据拷贝
使用:
int main()
{
int a[20] = { 1,2,3,4,5,6,7,8,9 ,10};
int i = 0;
memmove(a+3, a, 3*4);
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
模拟·:
void* my_memmove(void* dest, const void* sur,size_t count)
{
assert(dest && sur);
void* s = dest;
//从前往后
if (dest < sur)
{
while (count--)
{
*(char*)dest = *(char*)sur;
dest = (char*)dest + 1;
sur = (char*)sur + 1;
}
}
//从后往前
else
{
while (count--)
{
*((char*)dest + count) = *((char*)sur + count);
}
}
return s;
}
int main()
{
int a[20] = { 1,2,3,4,5,6,7,8,9 ,10 };
int i = 0;
my_memmove(a + 3, a, 3 * 4);
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
为什么分两种情况(从前往后,从后往前)?
想一想,如果和memcpy一样的话,那它存在的价值在哪儿呢?在于,memmove可以用来处理重叠内存的数据拷贝。
如果和memcpy就会出现上述问题,因此出现了memmove来优化了它。
想一想,上述情况下,我们怎么复制合适呢?
对,采用从后往前复制就可以啦!
情况划分:
3、内存设置——memset
使用:
int main()
{
char a[10] = { 0 };
memset(a, 3, 10);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
注意:我们是将每个字节都初始化为int c,所以,在使用处理整型时,一定要小心,
错误示范:
因为int是四个字节,他将4个字节都变成了1,自然输出就不是预期结果了
模拟:
void* my_memset(void*dest, int c, size_t count)
{
assert(dest);
void* ret = dest;
while (count--)
{
*((char*)dest) = c;
dest=((char*)dest)+1;
}
return ret;
}
int main()
{
char a[10] = { 0 };
my_memset(a, 3, 10);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
4、内存比较——memcmp
使用:类似于strcmp,上一期有详细讲解:http://t.csdn.cn/lEz2d
int main()
{
int a1[] = {1,2,3,4,5};
int a2[] = { 1,2,3,6,7 };
int ret = memcmp(a1, a2);
printf("%d\n", ret);
return 0;
}
模拟:
int my_memcmp(const void* str1, const void* str2,size_t count)
{
assert(str1 && str2);
while (*(char*)str1 == *(char*)str2)
{
count--;
str1=(char*)str1+1;
str2=(char*)str2+1;
if (count == 0)
break;
}
return *(char*)str1 - *(char*)str2;
}
int main()
{
int a1[] = { 1,2,3,5,5 };
int a2[] = { 1,2,3,4,7 };
int ret = my_memcmp(a1, a2,24);
if (ret > 0)
printf(">");
else if (ret == 0)
printf("=");
else
printf("<");
return 0;
}
结束啦!如果有不太理解的地方,去看看上一期,应该就会解决的。