首页 > 系统相关 >字符串函数与内存函数的使用和模拟实现

字符串函数与内存函数的使用和模拟实现

时间:2024-03-16 15:31:06浏览次数:13  
标签:src 函数 dest char int num 内存 字符串 include

前言:

字符函数与内存函数的优劣:

字符函数如果处理字符相关的数据的话,用起来比较方便。相较于字符串函数,内存函数可以处理除字符外的其他类型的数据。

目录

1.字符串函数

1.1 strcpy

1.2 strcmp

1.3 strcat

 1.4 strncpy   strncmp  strncat

2.内存函数

2.1 memcpy 

2.2 memmove

1.字符串函数

1.1 strcpy

介绍:

将 source 中的字符数据覆盖式(将'\0'拷贝到destion中)的拷贝到 destion中,并返回 destion 的字符串的首地址。

模拟实现:

#include <assert.h>
#include <stdio.h>
char* my_strcpy(char* dest, const char* src)
{
    //断言防止dest和src为空指针
	assert(dest != NULL && src != NULL);
	char* tmp = dest;
    // * 的优先级高 ,所以先解引用在++,直到src将'\0'赋值给dest
	while (*dest++ = *src++)
	{
		;
	}
	return tmp;
}
int main()
{
	char s1[100];
	char* s2 = "hello world!";
	char *ret = my_strcpy(s1, s2);
	printf("%s\n", ret);
}

1.2 strcmp

介绍:

比较字符串的大小,就是一个一个的字符的比较。

注意:返回值,如果

str1>str2 ,则返回大于0的数;

str1<str2,则返回小于0的数;

str1=str2,则返回0。

 模拟实现:

#include <stdio.h>
#include <assert.h>
int my_strcmp(const char* dest, const char* src)
{
    assert(dest&&src);
    //当dest与src不同时,跳出循环
	while (*dest == *src)
	{   
        //这时dest与src相同,并且都是'\0'
		if (*dest == '\0')
			return 0;
		dest++;
		src++;
	}
	return *dest - *src;
}
int main()
{
	char s1[10] = "abcef";
	char s2[10] = "abcef";
	int ret = my_strcmp(s1, s2);
	if (ret == 0)
		printf("s1=s2");
	else if (ret > 0)
		printf("s1>s2");
	else
		printf("s1<s2");
	return 0;
}

1.3 strcat

介绍:

在 destion 所指向的字符串后,追加 source 所指向的字符串。 

模拟实现:

#include <stdio.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
	assert(dest && src);
	char* tmp = dest;
    //通过while循环是dest指向'\0'
	while (*dest != '\0')
		dest++;
    //将src拷贝到dest'\0'之后的位置
	while (*dest++ = *src++)
	{
		;
	}
	return tmp;
}
int main()
{
	char s1[20] = "hello ";
	char* s2 = "world!";
	char *ret = my_strcat(s1, s2);
	printf("%s", ret);
	return 0;
}

 1.4 strncpy   strncmp  strncat

介绍:

相较于前面的函数,就多了个参数 num(决定你要拷贝,比较或追加多少字节)

注意:num的单位是字节 

接下来就只附实现代码喽。

 

模拟实现:

strncpy:

#include <assert.h>
#include <stdio.h>
char* my_strncpy(char* dest, const char* src,size_t num)
{
	assert(dest != NULL && src != NULL);
	int i = 0;
    //若i<num时,src[i]是'\0',则直接跳出循环,后面的就不拷贝了
	for (i = 0; src[i]!='\0'&&i < num; i++)
	{
		dest[i] = src[i];
	}
    //一定要在dest拷贝完的结尾加上'\0'
    if(i<num)//也可以不判断,若不判断就是覆盖式拷贝
	    dest[i] = '\0';
	return  dest;
}
int main()
{
	char s1[100] = "I don't know";
	char* s2 = "hello world!";
	char *ret = my_strncpy(s1, s2,5);
	printf("%s\n", ret);
}

strncmp:

#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* dest, const char* src,size_t num)
{
	assert(dest && src);
	int i = 0;
	for (i = 0; i < num; i++)
	{
        //如果不相同返回
		if (dest[i] != src[i])
			return dest[i] - src[i];
	}
	return 0;
}


int main()
{
	char s1[10] = "abcef";
	char s2[10] = "abdef";
	int ret = my_strncmp(s1, s2, 2);
	if (ret == 0)
		printf("s1=s2");
	else if (ret > 0)
		printf("s1>s2");
	else
		printf("s1<s2");
	return 0;
}

 strncat:

#include <stdio.h>
#include <assert.h>
char* my_strncat(char* dest, const char* src,size_t num)
{
	assert(dest && src);
	char* tmp = dest;
    //通过while循环使dest指向字符串结束标志'\0'
	while (*dest != '\0')
		dest++;
	int i = 0;
	for (i = 0; i < num; i++)
	{
		dest[i] = src[i];
	}
    //最后追加完,在字符串末尾加上'\0'
	dest[i] = '\0';
	return tmp;
}
int main()
{
	char s1[20] = "hello ";
	char* s2 = "world!";
	char *ret = my_strncat(s1, s2 , 3);
	printf("%s", ret);
	return 0;
}

2.内存函数

2.1 memcpy 

介绍:

跟strcpy差不多,这里就不多介绍了,但注意以下两点

