【c语言进阶】字符函数和字符串函数知识总结

news2024/9/28 23:31:08

字符函数和字符串函数

  • 前期背景
  • 求字符串长度函数
    • strlen函数
    • strlen函数三种模拟实现
  • 长度不受限制的字符串函数
    • strcpy函数
    • strcpy函数模拟实现
    • strcat函数
    • strcat函数模拟实现
    • strcmp函数
    • strcmp函数模拟实现
  • 长度受限制的字符串函数
    • strncpy函数
    • strncpy函数模拟实现
    • strncat函数
    • strncat函数模拟实现
    • strncmp函数
    • strncmp函数模拟实现
  • 字符串查找
    • strstr函数
    • strstr函数模拟实现
    • strtok函数
  • 错误信息报告
    • strerror函数
    • perror函数
    • 字符分类函数
    • 大小写转化函数
  • 内存操作函数
    • memcpy函数
    • memcpy函数模拟实现
    • memmove函数
    • memmove函数模拟实现
    • memset函数
    • memcmp函数

铁汁们,今天给大家分享一篇字符函数和字符串函数全面知识总结,来吧,开造⛳️

前期背景

在C语言具有许多数据类型,但不具有字符串类型,字符串通常放在字符指针或字符数组中,因为在C语言中对字符和字符串的处理很频繁,从而延伸出许许多多有关字符串的函数。

求字符串长度函数

strlen函数

功能求字符串中元素的个数,不包括末尾的 ’ \0 '。 头文件为#include<string.h>

在这里插入图片描述
字符串是以 ’ \0 '作为结束标志,strlen函数返回的是在字符串中 ’ \0 '前面的总元素个数(不包括 ’ \0 ') 。

注意
1.strlen函数的返回值为 size_t ,无符号整形(unsigned int)

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	const char* str1 = "abcdef";  //元素个数为6个
	const char* str2 = "bbb";    //元素个数为3个
	if (strlen(str2) - strlen(str1) > 0) //两个无符号进行运算,则结果也为无符号
	{
		printf("str2>str1\n");
	}
	else
	{
		printf("srt1>str2\n");
	}
	return 0;
}

在这里插入图片描述
图解:
在这里插入图片描述

2.参数指向的字符串必须要以 ‘\0’ 为结束标志,否则,strlen会越界一直找’ \0 ',直到遇到 ’ \0 ’ 停止,结果为随机值。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	char arr1[8] = "abcde";
	char arr2[5] = {'a','b','c','d','e'};
	printf("%d\n",strlen(arr1));
	printf("%d\n",strlen(arr2));
	return 0;
}

在这里插入图片描述

strlen函数三种模拟实现

1.计数器

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
int my_strlen(const char* arr)  //计数器模拟实现strlen
{
    assert(arr);  //断言,检查指针的有效性,防止对空指针进行解引用、加减整数操作
	int count = 0;
	while (*arr)
	{
		count++;
		arr++;
	}
	return count;
}

