【C语言】字符函数、字符串函数与内存函数

news2024/12/28 6:38:02

简单不先于复杂,而是在复杂之后。

89efcc89ac61428db4d5b6639b2bd948.jpeg

目录

0. 前言 

1. 函数介绍 

1.1 strlen 

1.1.1 介绍

1.1.2 strlen 函数模拟实现

1.1.2.1 计数器方法 

1.1.2.2 递归方法 

1.1.2.3 指针 - 指针方法 

1.2 strcpy 

1.2.1 介绍

1.2.2 strcpy 函数模拟实现

1.3 strcat

1.3.1 介绍

1.3.2 strcat 函数模拟实现

 1.4 strcmp

1.4.1 介绍 

1.4.2 strcmp 函数模拟实现   

1.5 strncpy

 1.5.1 函数介绍

1.6 strncat 

1.6.1 函数介绍 

 1.7 strncmp

 1.7.1 函数介绍 

1.8 strstr 

1.8.1 函数介绍 

1.8.2  strstr 函数模拟实现

1.9 strtok 

1.9.1 函数介绍 

1.10  sterror

1.10.1  函数介绍

1.11  memcpy

1.11.1 函数介绍 

1.11.2 memcpy 函数模拟实现

1.12 memmove 

1.12.1 函数介绍 

 1.12.2 memmove 函数模拟实现

1.13 memcmp

1.13.1 函数介绍 

1.14 memset 

 


0. 前言 

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在常量字符串中或者字符数组中。

字符串常量适用于那些对它不做修改的字符串函数。 

1. 函数介绍 

1.1 strlen 

1.1.1 介绍

 

计算字符串长度。 

  •  字符串以 '\0' 为结束标志, strlen 函数返回的是在字符串中 '\0' 前面的字符个数(不包含 \0)。
  • 参数指向的字符串必须要以 \0 结束。
  • 注意函数的返回类型是 size_t 是无符号的。
  • 学会 strlen 的模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	//char arr[] = "abcdef";
	//a b c d e f \0

	char arr[] = { 'w','o','w' };
	//[][][][][][][][][w][o][w][][][][][][][][]

	int len = strlen(arr);//随机值

	printf("%d\n", len); 

	return 0;
}

 

 

1.1.2 strlen 函数模拟实现

1.1.2.1 计数器方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>

size_t my_strlen(const char* str)
{
	assert(*str);
	size_t count = 0;
	while (*str != '\0')
	{
		str++;
		count++;
	}

	return count;
}

int main()
{
	char arr[] = "abcdef";
	size_t n = my_strlen(arr);
	printf("%d\n", n);

	return 0;
}
1.1.2.2 递归方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

size_t my_strlen(const char* str)
{

	if (*str == '\0')
	{
		return 0;
	}
	else
	{
		return 1 + my_strlen(str + 1);
	}
}

int main()
{
	char arr[] = "abcdef";
	size_t n = my_strlen(arr);
	printf("%d\n", n);

	return 0;
}
1.1.2.3 指针 - 指针方法 

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>

size_t my_strlen(const char* str)
{
	assert(*str);
	char* start = str;
	while (*str != '\0')
	{
		str++;
	}
	return str - start;
}

int main()
{
	char arr[] = "abcdef";
	size_t n = my_strlen(arr);
	printf("%d\n", n);

	return 0;
}

1.2 strcpy 

1.2.1 介绍

char* strcpy(char* destination, const char* source);

字符串拷贝。 

  •  Copies the C string pointed by source into the array pointed by destination, including the terminating null character (and stopping at that point).
  • 源字符串必须以 '\0' 结束
  • 会将源字符串中的 '\0' 拷贝到目标空间
  • 目标空间必须足够大,以确保能存放源字符串
  • 目标空间必须可变
  • 学会模拟实现

 

 

以上为正确写法。

 因为目标地址指向一个常量字符串,这个区域不可修改,所以会引发异常,故要求目标空间必须可变。

1.2.2 strcpy 函数模拟实现

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

//strcpy 返回目标空间的起始地址
char* my_strcpy(char* dest, const char *src)
{
	//实现字符串拷贝只有需要解引用操作才能找到字符串内容
	//故两个指针不可为空指针,要对其断言
	assert(dest);
	assert(src);

	char* ret = dest;

	while (*src)
	{
		*dest++ = *src++;
	}
	*dest = *src;

	return ret;
}