1.memcpy 可以拷贝 除字符串外的其他类型的数据

2.memcpy 不可以重叠的拷贝,重叠拷贝就是将自己的一部分拷贝给自己,但库里给的函数可以实现。

模拟实现:

#include <stdio.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	while (num--)
	{
        //使用void* 的指针需要强制类型转换
		*((char*)dest + num) = *((char*)src + num);
	}
	return dest;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr1[10] = { 0 };
	my_memcpy(arr1, arr, 20);
	for (int i = 0; i < 10; i++)
		printf("%d ", arr1[i]);
	return 0;
}

2.2 memmove

敲黑板楼,这里是重点。

简介:

就是将 src 中 num 个字节的数据拷贝到 src中,与memcmp 相比 ,它可以实现重叠拷贝。

实现思路:(主要讲重叠拷贝的思路)若不重叠怎么拷贝都可以。

dest <src:从前往后拷贝

dest = src :从前往后或从后往前都可以

dest>src:从后往前拷贝

情况1:(dest>src)图解

情况2:(dest<src)

 模拟实现:

#include <stdio.h>
#include <assert.h>
void* my_memmove(void* dest,const void* src, size_t num)
{
    assert(dest&&src);
    //从前往后拷贝
	if (dest < src)
	{
		for (int i = 0; i < num; i++)
		{
			*((char*)dest + i) = *((char*)src + i);
		}
	}
    //从后往前拷贝
	else
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	return dest;
}
int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr + 2, arr, 20);
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

还有memset    memcmp等这里就不多介绍了。

结语:

头回写这么多,希望自己能继续坚持。

祝愿大家c语言能越学越好。 

标签:src,函数,dest,char,int,num,内存,字符串,include
From: https://blog.csdn.net/2402_82658387/article/details/136752713

相关文章

  • kubernetes中的内存表示单位Mi和M的区别
    官网解释:Meaningofmemory,Mi表示(1Mi=1024x1024),M表示(1M=1000x1000)(其它单位类推,如Ki/KGi/G)创建两个pod,一个申请1Mi,另一个申请1MTRANSLATEwithxEnglishArabicHebrewPolishBulgarianHindiPortugueseCatalanHmongDawRomanianChines......
  • 代码随想录算法训练营第十一天| 20. 有效的括号 1047. 删除字符串中的所有相邻重复
    20.有效的括号https://leetcode.cn/problems/valid-parentheses/description/publicbooleanisValid(Strings){if(s==null)returntrue;Stack<Character>stack=newStack<>();for(inti=0;i<s.length();i++){......
  • 滴水逆向笔记系列-c++总结2-36.权限控制-37.虚函数-38.多态_绑定
    第三十六课c++3权限控制1.定义和实现分开写2.private和publicprivate权限说明私有变量在类外是无法访问的,只有在类内或者使用类内函数访问类内函数访问3.private真的不能访问吗反汇编看看t对象在初始化public和private成员时都是一视同仁的,在底层还是没区别,都是编......
  • 【C++函数速查】lower_bound和upper_bound使用方法详细解读
    文章目录1)概述2)函数使用3)案例代码1)概述lower_......
  • 结构体三种实例化方法(含成员函数)
    结构体成员函数三种实例化方法结构体成员函数需要定义成指针函数,定义函数,但不在结构体内实现方法,在外部(需要在函数体内部实现)结构体指针使用->符号访问结构体直接实例化使用.符号访问成员第一种:结构体直接实例化#include<stdio.h>//在此初始化结构体,内部成......
  • C++函数调用优化
    C++函数调用优化施磊老师网课笔记截图1、用临时对象拷贝构造一个新对象的时候,编译器会对其优化,直接用生成临时对象的方法构造新对象;......
  • C++ Function Templates (函数模板)
    C++FunctionTemplates[函数模板]1.TemplatesandGenericProgramming(模板与泛型编程)2.DefiningaFunctionTemplates(定义函数模板)2.1.InstantiatingaFunctionTemplate(实例化函数模板)2.2.TemplateTypeParameters(模板类型参数)2.3.Non......
  • KMP字符串(解释+例题)
    题目描述:  思路: 数据结构KMP算法配图详解(超详细)_kmp算法流程图-CSDN博客AcWing831.字符串查找---用16幅图从暴力一步步优化到KMP-AcWing推荐以上两篇大佬的文章kmp算法步骤(p子串和s串下标从1开始):1、kmp匹配过程首先需要了解什么是前缀和后缀(只针对p子串去......
  • 20240315,逻辑类型,条件和逗号,函数,数组
    刚好看到逻辑类型,今天早上有个很好玩的事情,一早上醒来圆圆的小狗跑到了床下,然后她说“你是不是打我的小狗了”我;”我没有,我什么都不知道””他的屁股都扁了“我:“我怎么知道,他的屁股扁了关我什么事"“你怎么知道他的屁股扁了”我“不是你说的嘛”“我诈你的”,然后走了......
  • PHP是如何和电脑的内存交互的?
    PHP和电脑的内存交互其实就像是我们和人类的大脑交互一样。电脑的内存就像是大脑里的记忆区域,它暂时存储着电脑正在使用或即将使用的信息。PHP是一种编程语言,它就像是电脑里的一个小助手,帮助电脑完成各种任务。PHP和内存的关系存储变量和数据:当PHP程序运行时,它会在电脑的内存......