int main()
{
	char arr[10] = "hello bit";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

2.指针-指针(计算的是两指针之间的元素个数)

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
int my_strlen(const char* arr)  //指针-指针模拟实现strlen
{
    assert(arr);  //断言,检查指针的有效性,防止对空指针进行解引用、加减整数操作
	char* start = arr;
	char* end = arr;
	while (*end)
	  end++;
	return end - start;
}

int main()
{
	char arr[10] = "hello bit";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

3.递归

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
int my_strlen(const char* arr)  //递归模拟实现strlen
{
    assert(arr);  //断言,检查指针的有效性,防止对空指针进行解引用、加减整数操作
	if (*arr != '\0')
		return my_strlen(arr + 1) + 1;
	else
		return 0;
}

int main()
{
	char arr[10] = "hello bit";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

在这里插入图片描述

长度不受限制的字符串函数

strcpy函数

功能将源头字符串的内容拷贝到目标字符串,包括末尾的 ‘\0’(相当于从前往后进行覆盖)。 头文件为#include<string.h>
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	char dest[20] = "abcdefg";
	char source[6] = "hello";
	strcpy(dest, source + 2); //可以从源字符串的任意位置处开始拷贝
	printf("%s", dest);
	return 0;
}

在这里插入图片描述

=注意
1.会将源头字符串的 '\0’拷贝进去。

2.目标空间要足够大,足以存放源头字符串。

3.目标空间必须是可变的(不能被const修饰)。

4.源头字符串必须以 ‘\0’ 为结束标志(因为strcpy拷贝完\0’后就立即停止拷贝)。

strcpy函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcpy(char* dest, const char* source)
{
    assert(dest&&source); //断言,检查指针的有效性,防止对空指针进行解引用、加减整数操作
	char* ret = dest;
	while (*dest++ = *source++)
	{
		;
	}
	return ret;
}

int main()
{
	char dest[20] = "abcdefg";
	char source[6] = "hello";
	char* ret = my_strcpy(dest, source);
	printf("%s", ret);
	return 0;
}

strcpy在内存中的拷贝过程:
在这里插入图片描述
在这里插入图片描述

strcat函数

功能将源头字符串的内容追加到目标字符串的后面(从目标串的’\0’位置开始向后追加)头文件为#include<string.h>
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	char dest[30] = "heihei";
	char source[] = " hello";
	strcat(dest, source);
	printf("%s", dest);
	return 0;
}

在这里插入图片描述

注意
1.目标字符串必须可修改。
2.源字符串必须含有 '\0’为结束标志。
3.目标空间要足够大,足以容纳源头字符串的内容。

问题:字符串是否可以自己给自己追加?
答:字符串不可以自己给自己追加,因为源头字符串的’\0’会被覆盖,造成源头字符串会一直向后死循环追加。strcat遇到源头字符串的 ‘\0’就停止追加,并且源头字符串末尾的’\0’也会被追加过去。

在这里插入图片描述

strcat函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
char* my_strcat(char* dest,const char* source)
{
    assert(dest&&source); //断言,检查指针的有效性,防止对空指针进行解引用、加减整数操作
	char* ret = dest;
	while (*dest)  //找目标字符串中的'\0'
	{
		dest++;
	}
	while (*dest++ = *source++)
	{
		;
	}
	return ret;
}

int main()
{
	char dest[30] = "abcde";
	char source[] = "hello bit";
	char* ret = my_strcat(dest, source);
	printf("%s", ret);
	return 0;
}

在这里插入图片描述

strcmp函数

功能:用来比较两字符串的大小,两字符串不能直接用==进行比较。 头文件为#include<string.h>

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	char s1[] = "abcdefg";
	char s2[] = "abcde";
	int ret=strcmp(s1, s2);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述

问题:strcmp如何判断两字符串大小?

答:两个字符串从前向后依次比较两个字符,判断是否相等,相等,则继续比较下一个字符,直到有一个串遇到’\0’,并比较完’\0’,就停止。若不相等,比较两字符的ASCII值,ASCII值大的串,字符串大。《—等价于—》ASCII值的比较

在这里插入图片描述
strcmp返回值三种情况:

a.字符串1(前面的参数)大于 字符串2(后面的参数),则返回大于0的数

b.字符串1(前面的参数)小于 字符串2(后面的参数),则返回小于0的数

c.字符串1(前面的参数)等于 字符串2(后面的参数),则返回等于0的数

strcmp函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int my_strcmp(const char* s1, const char* s2)
{
	assert(s1 && s2);
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
			return 0;
		s1++;
		s2++;
	}
	return *s1 - *s2;
}

int main()
{
	char s1[] = "abcde";
	char s2[] = "abcdef";
	int ret = my_strcmp(s1, s2);
	printf("%d", ret);
	return 0;
}

在这里插入图片描述

长度受限制的字符串函数

strncpy函数

功能头文件为#include<string.h>

情况1:源字符串的长度>num,将源字符串的前num个字符拷贝到目标字符串中;

情况2:源字符串的长度<num将源字符串全部拷贝到目标字符串中,包括源字符串末尾的’\0’,源字符串拷贝完后,在目标字符串的后面一直追加 ‘\0’,直到num停止

在这里插入图片描述
情况1代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	int num = 5; //源字符串的长度>num
	char dest[30] = "heheabcd";
	char source[] = "lala hello";
	strncpy(dest, source, num);
	printf("%s", dest);
	return 0;
}

在这里插入图片描述
情况2代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	int num = 20; //源字符串的长度<num
	char dest[30] = "heheabcdefghi";
	char source[] = "lala hello";
	strncpy(dest, source, num);
	printf("%s", dest);
	return 0;
}