int main()
{
	char arr1[] = { "abcdef" };
	char arr2[20] = { 0 };
	my_strcpy(arr2, arr1);
	printf("%s\n", arr2);

	return 0;
}

以上代码不够简练,可以优化:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

//strcpy 返回目标空间的起始地址
char* my_strcpy(char* dest, const char* src)
{
	//实现字符串拷贝只有需要解引用操作才能找到字符串内容
	//故两个指针不可为空指针,要对其断言
	assert(dest && src);

	char* ret = dest;

	while (*dest++ = *src++)
	{
		;
	}

	return ret;
}

int main()
{
	char arr1[] = { "abcdef" };
	char arr2[20] = { 0 };
	my_strcpy(arr2, arr1);
	printf("%s\n", arr2);

	return 0;
}

这样的话 *dest++ = *src++ 这个语句就做到了既赋值又判断。

1.3 strcat

1.3.1 介绍

 

 字符串追加。

  • Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.
  • 源字符串必须以’\0‘结束。
  • 目标空间必须足够大,能容纳下源字符串的内容.
  • 目标空间必须可修改。
  • 字符串自己给自己追加,如何?

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>
//字符串追加
int main()
{
	char arr1[20] = "hello";
	strcat(arr1, "world");
	printf("%s\n", arr1);

	return 0;
}

1.3.2 strcat 函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>

//字符串追加
char* my_strcat(char* dest, const char* src)
{ 
	assert(dest && src);
	char* ret = *dest;
	while (*dest != '\0')
	{
		dest++;
	}
	while (*dest++ = *src++)
	{
		;
	}

	return ret;
}

int main()
{
	char arr1[20] = "hello ";
	my_strcat(arr1, "world");
	printf("%s\n", arr1);

	return 0;
}

如果自己给自己追加,程序会崩溃。

因为当把源字符串的字符逐个拷贝到目标字符串后面的时候,直到该拷贝‘\0’的时候,源字符串的‘\0‘被第一个拷贝过来的字符覆盖掉了,会陷入死循环。

所以我们要尽量避免字符串自己给自己追加。 

 1.4 strcmp

1.4.1 介绍 

 

  • 比较两个字符串是否相等。
  •  This function starts comparing the first character of each string. If they are equal to each other, it continues with the following pairs until the characters differ or until a terminating null-character is reached.
  • 标准规定:

                      1. 第一个字符串大于第二个字符串,则返回大于0的数字

                      2. 第一个字符串等于第二个字符串,则返回0

                      3. 第一个字符串小于第二个字符串,则返回小于0的数字

这种写法是在比较两个数组首元素的地址。 

 两个字符串比较是否相等,应该使用 strcmp

一对字符在比较的时候比较的是 ASCII 码值。

1.4.2 strcmp 函数模拟实现   

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

int my_strcmp(const char* str1,const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	if (*str1 > *str2)
		return 1;
	else
		return -1;
}

int main()
{
	char arr1[20] = "abc";
	char arr2[20] = "abc";
	//比较一下两个字符串是否相等

	int ret = my_strcmp(arr1, arr2);

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

	//arr1 和 arr2 是数组名,是数组首元素的地址,必然不相等
	//if (arr1 == arr2)
	//{
	//	printf("==\0");
	//}
	//else
	//{
	//	printf("!=\0");
	//}

	return 0;
}

函数还可以简化:

int my_strcmp(const char* str1,const char* str2)
{
	assert(str1 && str2);
	while (*str1 == *str2)
	{
		if (*str1 == '\0')
			return 0;
		str1++;
		str2++;
	}
	return (*str1 > *str2);
}

当目标空间不够时,会产生越界访问导致程序崩溃,但是函数仍然可以将大小超出目标空间的字符串拷贝。 

这是潜在的安全隐患。

