首页 > 系统相关 >字符串函数与内存函数(day22)

字符串函数与内存函数(day22)

时间:2023-01-11 16:07:50浏览次数:35  
标签:return 函数 memmove int void day22 char 内存 arr1

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函数。

字符串函数与内存函数(day22)_数组

其形式类似于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个字节的数据。超出数组范围了.

字符串函数与内存函数(day22)_字符串数组_02

字符串函数与内存函数(day22)_数组_03

字符串函数与内存函数(day22)_字符串数组_04

字符串函数与内存函数(day22)_数组_05

字符串函数与内存函数(day22)_数据_06

复现函数

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;
}

报错

字符串函数与内存函数(day22)_数据_07

当强制转换arr1内某元素的地址数组为const void*,再通过函数memcpy进行同一数组的内部复制时会发生错误。

源数组传递的指针为const类型无法更改,而更改的就是已经在访问的数组,结果就是实参传递给型参时报错。

字符串函数与内存函数(day22)_字符串数组_08

即使编译过去以后,变量也未发生改变。当源指针所指定的元素与目的地指针的元素发生冲突时,就会用到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;
}

代码调试

字符串函数与内存函数(day22)_数据_09

字符串函数与内存函数(day22)_数组_10

字符串函数与内存函数(day22)_数据_11

标签:return,函数,memmove,int,void,day22,char,内存,arr1
From: https://blog.51cto.com/u_15862591/6002310

相关文章

  • 剑指 Offer 30. 包含min函数的栈
    剑指Offer30.包含min函数的栈定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数在该栈中,调用min、push及pop的时间复杂度都是O(1)。 示......
  • C++构造函数【cherno课程学习】
    C++构造函数无参构造函数首先创造一个Entity类,在类里面有两个变量x,y以及一个方法#include<iostream>classEntity{public:floatX,Y;voidPrint(){......
  • 蹦床函数实现深度递归的深拷贝;递归改循环,避免栈溢出
    1、先写蹦床函数——可以将递归转为循环执行点击查看代码//蹦床函数functiontoc(func){letargsArr=[];letactive=false;returnfunction(){ar......
  • cmake常用函数记录
    由于cmake我一般是项目移植的时候,才会涉及到,一些常用函数隔一段时间就会忘记,所以在此做一下笔记,以便日后查看。1、添加链接库所在的目录: link_directories("./libs")......
  • Java8常见函数式接口总结
    函数式接口函数式接口:有且仅有一个抽象方法的接口。使用@FunctionalInterface注解来标记。如果接口不是函数式接口就会编译出错满足条件的接口即使不加上注解,那也是函......
  • jQuery核心函数之选择器(表单选择器)
    视频表提交的是value。<!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>08_表单选择器</title></head><body><form>用户名:<inputtype="t......
  • jQuery核心函数之选择器(练习表格隔行变色)
    视频行号从0开始。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><title>01__表格隔行变色</title><style>div,span,p{widt......
  • jQuery核心函数之选择器(过滤选择器)
    视频过滤选择器的执行有先后顺序。<!DOCTYPEhtml><html><head><metacharset="UTF-8"><title>07_过滤选择器</title></head><body><divid="div1"clas......
  • 从自定义的库函数到STM32官方标准库
      在​​上一节​​的基础上,进一步改写代码,再引入官方标注库函数。虽然官方标准库慢慢式微,有一些别的库可能会取代它,但是并不妨碍我们继续拿官方库来写代码,吸取里边好的写......
  • 消息服务 + Serverless 函数计算如何助力企业降本提效?
    作者|柳下背景介绍消息队列服务(下文均以MessageService命名)作为云计算PaaS领域的基础设施之一,其高并发、削峰填谷的特性愈发受到开发者关注。MessageService对......