在这里插入图片描述
内存图:
在这里插入图片描述

strncpy函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
char* my_strncpy(char* dest,const char* source, int num)
{
	assert(dest && source);
	char* ret = dest;
	while (num--)
	{
		if (*source != '\0')  //情况1,源字符串的长度>num
			*dest++ = *source++;
		else      //情况2,源字符串的长度<num,源字符串拷贝完后,在目标字符串后一直追加'\0'
			*dest++ = '\0';
	}
	return ret;
}

int main()
{
	int num = 5;
	char dest[30] = "heheabcdefghi";
	char source[] = "lala hello";
	char* ret = my_strncpy(dest, source, num);
	printf("%s\n", dest);
	return 0;
}

在这里插入图片描述

strncat函数

功能头文件为#include<string.h>

在这里插入图片描述
情况1:源字符串的长度>num,将源字符串的前num个字符追加到目标字符串后面,最后在目标字符串后面自动补上 ‘\0’;

情况2:源字符串的长度<num将源字符串全部追加到目标字符串后面,包括源字符串末尾的’\0’,则就停止追加。

情况1代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
#include<string.h>
int main()
{
	int num = 5; //情况1,源字符串的长度>num
	char dest[30] = "abcde\0lalalalalala";
	char source[] = "hello world";
	strncat(dest, source, num);   
	printf("%s\n", dest);
	return 0;
}

在这里插入图片描述
在这里插入图片描述
情况2代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
#include<string.h>
int main()
{
	int num = 20; //情况2,源字符串的长度<num
	char dest[30] = "abcde\0lalalalalalalalalalala";
	char source[] = "hello world";
	strncat(dest, source, num);
	printf("%s\n", dest);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

strncat函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
char* my_strncat(char* dest, const char* source,int num)
{
	assert(dest && source);
	char* ret = dest;
	while (*dest)
		dest++;
	while (num--)
	{
		*dest = *source;
		if (*source == '\0')  //清款2
			break;
		dest++;
		source++;
	}
	if (*source != '\0')  //情况1
		*dest = '\0';
	return ret;
}

int main()
{
	int num =5;
	char dest[30] = "abcde\0lalalalalalalalalalala";
	char source[] = "hello world";
	char* ret=my_strncat(dest, source, num);
	printf("%s\n", ret);
	return 0;
}

在这里插入图片描述

strncmp函数

功能:比较前num个字符的大小, 头文件为#include<string.h>

比较到在num范围内有一个串结束、两串中有一个字符不相等,前num个字符全部比完,就停止比较了。

在这里插入图片描述
返回值三种情况:同strcmp函数返回值情况相同。
在这里插入图片描述

strncmp函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
int my_strncmp(const char* s1,const char* s2, int num)
{
    assert(s1&&s2);
	while (num--)
	{
		while (*s1 == *s2)
		{
			if(*s1 == '\0')
				return 0;
			s1++;
			s2++;
		}
		return *s1-*s2;
	}
}

int main()
{
	int num = 3;
	char arr1[] = "abcdef";
	char arr2[] = "abed";
	int len = my_strncmp(arr1, arr2,num);
	printf("%d\n", len);
	return 0;
}

在这里插入图片描述

字符串查找

strstr函数

功能:在string指向的字符串中查找strCharSet指向的字符串是否出现,出现,则返回strCharSet指向的字符串在tring指向的字符串第一次出现的起始位置,若未出现,则返回NULL。 头文件为#include<string.h>
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
#include<string.h>
int main()
{
	char arr[] = "abcdefbcdef";
	char src[] = "bcdef";
	char* ret=strstr(arr, src);
	printf("%s\n", ret);
	return 0;
}

在这里插入图片描述

strstr函数模拟实现

版本1:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
char* my_strstr(char* dest, char* src)
{
	assert(dest && src);
	char* cur = dest;
	char* s1;
	char* s2;
	while (*cur)
	{
		s1 = cur;
		s2 = src;
		while (*s2&&*s1)
		{
			if (*s1 != *s2)
				break;
			s1++;
			s2++;
		}
		if (*s2 == '\0')
			return cur;
			cur++;
	}
}

int main()
{
	char arr[] = "abbbcdefbcdef";
	char src[] = "bcdef";
	char* ret=my_strstr(arr, src);
	printf("%s\n", ret);
	return 0;
}

在这里插入图片描述

在这里插入图片描述
版本2:枚举法(效率更高)

#define _CRT_SECURE_NO_WARNINGS 1 
#include <stdio.h>
#include<assert.h>
#include<string.h>
char* my_strstr(char* dest, char* src)
{
	assert(dest && src);
	char* ret = dest;
	int len1 = strlen(dest);
	int len2 = strlen(src);
	int i=0;
	for ( ; i + len2 <= len1; i++)
	{
		int j = 0;
		for (; j < len2; j++)
		{
			if (dest[i+j] != src[j])
				break;
		}
		if (j == len2)
			return (ret + i);
	}
	return NULL;
}

int main()
{
	char arr[] = "abbbcdefbcdef";
	char src[] = "bcdef";
	char* ret=my_strstr(arr, src);
	printf("%s\n", ret);
	return 0;
}

在这里插入图片描述

在这里插入图片描述

strtok函数

功能:用于处理带标记的字符串。头文件为#include<string.h>
在这里插入图片描述
注意

1.参数2strDelimit指向的字符串定义了用作分隔符的集合,注意参数2必须是字符串,而’\0‘代表的是字符串结束符,通常用于标记字符串的末尾,并不作为分隔符。

2.strToken指向的字符串,它包含了0个或者多个strDelimit指向字符串的分隔符标记。

3.strtok函数找到strDelimit指向字符串中的下一个分隔符的标记,并会自动保存这个标记符在字符串的位置,返回一个指向这个标记的指针。

4.当第一个参数不为NULL,找到第一个分割符标记,该函数内部会自动保存这个标记符在字符串的位置,进行第二次使用strtok函数时,函数的第一个参数为NULL,该函数会从上次strtok函数保存的上个分割标记符后一个位置处查询下一个分割标记符并保存下一个分割标记符所在字符串中的位置,直到不存在分隔符停止查找。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	char arr1[] = "naifu,naiyou.fsq#zzx";
	const char* arr2= ",.#";
	for (char* ret = strtok(arr1, arr2); ret != NULL; ret=strtok(NULL, arr2))
	{
		printf("%s\n", ret);
	}return 0;
}