1.5 strncpy

 1.5.1 函数介绍

 

  •  Copies the first num characters of source to destination. If the end of the source C string(which is signaled by a null-character) is found before num characters have been copied, destination is padded with zeros until a total of num characters have been written to it.
  • 拷贝num个字符从源字符串到目标空间。
  • 如果源字符串小于num,在拷贝完源字符串时,在目标后面追加0,直到num个。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	char arr1[] = "abcdef";
	char arr2[] = "hello world";

	strncpy(arr1, arr2, 5);

	printf("%s\n", arr1);

	return 0;
}

 

因为在源字符串后面追加了0,也就是\0, 所以在源字符串小于num时,数组里存放的虽然追加两个0,后面有字符‘f’,但是打印字符串时到第一个‘\0’ 就已经终止了,只能打印源字符串的内容。

1.6 strncat 

1.6.1 函数介绍 

char * strncat ( char * destination, const char * source, size_t num );
  • Appends the first num characters of source to destination, plus a terminating null-character.
  • If the length of the C string in source is less than num, only the content up to the terminating null-character is copied.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	char arr1[20] = "hello\0xxxxxxxx ";
	char arr2[] = "world";

	strncat(arr1, arr2, 3);


	return 0;
}

如果 num 大于源字符串,也不会像 strncpy 一样多追加几个 \0 。

 1.7 strncmp

 1.7.1 函数介绍 

int strncmp ( const char * str1, const char * str2, size_t num );
  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<stdio.h>

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

	int ret = strncmp(arr1, arr2, 3);
	if (ret == 0)
		printf("==");
	else if (ret < 0)
		printf("<");
	else
		printf(">");

	return 0;
}

我们以后在使用字符串函数的时候尽量使用带n的版本,更严谨一些。

1.8 strstr 

1.8.1 函数介绍 

char * strstr ( const char *str1, const char * str2);
  • Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
  • 查找子串(str2 是子串)

 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	char email[] = "lxz@code.com";
	char substr[] = "code";
	char* ret = strstr(email, substr);
	if (ret == NULL)
	{
		printf("子串不存在");
	}
	else
	{
		printf("%s\n", ret);
	}


	return 0;
}

1.8.2  strstr 函数模拟实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

char* my_strstr(const char* str1, const char* str2)
{
	assert(str1 && str2);
	const char* s1 = str1;
	const char* s2 = str2;
	const char* p = str1;

	while (*p)
	{
		s1 = p;
		s2 = str2;
		while (*s1 != '\0' && s2 != '\0' && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)p;
		}
		p++;
	}
	return NULL;
}

int main()
{
	char email[] = "lxz@code.com";
	char substr[] = "code";
	char* ret = my_strstr(email, substr);
	if (ret == NULL)
	{
		printf("子串不存在");
	}
	else
	{
		printf("%s\n", ret);
	}


	return 0;
}

这样找子串是不够高效的,有一个 KMP 算法,用来实现在一个字符串中查找子字符串,效率高但是实现难度大。 

这里不做赘述。

1.9 strtok 

1.9.1 函数介绍 

char * strtok ( char * str, const char * sep );
  • 切割字符串
  • sep 参数是个字符串,定义了用作分隔符的字符集合。
  • 第一个参数指定一个字符串,它包含了 0 个或者多个由 sep 字符串中一个或多个分隔符分割的标记。
  • strtok 函数找到 str 中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok 函数会改变被操作的字符串,所以在使用 strtok 函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok 函数的第一个参数不为 NULL,函数将找到 str 中第一个标记, strtok 函数将保存它在字符串中的位置。
  • strtok 函数的第一个参数为 NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	const char* sep = "@.";
	char email[] = "lxz@code.com";
	char cp[30] = { 0 };
	strcpy(cp, email);
	char* ret = strtok(cp, sep);
	printf("%s\n", ret);
	ret = strtok(NULL, sep);
	printf("%s\n", ret);
	ret = strtok(NULL, sep);
	printf("%s\n", ret);

	return 0;
}

因为我们不知道字符串中有几个字段,所以不知道应该调用几次 strtok 函数,所以换一种写法。 

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	const char* sep = "@.";
	char email[] = "lxz@code.com";
	char cp[30] = { 0 };
	strcpy(cp, email);

	char* ret = NULL;
	for (ret = strtok(cp, sep);
		ret != NULL; 
		ret = strtok(NULL, sep))
	{
		printf("%s\n", ret);
	}

	//char* ret = strtok(cp, sep);
	//printf("%s\n", ret);

	//ret = strtok(NULL, sep);
	//printf("%s\n", ret);

	//ret = strtok(NULL, sep);
	//printf("%s\n", ret);

	return 0;
}

 这样写利用 for 循环可以适应任意数量字段的字符串。

