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

字符函数和字符串函数

  • 前期背景
  • 求字符串长度函数
    • 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相同。
在这里插入图片描述

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】QML-02:QQuickView用法

1、先看demo QtCreator自动生成的工程是使用QQmlApplicationEngine来加载qml文件&#xff0c;下面的demo将使用QQuickView来加载qml文件 #include <QGuiApplication> #include <QtQuick/QQuickView>int main(int argc, char *argv[]) {QGuiApplication app(argc,…

electron dialog.showMessageBox使用案例

electron 版本&#xff1a;25.3.1 index.html <!DOCTYPE html> <html> <head><meta charset"UTF-8"><title>Hello World!</title><meta http-equiv"Content-Security-Policy" content"script-src self unsa…

MySQL绿色安装和配置

1、 从地址http://dev.mysql.com/downloads/mysql/中选择windows的版本下载。 2、 mysql各个版本的简介 &#xff08;1&#xff09; MySQL Community Server 社区版本&#xff0c;开源免费&#xff0c;但不提供官方技术支持。 &#xff08;2&#xff09; MySQL Enterprise Ed…

失去SSL证书,会对网站安全造成什么影响?

作为网络世界中的“身份证”&#xff0c;SSL证书可以在网络世界中证明你是一个真实可信的企业或个人网站&#xff0c;而不是一个钓鱼网站。且在网站的服务器上部署SSL证书后&#xff0c;可以使网站与访问者之间通过SSL协议建立安全的加密连接&#xff0c;确保在Web服务器和浏览…

【Unity细节】关于拉进镜头场景后场景资源消失的问题的解决

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 收录于专栏&#xff1a;unity细节和bug ⭐关于拉进镜头场景资源消失的问题的解决⭐ 文章目录 ⭐关于拉进镜头场景资源消失…

No100.精选前端面试题,享受每天的挑战和学习(事件循环)

文章目录 1. 请解释一下JavaScript中的事件循环&#xff08;Event Loop&#xff09;是什么&#xff0c;并描述其工作原理。2. 请解释一下JavaScript中的宏任务&#xff08;macro-task&#xff09;和微任务&#xff08;micro-task&#xff09;的区别3. 在事件循环中&#xff0c;…

移动IP的原理

目的 使得移动主机在各网络之间漫游时&#xff0c;仍然能保持其原来的IP地址不变 工作步骤 代理发现与注册 主机A&#xff1a;主机A移动到外地网络后&#xff0c;通过“代理发现协议”&#xff0c;与外地代理建立联系&#xff0c;并从外地代理获得一个转交地址&#xff0c;…

非线性质量弹簧阻尼器的神经网络仿真研究(Matlab代码Simulink仿真实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

浅谈性能测试中的基准测试

在性能测试中有一种测试类型叫做基准测试。这篇文章&#xff0c;就聊聊关于基准测试的一些事儿。 1、定义 通过设计合理的测试方法&#xff0c;选用合适的测试工具和被测系统&#xff0c;实现对某个特定目标场景的某项性能指标进行定量的和可对比的测试。 2、特质 ①、可重…

FPGA——verilog实现格雷码与二进制的转换

文章目录 一、格雷码简介二、二进制转格雷码三、格雷码转二进制四、仿真 一、格雷码简介 格雷码是一种循环二进制码或者叫作反射二进制码。跨时钟域会产生亚稳态问题&#xff08;CDC问题&#xff09;&#xff1a;从时钟域A过来的信号难以满足时钟域B中触发器的建立时间和保持时…

【ROS第一讲】一、创建工作空间

【ROS第一讲】一、创建工作空间 一、工作空间1.src&#xff1a;2.build&#xff1a;3.devel&#xff1a;4.install: 二、创建工作空间1.工作空间的编译2.配置环境变量&#xff1a; 三、创建功能包 一、工作空间 1.src&#xff1a; 放置所有功能包源码的空间 2.build&#xf…

vue中tab隐藏display:none(v-show无效,v-if有效)

目录 背景 原因&#xff1a;display: table-cell>display:none 解决&#xff1a; 方法A.获取元素设置display&#xff08;适用于 简单场景&#xff09; 方法B.自定义tabs​​​​​​​ &#xff08;适用于 复杂场景&#xff09; 背景 内联样式(style“ ”) /this.$…

redis群集(主从复制)

---------------------- Redis 主从复制 ---------------------------------------- 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(Master)&#xff0c;后者称为从节点(Slave)&#xff1b;数据的复制是单向的&#xf…

Docker 如何助您成为数据科学家

一、说明 在过去的 5 年里&#xff0c;我听到了很多关于 docker 容器的嗡嗡声。似乎我所有的软件工程朋友都在使用它们来开发应用程序。我想弄清楚这项技术如何使我更有效率&#xff0c;但我发现网上的教程要么太详细&#xff1a;阐明我作为数据科学家永远不会使用的功能&#…

5.定时器-间歇函数

网页中经常会需要一种功能&#xff1a;每隔一段时间需要自动执行一段代码&#xff0c;不需要我们手动去触发 例如&#xff1a;网页中的倒计时 ●要实现这种需求&#xff0c;需要定时器函数 5.1开启定时器 语法 setInterval(函数,间隔时间)作用&#xff1a;每隔一段时间调用这…

excel要如何自动累加某个单元格上方的所有单元格?

输入公式 SUM(INDIRECT("A1:A"&ROW()-1)) 运行实例如下图 注意图中b4&#xff0c;和b5单元格都输入相同的公式。 此方法可以避免写vba&#xff0c;以前此类问题的解决都是通过vba代码进行处理 对函数进行解析 主要使用了 INDIRECT() 2、公式说明&#xff1a;…

Windows实现端口转发(附配置过程图文详解)

文章目录 1. 前言2. 命令提示符3. 防火墙4. netsh 命令4.1 查看已有的转发规则4.2 新增转发规则4.3 删除转发规则 5. 图解汇总6. 欢迎纠正~ 1. 前言 利用Windows端口转发&#xff0c;实现本地设备 ⬅➡ 公网主机 ⬅➡ 远端服务器 2. 命令提示符 以管理员身份打开“命令提示…

成本中心修改或者创建保存时增强的实现

成本中心修改或者创建保存时增强 用户出口程序为&#xff1a;EXIT_SAPLKMA1_003。 可以通过SMOD 或者 CMOD来添加增强代码。 CMOD->COOMKS02 ->EXIT_SAPLKMA1_003 按公司要求&#xff0c;写了段代码检查 创建利成本中心时&#xff0c;业务范围要规范输入。 data PRCTR…

2023年 React 最佳学习路线

CSS CSS JavaScript JavaScript TypeScript 目前没有找到比其他文档好很多的文档地址 可以先看官网 React 新版 React 官方文档无敌 React React-router-dom V5 V6 Webpack webpack Antd antd

Docker 镜像构建 搭建分布式LNMP论坛 实践

地址规划 nginx 172.18.0.10 mysql 172.18.0.20 php 172.18.0.30 宿主机准备 拉取镜像&#xff0c;下面以此镜像为基础 docker pull centos:7 创建自定义网段以便指定 IP 不变动 docker network create --subnet172.18.0.0/16 --opt "com.docker.network.bridge.na…