在这里插入图片描述

错误信息报告

strerror函数

功能返回错误码所对应的错误信息头文件为#include<string.h>
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>  //strerror库函数的头文件
#include<errno.h>   //必须包含的头文件
int main()
{
	FILE* p = fopen("lala.txt", "r");
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));  //errno存放错误码
		return 1;
	}
	fclose(p);
	p = NULL;
	return 0;
}

在这里插入图片描述
strerror函数可以用于确定库函数在执行时发生的错误的原因。当库函数遇到错误时,它会设置一个全局变量errno,C语言会将错误码存放在errno这个全局变量中,strerror函数使用errno确定特定错误码对应的错误消息。

perror函数

功能:返回错误码所对应的错误信息。头文件为#include<stdio.h>
在这里插入图片描述
与strerror作用效果相同,只是perror会输出string指向的字符串内容在加个冒号(:),在输出错误码所对应的错误信息,在文件操作中,确定错误信息是什么,常用perror函数。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
	FILE* p = fopen("lala.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return 1;
	}
	fclose(p);
	p = NULL;
	return 0;

在这里插入图片描述

字符分类函数

头文件为#include<ctype.h>
在这里插入图片描述

大小写转化函数

头文件为#include<ctype.h>
在这里插入图片描述

内存操作函数

memcpy函数

功能:从src位置向后拷贝count个字节的内容到dest指向的字符串中(遇到\0不会停下来)。若拷贝的字节数大于源头字符串的总字节数,超过的字节数拷贝的内容为随机值。 头文件为#include<string.h>

注意:memecpy适用于不重叠数据或者无关联的数据拷贝。

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	int count = 4;
	int arr[10] = { 1,2,3,4,5,6 };
	int src[6] = { 7,8,9,10,11,12 };
	memcpy(arr, src, sizeof(arr[0])*count);
	for (int i = 0; i <10; i++)
		printf("%d ", arr[i]);
	return 0;
}

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<string.h>
int main()
{
	int count = 3;
	int arr[10] = { 1,2,3,4,5,6 };
	int src[3] = { 7,8,9};
	memcpy(arr, src, sizeof(arr[0])*count);
	for (int i = 0; i <10; i++)
		printf("%d ", arr[i]);
	return 0;
}