1.10  sterror

1.10.1  函数介绍

char * strerror ( int errnum );
  •  返回错误码,所对应的错误信息

C语言的库函数,在执行失败的时候,都会设置错误码。

 

 

字符分类函数: 

函数如果他的参数符合下列条件就返回真
iscntrl任何控制字符
isspace空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit十进制数字 0~9
isxdigit十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower小写字母a~z
isupper大写字母A~Z
isalpha字母a~z或A~Z
isalnum字母或者数字,a~z,A~Z,0~9
ispunct标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph任何图形字符
isprint任何可打印字符,包括图形字符和空白字符

这些函数用法都很简单,不做赘述。 

字符转换: 

int tolower ( int c );//转小写
int toupper ( int c );//转大写

1.11  memcpy

1.11.1 函数介绍 

void * memcpy ( void * destination, const void * source, size_t num );
  • 函数 memcpy 从 source 的位置开始向后复制 num 个字节的数据到 destination 的内存位置。
  • 这个函数在遇到 ‘\0’ 的时候并不会停下来。
  • 如果 source 和 destination 有任何的重叠,复制的结果都是未定义的。

memcpy 函数可以用于复制任何类型的数据,无论是字符、整数、浮点数还是自定义数据结构。它不关心数据的具体类型,只是按照指定的字节数进行复制。

由于 memcpy 的参数是 void* 类型,可以轻松地将不同数据类型的数据复制到目标内存中,而不需要进行类型转换。这使得代码更加灵活和可维护。

1.11.2 memcpy 函数模拟实现

 C 语言中 void* 类型的指针不能直接解引用的原因是因为 void* 是一种通用的指针类型,它可以用来存储任何数据类型的地址,但它本身并不知道指向的是什么类型的数据。因此,直接解引用 void* 指针是不允许的,因为编译器无法确定要访问多少字节的内存以及如何解释这些字节。

为了解引用 void* 指针,需要将其转换为一个特定的数据类型的指针,这通常涉及到类型转换。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

void* my_memcpy(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	while (num--)
	{
		*(char*)dest = *(char*)src;
		dest = (char*)dest + 1;
		src = (char*)src + 1;	
	}

	return ret;
}


int main()
{
	int arr1[] = { 1,2,3,4,5,6,7 };
	int arr2[10] = { 0 };
	my_memcpy(arr2, arr1, 28);

	return 0;
}

memcpy 负责拷贝两块独立空间中的数据,对于重叠的空间,比如将自身空间中的数据拷贝到自身空间中,是不支持的。

重叠空间的拷贝,要用到 memmove 

1.12 memmove 

1.12.1 函数介绍 

 

void * memmove ( void * destination, const void * source, size_t num );
  • 和 memcpy 的差别就是 memmove 函数处理的源内存块和目标内存块是可以重叠的。
  • 如果源空间和目标空间出现重叠, 就得使用 memmove 函数处理。

   

 1.12.2 memmove 函数模拟实现

         

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>

void* my_memmove(void* dest, const void* src, size_t num)
{
	assert(dest && src);
	void* ret = dest;
	if (dest < src)
	{
		//前->后
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	else
	{
		//后->前
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}

	return ret;
}

void test()
{
	int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
	
	my_memmove(arr1 + 2, arr1, 20);

	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr1[i]);
	}
}

int main()
{
	test();

	return 0;
}

1.13 memcmp

1.13.1 函数介绍 

int memcmp ( const void * ptr1,
const void * ptr2,
size_t num );
  • 比较从ptr1和ptr2指针开始的num个字节
  • 返回值如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>

int main()
{
	int arr1[] = { 1,2,3,4,5 };//01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00
	int arr2[] = { 1,3,2 };    //01 00 00 00 03 00 00 00 02 00 00 00
	int ret = memcmp(arr1, arr2, 12);
	printf("%d\n", ret);

	return 0;
}

strcmp 只能比较字符串

memcmp 可以比较任意类型的数据 

