字符串和内存函数的整理

目录

首先看一张图来认识一下这些函数

1.strlen    计算字符的大小函数

 2.strcpy   字符串拷贝函数

3.strcat  字符串追加函数

4. strcmp  比较字符串

5.一些加n的函数

6.strstr   查找字符串

7.memcpy    内存拷贝函数

8.memmove   可以自己拷贝自己

9.memset   内存初始化函数

10.memcmp  内存比较函数


首先看一张图来认识一下这些函数

1.strlen    计算字符的大小函数

字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包
含 '\0' )。


注意函数的返回值为size_t,是无符号的( 易错 )   不能加减进行比较,因为返回的是一个无符号数

(可以直接比较大小,也可以强制类型转化后进行比较)

int main()
{

	char arr1[] = { 'a','b','c','d','e' };
	
	char arr2[10]= { 'a','b','c','d','e' };

	int len1 = strlen(arr1);
	
	printf("%d\n", len1);          //结果为随机值,不知道0在那出现

	int len2 = strlen(arr2);      //结果是5,因为规定了大小10个,其余的默认为0

	printf("%d", len2);

	return 0;
}

计数器的方法模拟实现strlen

#include <assert.h>
int my_strlen(const char* str)
{

	assert(str);
	int count = 0;
	while (*str)
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	char arr[] = "abcdef";

	int len = my_strlen(arr);

	printf("%d\n", len);
	return 0;
}

 2.strcpy   字符串拷贝函数

源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。  源字符串中必须有\0
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可修改,不能是常量字符串

 

/模拟实现strcmp

//strcmp函数返回的是目标空间的起始地址 
char* my_strcmp(char* dest, char* str)
{
	assert(dest && str);
	//这样写容易理解
	char* ret = dest;     //返回类型是char*,返回的是目标空间的起始地址 ,目的为了实现链式访问
	while (*str!='\0')
	{
		*dest++ = *str++;

	}
	*dest = *str;  //把'\0'也拷贝进来
	return ret;

	//最简化写法
	//while (*dest++ = *str++)
	//{
	//	;
	//}
}

int  main()
{
	char arr1 [20] = { 0 };     //目标空间

	char* arr2 = "abcdef";       //源字符串

	my_strcmp(arr1, arr2);

	//printf("%s", arr1);
	printf("%s", my_strcmp(arr1, arr2)); //这个就是链式访问
	//把my_strcmp函数的返回值作为printf的参数
	
	return 0;
}

3.strcat  字符串追加函数

strcat  字符串追加(在目标空间'\0'之后开始追加,会覆盖'\0')
源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变。

int main()
{
	char arr1[10] = "hello";   //目标空间字符串
	char arr2[] = " bit";     //源字符串

	strcat(arr1, arr2);
	printf("%s", arr1);    //hello bit

	return 0;
}


模拟实现strcat

char* my_strcat(char*dest,char*str)
{
	//1.先找目标空间中的'\0'
	assert(dest && str);
	char* ret = dest;
	while (*dest)
	{
		dest++;
	}
	//当循坏出来后,*dest就是0
	// 2.进行字符串追加,相当于字符串的拷贝
	while (*dest++ = *str++)
	{
		;
	}
	return dest;     //返回的是目标空间的起始地址
}

int main()
{
	char arr1[20] = "hello";
	char arr2[] = " bit";

	my_strcat(arr1, arr2);
	printf("%s", arr1);      hello bit
}
字符串给自己追加可能会造成死循环

4. strcmp  比较字符串

strcmp比较的不是字符串的长度!!  
是比较对应位置字符的大小,用Asii码值来进行比较,相同就比下一对直到遇到\0
abcdef 和abq比较,q大于c,后面的不用进行比较了,所以后面的大

int main()
{
	char arr1[] = "abcde";
	char arr2[] = "abcq";

	int ret=strcmp(arr1, arr2);

	if (ret > 0)
		printf(">\n");
	else if (ret == 0)
		printf("==\n"); 
	else
		printf("<\n");
 
	return 0;            <
} 

模拟实现strcmp


int my_strcmp(const char* s1, const char* s2)
{
	assert(s1 && s2);

	while (*s1 == *s2)
	{
		if (*s1 == '\0')
		{
			return 0;
		}
		s1++;
		s2++;
    }
	if (*s1 > *s2)
		return 1;
	else
		return -1;
}

int main()
{
	char arr1[] = "abc";
	char arr2[] = "abcd";

	int ret = my_strcmp(arr1, arr2);

	if (ret > 0)
		printf(">\n");
	else if (ret == 0)
		printf("==\n");
	else
		printf("<\n");

	printf("%d", ret);

	return 0;
}

5.一些加n的函数

strncpy,字符串拷贝,后面可以加字数

    strncat ,追加,后面也可以加字数

   strncmp ,比较字符串,可以选择比较哪个

6.strstr   查找字符串

  判断arr2是不是arr1的字串,如果是打印出来加上后面的值, 如果不是,返回0

int main()
{
	char arr1[] = "abcdefabcdef";
	char arr2[] = "cdef";

	char*ret=strstr(arr1, arr2);
	if (NULL == ret)
	{
		printf("找不到子串\n");
	}
	else
	{
		printf("%s\n", ret);      //返回的是cdefabcdef
	}
	return 0;
}

7.memcpy    内存拷贝函数

内存操作函数,memcpy,拷贝数组结构体等等
函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
这个函数在遇到 '\0' 的时候并不会停下来。
如果source和destination有任何的重叠,复制的结果都是未定义的。

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };

	int arr2[5] = { 0 };

	memcpy(arr2, arr1,20);     //20个字节

	return 0;        // 通过调试来观察
}

void* memcpy(void* destination, const void* source, size_t num); 库里面的用法



模拟实现memcpy
#include<assert.h>

void* my_memcpy(void* dest, const void* str, size_t num)
{

	assert(dest && str);
	void* ret = dest;     //返回的是目标空间的起始地址

	while (num--)                //循坏20次
	{
		*(char*)dest = *(char*)str;   //每次改变一个字节
		dest = (char*)dest + 1;
		str = (char*)str + 1;
	}
	return ret;
}

int main()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };

	int arr2[5] = { 0 };

	my_memcpy(arr2, arr1,20);     //20个字节

	return 0;        //通过调试来进行测试
}

8.memmove   可以自己拷贝自己


和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。

int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	//把12345拷贝到34567的位置上,结果为1 2 1 2 3 4 5 8 9 10
	memmove(arr + 2, arr, 20);

	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}

	return 0;
}

9.memset   内存初始化函数

memset是以字节为单位来初始化的

10.memcmp  内存比较函数

比较内存中的值,一个字节一个字节进行比较

 第18个字节不同,00小于33,返回的是负数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值