在这里插入图片描述

memcpy函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
#include<string.h>
void* my_memcpy(void* dest, void* src, int count)  //适用于任意类型
{
	assert(dest && src);
	while (count--)
	{
		*(char*)dest = *(char*)src; //对空指针进行解引用操作,具有临时性,有效时长仅在其所在的语句中
		(char*)dest = (char*)dest + 1; //(char*)dest++,因优先级:++>(),dest(NULL)先与++结合,不能对空指针进行加减、解引用操作
		(char*)src = (char*)src + 1;
	}
	return ;
}

int main()
{
	int count = 4;
	int arr[10] = { 1,2,3,4,5,6,7,8 };
	int src[6] = { 9,10,11,12 };
	int len = sizeof(arr) / sizeof(arr[0]);
	my_memcpy(arr, src, sizeof(arr[0] )* count);
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在这里插入图片描述
问题:memcpy可以拷贝重叠数据吗?
答:memcpy不可以拷贝重叠数据,会造成数据被覆盖。

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
#include<string.h>
void* my_memcpy(void* dest, void* src, int count)  //适用于任意类型
{
	assert(dest && src);
	while (count--)
	{
		*(char*)dest = *(char*)src; //对空指针进行解引用操作,具有临时性,有效时长仅在其所在的语句中
		(char*)dest = (char*)dest + 1; //(char*)dest++,因优先级:++>(),dest(NULL)先与++结合,不能对空指针进行加减、解引用操作
		(char*)src = (char*)src + 1;
	}
	return ;
}

int main()
{
	int count = 5;
	int arr[10] = { 1,2,3,4,5,6,7,8 };
	int src[6] = { 9,10,11,12 };
	int len = sizeof(arr) / sizeof(arr[0]);
	my_memcpy(arr+2, arr, sizeof(arr[0] )* count); //memcpy拷贝重叠数据
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述

memmove函数

功能:从src位置向后拷贝count个字节的内容到dest指向的字符串中(遇到\0不会停下来)。若拷贝的字节数大于源头字符串的总字节数,超过的字节数拷贝的内容为随机值。 头文件为#include<string.h>

注意:memmove既适用于重叠数据或者有关联的数据拷贝,又适用于不重叠数据或者无关联的数据拷贝。

在这里插入图片描述

重叠数据或者有关联的数据拷贝:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
int main()
{
	int count = 5;
	int arr[10] = { 1,2,3,4,5,6,7,8 };
	int len = sizeof(arr) / sizeof(arr[0]);
	memmove(arr+2, arr, sizeof(arr[0] )* count);
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在这里插入图片描述
不重叠数据或者无关联的数据拷贝:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
int main()
{
	int count = 5;
	int arr[10] = { 1,2,3,4,5,6,7,8 };
	int src[5] = { 9,10,11,12,13 };
	int len = sizeof(arr) / sizeof(arr[0]);
	memmove(arr,src, sizeof(arr[0] )* count);
	for (int i = 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在这里插入图片描述

memmove函数模拟实现

memmove模拟实现图:
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* src, int count)
{
	void* ret = dest;
	if (dest < src)  //从前往后拷贝
	{
		while (count--)
		{
			*((char*)dest) = *((char*)src);
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else   //从后往前拷贝
	{
		while (count--)
		{
			*((char*)dest + count) = *((char*)src + count);
		}
	}
	return ret;
}

int main()
{
	int count = 5;
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	my_memmove(arr+2, arr, sizeof(int) * count);   //重叠数据
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述
问题:memmove与memcp有何区别?

答:memmove既可以处理重叠数据,又可处理不重叠数据(100%)。 memcpy被规定来只能用来处理不重叠或者无关联的数据(60%),但在有些编译器上,memcpy也可用来处理重叠数据,所以一般处理重叠数据的拷贝选择memmove,处理不重叠的数据选择memcpy。

memset函数

功能:将dest指向的内存空间的前count字节的内容全部设置为c。 头文件为#include<string.h>

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int count = 5;
	memset(arr, 0, sizeof(int) * count);
	for (int i = 0; i < 10; i++)
		printf("%d ", arr[i]);
	return 0;
}

在这里插入图片描述
应用场景:常适用于初始化一块连续的内存空间,eg:静态版通讯录实现。

memcmp函数

功能:将dest指向的内存空间前count字节的内容与src指向的内存空间前count字节的内容相比较,比较到在count字节范围内有一个空间结束、两空间中有一个字节不相等,前num个字节全部比完,就停止比较了,返回值与strncmp相同。
在这里插入图片描述

铁铁们,字符函数和字符串函数知识总结就到此结束啦,若博主有不好的地方,请指正,欢迎铁铁们留言,请动动你们的手给作者点个👍鼓励吧,你们的鼓励就是我的动力✨

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/803804.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推理和训练

监督学习与非监督学习 Supervised Learning有监督式学习: 输入的数据被称为训练数据&#xff0c;一个模型需要通过一个训练过程&#xff0c;在这个过程中进行预期判断&#xff0c;如果错误了再进行修正&#xff0c;训练过程一直持续到基于训练数据达到预期的精确性。其关键方法…

【Python机器学习】实验04(2) 机器学习应用实践--手动调参

文章目录 机器学习应用实践1.1 准备数据此处进行的调整为&#xff1a;要所有数据进行拆分 1.2 定义假设函数Sigmoid 函数 1.3 定义代价函数1.4 定义梯度下降算法gradient descent(梯度下降) 此处进行的调整为&#xff1a;采用train_x, train_y进行训练 1.5 绘制决策边界1.6 计算…

echarts遇到的问题

文章目录 折线图-区域面积图 areaStyley轴只有整数y轴不从0开始y轴数值不确定&#xff0c;有大有小&#xff0c;需要动态处理折线-显示label标线legend的格式化和默认选中状态x轴的lable超长处理x轴的相关设置 echarts各个场景遇到的问题 折线图-区域面积图 areaStyle areaStyl…

【JVM】JVM五大内存区域介绍

目录 一、程序计数器&#xff08;线程私有&#xff09; 二、java虚拟机栈&#xff08;线程私有&#xff09; 2.1、虚拟机栈 2.2、栈相关测试 2.2.1、栈溢出 三、本地方法栈&#xff08;线程私有&#xff09; 四、java堆&#xff08;线程共享&#xff09; 五、方法区&…

微信小程序 居中、居右、居底和横向、纵向布局,文字在图片中间,网格布局

微信小程序居中、居右、横纵布局 1、水平垂直居中&#xff08;相对父类控件&#xff09;方式一&#xff1a;水平垂直居中 父类控件&#xff1a; display: flex;align-items: center;//子控件垂直居中justify-content: center;//子控件水平居中width: 100%;height: 400px //注意…

go 查询采购单设备事项[小示例]V2-两种模式{严格,包含模式}

第一版&#xff1a; https://mp.csdn.net/mp_blog/creation/editor/131979385 第二版&#xff1a; 优化内容&#xff1a; 检索数据的两种方式&#xff1a; 1.严格模式--找寻名称是一模一样的内容&#xff0c;在上一个版本实现了 2.包含模式&#xff0c;也就是我输入检索关…

ps 给衣服换色

可以通过色相饱和度来改变颜色 但如果要加强对比 可以通过色阶或曲线来调整 针对整体 调整图层-色相/饱和度 着色 给整个画面上色 选区-遮罩-取出来 然后调整图层-色相/饱和度也可以 或者以有图层-色相饱和度后 选区 按ctrli使其遮罩 同时按alt鼠标左键单机 ctrli反相…

【SSM—SpringMVC】 问题集锦(持续更新)

目录 1.Tomcat启动&#xff0c;部署工件失败 1.Tomcat启动&#xff0c;部署工件失败 解决&#xff1a;使用SpringMVC&#xff0c;添加Web支持&#xff0c;要将项目结构进行添加WEB-INF下添加lib目录&#xff0c;将依赖添进去

解锁 Kotlin 中密封类(Seal Class)的能力:设计模式与代码组织的优化

解锁 Kotlin 中密封类(Seal Class)的能力&#xff1a;设计模式与代码组织的优化 多年来&#xff0c;我参与了多个项目&#xff0c;深知编写清晰、易维护代码的价值。最近在一个涉及大量数据类型处理的项目中&#xff0c;我发现使用密封类极大地提高了数据的组织和管理效率。此…

推动中小企业数字化转型,开利网络签约

随着数字经济的发展&#xff0c;大数据、区块链、物联网、AI等新兴数字化技术已成为一种趋势&#xff0c;对于产业园区而言&#xff0c;结合数字化技术形成的“数字园区”理念正逐渐出现在公众视野中。什么是“数字园区”&#xff1f;简单来说&#xff0c;通过对产业园区进行数…

<C语言> 动态内存管理

1.动态内存函数 为什么存在动态内存分配&#xff1f; int main(){int num 10; //向栈空间申请4个字节int arr[10]; //向栈空间申请了40个字节return 0; }上述的开辟空间的方式有两个特点&#xff1a; 空间开辟大小是固定的。数组在申明的时候&#xff0c;必须指定数组的…

使用RunnerGo来简化测试流程

在软件开发过程中&#xff0c;测试是一个重要的环节&#xff0c;需要投入大量时间和精力来确保应用程序或网站的质量和稳定性。但是&#xff0c;随着应用程序变得更加复杂和庞大&#xff0c;传统的测试工具在面对比较繁琐的项目时非常费时费力。这时&#xff0c;一些自动化测试…

MAC电脑设置charles,连接手机的步骤说明(个人实际操作)

目录 一、charles web端设置 1. 安装charles之后&#xff0c;先安装证书 2. 设置 Proxy-Proxy Settings 3. 设置 SSL Proxying 二、手机的设置 1. 安卓 2. ios 资料获取方法 一、charles web端设置 1. 安装charles之后&#xff0c;先安装证书 Help-SSL Proxying-Inst…

高压放大器模块的作用是什么呢

高压放大器模块是一种集成了高压放大器芯片、控制电路、保护电路等多种元件和功能的模块化设备。它可以将输入信号进行放大处理&#xff0c;并输出到负载上&#xff0c;具有高性能、高可靠性、高稳定性等优点。下面安泰电子将详细介绍高压放大器模块的作用&#xff1a; 信号放大…

【LLM】浅析chatglm的sft+p-tuning v2

note GLM将针对不同类型下游任务的预训练目标统一为了自回归填空&#xff0c;结合了混合的注意力机制和新的二维位置编码。本文浅析sft&#xff0c;并基于GLM在广告描述数据集上进行sftp-tuning代码的数据流讲解 文章目录 note零、ChatGLM2模型一、Supervised fine-tuning1. 数…

位图和布隆过滤器+哈希切分思想

文章目录 一.位图(bitset)底层实现: 二.布隆过滤器(bloomFilter)底层实现: 三.哈希切分思想 一.位图(bitset) 位图是一种以一个比特位为数据记录单元的哈希表 ,以无符号整数为key值,采用直接定址法(不存在哈希冲突的问题),其哈希映射函数为 f ( k e y ) k e y ( k e y 的存在…

有关合泰BA45F5260中断的思考

最近看前辈写的代码&#xff0c;发现这样一段代码&#xff1a; #ifdef SUPPORT_RF_NET_FUNCTION if(UART_INT_is_L()) { TmrInsertTimer(eTmrHdlUartRxDelay,TMR_PERIOD(2000),NULL); break; } #endif 其中UART_INT_is_L&am…

【lesson6】Linux下:第一个小程序,进度条代码

文章目录 准备工作sleep问题fflush回车与换行的区别 进度条代码 准备工作 sleep问题 首先我们来看一段代码&#xff1a; 这时候有个 问题这个代码是输出“hello world”还是先sleep三秒&#xff1f; 再来一段代码 这个代码是先sleep三秒还是先输出“hello world”&#xff…

「乐天世界」NFT 作品集

进入「乐天世界」NFT 作品集的迷人世界&#xff0c;这里仿佛就是乐天世界探险主题公园里充满活力的礼品店。 准备好随着想象力的飞跃而沉浸其中吧&#xff0c;因为主题公园里的普通物品已经变得非凡。沉浸在游乐园美食的魔力中&#xff0c;如香脆的玉米热狗、令人垂涎的巧克力蛋…

立创EDA学习

学习树莓派3B的板子发现有个扩展板比较好&#xff0c;自己最好画一个&#xff0c;反正免费。 学习视频&#xff1a;立创EDA&#xff08;专业版&#xff09;电路设计与制作快速入门。 下载专业版&#xff0c;并激活。【分专业版和标准版&#xff0c;专业版也是免费的】 手机…