1.14 memset 

  • 内存设置 

这个函数以字节为单位初始化内容,会把每个字节改变为要改的值。 

int main()
{
	int arr[10] = { 0 };
	memset(arr, 1, 40);
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d\n", arr[i]);
	}

	return 0;
}

 

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

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

相关文章

基于标签的电影推荐算法研究_张萌

&#xff12; 标签推荐算法计算过程 &#xff12;&#xff0e;&#xff11; 计算用户对标签的喜好程度 用户对一个标签的认可度可以使用二元关系来表示&#xff0c;这种关系只有“是”“否”两种结果&#xff0c;实际上难以准确地表达出用 户对物品的喜好程度。因此&#x…

云耀服务器L实例搭配负载均衡部署Linux 可视化宝塔面板

云耀服务器L实例搭配负载均衡部署Linux 可视化宝塔面板 1. 华为云云耀服务器L实例介绍 华为云云耀服务器L实例是一种高性能、高可靠性的云服务器实例&#xff0c;适用于大规模企业级应用、大数据分析等场景。它基于华为最新一代的硬件虚拟化技术&#xff0c;提供了更高的计算…

Azure - 自动化机器学习AutoML Azure使用详解

目录 一、AutoML是如何工作的&#xff1f;二、何时考虑AutoML&#xff1f;三、AutoML助力训练与集成过程四、实战案例五、总结 自动化机器学习&#xff0c;简称为AutoML&#xff0c;旨在将机器学习模型的开发中繁琐且重复的任务自动化。这使得数据科学家、分析师以及开发人员能…

ArcGIS笔记13_利用ArcGIS制作岸线与水深地形数据?建立水动力模型之前的数据收集与处理?

本文目录 前言Step 1 岸线数据Step 2 水深地形数据Step 3 其他数据及资料 前言 在利用MIKE建立水动力模型&#xff08;详见【MIKE水动力笔记】系列&#xff09;之前&#xff0c;需要收集、处理和制作诸多数据和资料&#xff0c;主要有岸线数据、水深地形数据、开边界潮位驱动数…

File文件查找

用的是递归调用&#xff0c; &#xff08;递归死循环的结果是导致栈内存溢出错误&#xff09; 一.代码 package org.example;import java.io.File;public class day03 {public static void main(String[] args) {//文件查找&#xff0c;在d&#xff1a;temp下查找改名.mp4sea…

前端的简单介绍

前端核心的分析 CSS语法不够强大&#xff0c;比如无法嵌套书写&#xff0c;倒是模块化开发中需要书写很多重复的选择器 没有变量和合理的样式复用机制&#xff0c;使逻辑上相关的属性值必须字面量的心事重复的输出&#xff0c;导致难以维护 CSS预处理器,减少代码的笨重&#…

IDEA中application.properties文件中文乱码

现象&#xff1a; 原因&#xff1a; 项目编码格式与IDEA编码格式不一致导致的 解决办法&#xff1a; 在File->Settings->Editor->File Encodings选项中&#xff0c;将Global Encoding,Project Encoding,Default encoding for properties files这三个选项置为一致&a…

设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点(C语言实现)

设计一个递归算法&#xff0c;删除不带头结点的单链表L中所有值为x的结点&#xff08;C语言实现&#xff09; 这个代码网上基本都是直接照搬的王道&#xff0c;但是由于某些院校是明确要求用C语言实现&#xff0c;你那个C的引用符号&根本用不了&#xff0c;所以笔者这里用…

归结原理、归结演绎推理

主要内容 归结演绎推理范式子句与子句集将谓词公式转化为子句集命题逻辑鲁宾逊归结原理 归结演绎推理 定理证明的实质是对前提P和结论Q证明P →Q的永真性应用反证法&#xff0c;欲证明P →Q&#xff0c;只要证明 P∧~Q 等价于 F鲁宾逊归结原理对机械化推理有重大突破鲁宾逊归…

李宏毅老师浅谈机器学习

李宏毅老师浅谈机器学习 引例 - 宝可梦/数码宝贝 分类器如何定义损失函数&#xff1f;- 经验这里定义一个直观的loss函数根据全体数据&#xff0c;得到最好的模型参数(理想&#xff09;如何衡量现实损失和理想损失接近程度&#xff1f;如何得到跟含所有样本数据集很像的取样数据…

