strstr函数
实例
int main()
{
char arr1[20] = "abcdef";
char arr2[20] = "de";
char* ret = strstr(arr1, arr2);
if (ret == NULL)
printf("没有找到\n");
else
printf("找到了,匹配地址为%p\n", ret);
return 0;
strstr函数,传参为(查找字符串数组,匹配字符串数组),匹配不到查找值,返回空指针。匹配到字符串,返回首个匹配元素的地址。
注意:为全部匹配
实例复现
char* my_strstr(const char* str1,const char *str2)
{
assert(str1);
assert(str2);
char *s1=NULL;
char *s2=NULL;
char *cur=str1;
//如果子串一开始就是空,那么直接返回母串
if(*str2=='\0')
{
return *str1;
}
while(*cur!='\0')
{
s1=cur;
s2=str2;
while((*s1==*s2)&&*s1&&*s2)//s1和s2不能走到\0
{
s1++;
s2++;
}
if(*s2=='\0')
{
return cur;
}
cur++;
}
return NULL;
}
memcpy函数
内存拷贝函数,当操作对象不是字符串数组,比如整型数组时,字符串函数strcpy显然无法通过读取字符数组中的\0来实现对其他类型数组的操作,这时候可以考虑直接将内存中的数据拷贝到指定位置,使用memcpy函数。
其形式类似于strncpy函数。即复制指定字节的数据至dst数组内。
实例
int main()
{
int arr1[10] = { 1,2,3,4,5 };
int arr2[3] = { 3,6,9 };
int i = 0;
memcpy(arr1, arr2, sizeof(arr2));
for (i = 0; i < sizeof(arr1); i++)
{
printf("%5d", arr1[i]);
}
return 0;
}
结果
3 6 9 4 5 0 0 0 0 0-858993460-858993460-858993460-858993460-858993460-858993460 3 6 9
中间出现的随机值因为sizeof()操作符计算得40个字节,打印了40个字节的数据。超出数组范围了.
复现函数
void* my_memcpy(void* dest, void* src,size_t num)
{
void* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while (num--)
{
*(char*)dest = *(char*)src;
++(char*)dest;
++(char*)src;
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[5] = { 0 };
my_memcpy(arr2, arr1, (size_t)sizeof(arr1));
return 0;
}
错误示例
int main()
{
int arr1[10] = { 1,2,3,4,5 };
int arr2[5] = { 0 };
memcpy(arr1, (const void*)arr1[2], 12);
return 0;
}
报错
当强制转换arr1内某元素的地址数组为const void*,再通过函数memcpy进行同一数组的内部复制时会发生错误。
源数组传递的指针为const类型无法更改,而更改的就是已经在访问的数组,结果就是实参传递给型参时报错。
即使编译过去以后,变量也未发生改变。当源指针所指定的元素与目的地指针的元素发生冲突时,就会用到memmove函数。
memmove函数
memmove用于拷贝字节,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,但复制后源内容会被更改。
void *memmove(void *str1, const void *str2, size_t n)
从 str2 复制 n 个字符到 str1,但是在重叠内存块这方面,memmove() 是比 memcpy() 更安全的方法。如果目标区域和源区域有重叠的话,memmove() 能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中,复制后源区域的内容会被更改。如果目标区域与源区域没有重叠,则和 memcpy() 函数功能相同。
实例
int main()
{
int arr1[10] = { 1,2,3,4,5 };
int arr2[5] = { 0 };
int i;
memmove(arr1, arr1+2, 12);//步长为4字节,arr1+2即从第三个数开始,复制12个字节即三个元素
for (i = 0; i < sizeof(arr1) / sizeof(arr1[0]); i++)
{
printf("%5d",arr1[i]);
}
return 0;
}
结果
3 4 5 4 5 0 0 0 0 0
复现实例
void* my_memmove(void* dest, const void* sour, size_t num)
{
void* temp = dest;
assert(dest && sour);
char* dest1 = (char*)dest;
char* sour1 = (char*)sour;
//判断源地址和目标地址的大小,决定是倒序复制还是正序复制
if (dest1 > sour1)
{
//倒序复制
while (num--)
{
*(dest1 + num) = *(sour1 + num);
}
}
else if (dest1 < sour1)
{
//正序复制
while (num--)
{
*(dest1) = *(sour1);
dest1++;
sour1++;
}
}
return temp;
}
int main()
{
int arr1[10] = { 1,1,2,2,3,3,4,4,5,5 };
int i ;
my_memmove(arr1 + 2, arr1, 8);
return 0;
}
代码调试
标签:return,函数,memmove,int,void,day22,char,内存,arr1 From: https://blog.51cto.com/u_15862591/6002310