【java学习—十】捕获异常(2)

文章目录 1. 什么是异常2. 异常处理机制3. 捕获异常总结3.1. try 和 catch3.2. 捕获异常的有关信息&#xff1a;3.3. finally 1. 什么是异常 如果程序运行时&#xff0c;某一行出现异常&#xff0c;将会使程序中断&#xff0c;不在继续执行&#xff0c;举个例子如下&#xff1…

Kubernetes简介篇

文章目录 前言应用部署Kubernetes能做什么总结 前言 Kubernetes&#xff08;简称k8s&#xff09;是一个开源的容器编排和管理工具&#xff0c;由Google开发并捐赠给Cloud Native Computing Foundation&#xff08;CNCF&#xff09;管理。它能够自动化部署、扩展和管理容器化应…

Unity主程如何做好游戏项目管理

前言 很多小伙伴最近在面试或者考虑跳槽,可能工作了3~5年了想涨薪或想做技术总监或主程, 可自己还是个雏&#xff0c;没有做过项目技术管理&#xff0c;怎么办&#xff1f;今天我给大家梳理一下作为一个技术总监或主程你应该如何带好一个游戏项目&#xff0c;做好技术管理。接…

基于混合蛙跳算法的无人机航迹规划-附代码

基于混合蛙跳算法的无人机航迹规划 文章目录 基于混合蛙跳算法的无人机航迹规划1.混合蛙跳搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用混合蛙跳算法来优化无人机航迹规划。 …

小米14系列, OPPO Find N3安装谷歌服务框架,安装Play商店,Google

10月26号小米发布了新款手机小米14,那么很多大家需求问是否支持谷歌服务框架,是否支持Google Play商店gms。因为毕竟小米公司现在安装的系统是HyperOS澎湃OS。但是我拿到手机之后会发现还是开机初始界面会显示power by android,证明这一点他还是支持安装谷歌,包括最近一段时间发…

ASEMI高压二极管CL08-RG210参数,CL08-RG210封装

编辑-Z CL08-RG210参数描述&#xff1a; 型号&#xff1a;CL08-RG210 反向重复峰值电压VRRM&#xff1a;8000V 反向工作峰值电压VRWM&#xff1a;8000V 正向平均电流IF&#xff1a;0.5A 正向(不重复)浪涌电流IFSM&#xff1a;20A 反向恢复时间trr&#xff1a;80ns 正向…

spring-基于注解管理bean

基于注解管理bean 一、标记与扫描1、引入依赖2、创建spring配置文件3、创建组件4、扫描组件4.1、基本扫描&#xff1a;4.2、指定要排除的组件4.3、仅扫描指定组件 二、基于注解的自动装配 一、标记与扫描 1、引入依赖 <dependencies> <!-- 基于Maven依赖传递性&…

图像特征Vol.1:计算机视觉特征度量|第一弹:【纹理区域特征】

目录 一、前言二、纹理区域度量2.1&#xff1a;边缘特征度量2.2&#xff1a;互相关和自相关特征2.3&#xff1a;频谱方法—傅里叶谱2.4&#xff1a;灰度共生矩阵(GLCM)2.5&#xff1a;Laws纹理特征2.6&#xff1a;局部二值模式&#xff08;LBP&#xff09; 一、前言 &#x1f…

RocketMq源码分析(八)--消息消费流程

文章目录 一、消息消费实现二、消息消费过程1、消息拉取2、消息消费1&#xff09;提交消费请求2&#xff09;消费消息 一、消息消费实现 消息消费有2种实现&#xff0c;分别为&#xff1a;并发消费实现&#xff08;ConsumeMessageConcurrentlyService&#xff09;和顺序消费实现…

vue3-vite-ts-pinia

Vue3 vite Ts pinia 实战 源码 electron 仓库地址&#xff1a;https://gitee.com/szxio/vue3-vite-ts-pinia 视频地址&#xff1a;小满Vue3&#xff08;课程导读&#xff09;_哔哩哔哩_bilibili 课件地址&#xff1a;Vue3_小满zs的博客-CSDN博客 初始化Vue3项目 方式一 …