C语言—字符函数和字符串函数

news2024/11/24 6:21:44

字符函数和字符串函数

  • strlen
  • strcpy
  • strcat
  • strcmp
  • strncpy
  • strncat
  • strncmp
  • strstr
  • strtok
  • strerror
  • perror
  • 字符分类函数
  • 字符转换函数
  • memcpy
  • memmove
  • memmcmp
  • memset

C语言中对字符和字符串的处理很是频繁,但是C语言本身是没有字符串类型的,字符串通常放在 常量字符串中或者字符数组中。字符串常量适用于那些对它不做修改的字符串函数。

strlen

strlen函数的介绍

size_t strlen ( const char * str );

strlen函数用于求字符串的长度

注:

  • 字符串已经 ‘\0’ 作为结束标志,strlen函数返回的是在字符串中 ‘\0’ 前面出现的字符个数(不包含 ‘\0’ )。
  • 参数指向的字符串必须要以 ‘\0’ 结束。否则strlen函数计算出字符串的长度可能是随机值
  • 函数的返回值为size_t,是无符号的。

strlen函数的使用

int main()
{
	char arr[] = "abc";
	int len  = strlen(arr);  	

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

	return 0;
}

strlen函数的模拟实现

size_t my_strlen(const char* str)
{
	size_t count = 0;//计数器
	assert(str != NULL);

	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

经典面试题

在这里插入图片描述

注:

  • strlen函数的返回类型是无符号整型,上面的代码的if语句中的表达式会进行算术转换。
  • 库函数中strlen的模拟实现返回类型是无符号整形这是因为字符串的长度不可能是负数(一定是大于等于0的);而在模拟实现strlen函数时返回类型可以是整形这样可以避免上述代码中所出现的情况

strcpy

strcpy函数的介绍

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

strcpy用于字符串的拷贝

注:

  • 源字符串必须以 ‘\0’ 结束。
  • strcpy函数会将源字符串中的 ‘\0’ 拷贝到目标空间。
  • 目标空间必须足够大,以确保能存放源字符串。
  • 目标空间必须可变。(目标空间可以是栈区、堆区,不可以是字符常量区)

strcpy函数的使用

int main()
{
	
	char arr1[20] = "###########";
	//arr = "hello";//err    arr数组名是首元素的地址,地址是编号,hello不能放在编号上应该放在编号所指向空间里
	char* p1 = "hello";
	strcpy(arr1, p1);   //hello'\0'#####

	char arr2[] = { 'a', 'b', 'c' };
	//strcpy(arr1, arr2); //err 会发生指针越界访问,程序崩溃

	char* str = "xxxxxxxxxxxxxxxxxxx";
	char* p2 = "hello world";
	//strcpy(str, p2);//err 程序崩溃,目标空间必须是可修改的


	return 0;
}

strcpy函数的模拟实现

char *my_strcpy(char *dest, const char*src) 
{ 
 	char *ret = dest; 
 	assert(dest != NULL); 
 	assert(src != NULL); 
 	while((*dest++ = *src++)) 
 	{ 
 		; 
 	} 
 	return ret; 
}

strcat

strcat函数的介绍

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

strcat用于字符串追加(字符串连接)

注:

  • 源字符串必须以 ‘\0’ 结束。目标字符串必须以’\0’ 结束
  • 目标空间必须有足够的大,能容纳下源字符串的内容。
  • 目标空间必须可修改
  • 使用strcat函数时字符串不能自己给自己追加('\0’被覆盖从而找不到结束标志,导致死循环)

strcat函数的使用

int main()
{
	char arr1[20] = "hello \0#########";
	char arr2[] = "world";
	strcat(arr1, arr2);//字符串追加(连接)
	printf("%s\n", arr1);    //hello world'\0'####

	return 0;
}

strcat函数的模拟实现

char* my_strcat(char* dest, const char*src)
{
	char* ret = dest;
	assert(dest && src);
	//1. 找目标字符串中的\0
	while (*dest)
	{
		dest++;
	}
	//2. 追加源字符串,包含\0
	while(*dest++ = *src++)
	{
		;
	}

	return ret;//返回的目标空间的起始地址
}

strcmp

strcmp函数的介绍

int strcmp ( const char * str1, const char * str2 );

strcmp用于比较两个字符串的大小的

注:

  • 第一个字符串大于第二个字符串,则返回大于0的数字
  • 第一个字符串等于第二个字符串,则返回0
  • 第一个字符串小于第二个字符串,则返回小于0的数字

strcmp函数的使用

int main()
{

	//strcmp - 字符串比较大小的

	int ret1 = strcmp("aaa", "aaa");
	printf("%d\n", ret1);

	int ret2 = strcmp("abbb", "abq");//-1
	printf("%d\n", ret2);

	int ret3 = strcmp("abbb", "ab");//1
	printf("%d\n", ret3);
	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 my_strcmp(const char* s1, const char* s2)
{
	assert(s1 && s2);
	while (*s1 == *s2)
	{
		if (*s1 == '\0')
		{
			return 0;
		}
		s1++;
		s2++;
	}
	return *s1 - *s2;
}

注:C语言标准规定strcmp库函数实现时满足如果第一个字符串大于第二个字符串返回大于零的数,如果第一个字符串小于第二个字符串返回小于零的数,如果第一个字符串等于第二个字符串返回等于零的数即可。而VS编译器中在实现strcmp时第一个字符串大于第二个字符串返回1,第一个字符串小于第二个字符串返回-1,第一个字符串等于第二个字符串返回0。这只是在VS编译器中strcmp返回值是这样的而在其他编译器下strcmp的返回值就不一定是1,-1,0,但是在所有编译器下strcmp函数的返回值一定是大于零、小于零、等于零(因为这是C语言标准规定的)

strncpy

strncpy函数的介绍

char * strncpy ( char * destination, const char * source, size_t num );

strncpy用于拷贝num个字符

注:

  • 拷贝num个字符从源字符串到目标空间。
  • 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
  • VS编译器中的strcpy_s函数相当于是strncpy函数的一种版本,但是相较于strncpy增添了一些机制
  • strncpy中的num如果大于源字符串中的字符个数,拷贝完源字符串中的字符之后会自动在目的字符串之后将剩余的num个字符补’\0’

strncpy函数的使用

int main()
{
	char arr1[20] = "abcdefghi";
	char arr2[] = "qwer";
	strncpy(arr1, arr2, 6);  //qwer\0\0ghi

	char arr3[20] = "abcdef";
	strncpy(arr3, arr2,2);  //qwcdef

	return 0;
}

strncpy函数的实现

在这里插入图片描述

strncat

strncat函数的介绍

char * strncat ( char * destination, const char * source, size_t num );

strncat用于追加num个字符

注:

  • strncat函数中的num如果大于源字符串中的字符个数,那么在追加到源字符串中的‘\0’时会自动结束(无论num还有多少没追加)。如果小于源字符串中的字符个数,那么追加num个源字符串中的字符会在目的字符串之后自动添加’\0’

strncat函数的使用

int  main()
{
	char arr1[20] = "hello ";       
	char arr2[] = "world";
	strncat(arr1, arr2, 10);  	//hello world\0


	char arr3[20] = "hello ";
	char arr4[] = "world";
	strncat(arr3, arr4, 3);  //hello wor\0


	return 0;
}

strncat函数的实现

在这里插入图片描述

strncmp

strncmp函数的介绍

int strncmp ( const char * str1, const char * str2, size_t num );

strncmp用于比较num个字符

注:

  • 比较到出现另个字符不一样或者一个字符串结束或者num个字符全部比较完。

在这里插入图片描述

strncmp函数的使用

int main()
{
	char* p = "abcdef";
	char* q = "abcqwert";
	int ret1 = strcmp(p, q);  //-1
	int ret2 = strncmp(p, q, 3);  //0
	int ret3 = strncmp(p, q, 4);  //-1

	return 0;
}

strncmp的实现

在这里插入图片描述

注:

  • strcmp、strcpy、strcat都是长度不受限制的字符串函数
  • strncmp、strncpy、strncat都是长度受限制的字符串函数

strstr

strstr函数的介绍

char * strstr ( const char * str1, const char * str2 );

strstr函数用于在字符串中找另一个字符串

注:

  • 如果strstr函数找到了str2所指向的字符串在str1所指向字符串中的位置,那么返回一个在str1所指向的字符串中第一次出现str2所指向的字符串的指针。如果strstr函数没有找到str2所指向的字符串在str1所指向字符串中的位置,那么返回一个空指针

strstr函数的使用

int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";

	//在arr1中查找是否包含arr2数组
	char* ret = strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("没找到\n");
	}
	else
	{
		printf("找到了:%s\n", ret);
	}
	return 0;
}

strstr函数的模拟实现

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

	if (*str2 == '\0')
	{
		return (char*)str1;
	}

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

	return NULL;
}

注:

  • strstr库函数在VS编译器中也是用上面的方法实现的
  • KMP算法(KMP算法是字符串查找算法的一种)比暴力查找算法效率要高

字符串匹配算法(BF算法&&KMP算法)

strtok

strtok函数的介绍

char * strtok ( char * str, const char * sep );

strtok函数用于切割字符串的

注:

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

strtok函数的使用

int main()
{
	char arr[] = "lc17612269709@163.com hello";
	char* p = "@. ";
	char tmp[30] = { 0 };
	strcpy(tmp, arr);
	
	char* ret = NULL;

	for (ret = strtok(tmp, p); ret != NULL; ret=strtok(NULL, p))
	{
		printf("%s\n", ret);
	}

	//lc17612269709\0163\0com\0hello


	return 0;
}


注:

  • strtok函数实现记忆功能需要通过静态变量(猜测),它会每次记录上一次查找分隔符标记的位置。
  • 如果一个函数是依赖于全局变量,这个函数就不够通用不够灵活。
  • strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。
  • 分割字符串时不能用’\0’作为分割符去分割字符串(字符串的结束标志是’\0’)

strerror

  • 使用库函数的时候,调用库函数失败时都会设置错误码。

  • C语言中存在全局的错误码(int errno;)(全局变量),只要调用库函数发生了错误就把错误码放到这个errno变量里

  • 使用全局错误码需要引用头文件errno.h

char * strerror ( int errnum );

strerror函数用于打印错误码对应的错误信息

注:

  • strerror函数返回错误码,所对应的错误信息

strerror函数的使用

实例一:
在这里插入图片描述

实例二:

在这里插入图片描述

perror

void perror ( const char * str );

perror函数用于打印错误信息

注:

  • strerror函数是把错误码转换成错误信息,是否需要打印看程序员需求
  • perror函数直接打印错误信息
  • perror函数的功能是把错误码转化为错误信息),再打印错误信息(包含了自定义的信息)。
  • perror函数用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数str所指的字符串会先打印出,加上:后面再加上错误原因字符串。此错误原因依照全局变量errno的值来决定要输出的字符串。

perror函数的使用

实例一:

在这里插入图片描述

字符分类函数

函数如果它的参数符合下列条件就返回真
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任何可打印字符,包括图形字符和空白字符

字符分类函数的使用:

实例一:isdigit

#include<stdio.h>
#include<ctype.h>
int main()
{
	char ch = '#';
	int ret = isdigit(ch);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述

#include<stdio.h>
#include<ctype.h>
int main()
{
	char ch = '0';
	int ret = isdigit(ch);
	printf("%d\n", ret);
	return 0;
}

在这里插入图片描述

;isdigit 如果是数字字符返回非0的值,如果不是数字字符返回0

实例二:islower

在这里插入图片描述
在这里插入图片描述
:用法与上方isdigit类似

字符转换函数

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

字符转换函数的使用:

实例一:

#include<stdio.h>
#include<ctype.h>
int main()
{
	char arr[20] = { 0 };
	scanf("%s", arr);
	int i = 0;
	while (arr[i] != '\0')
	{
		if (isupper(arr[i]))
		{
			arr[i] = tolower(arr[i]);
			
		}
		printf("%c", arr[i]);
		i++;
	}
	return 0;
}

在这里插入图片描述

注:toupper用法与tolower用法类似

memcpy

本函数需要调用string.h的头文件

void * memcpy ( void * destination, const void * source, size_t num );

memcpy函数用于内存拷贝(不包括内存重叠)

注:

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

memcpy函数的使用:

#include<string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	memcpy(arr2, arr1, 20);
	return 0;
}

在这里插入图片描述

memcpy函数的模拟实现:

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dst, const void* src, size_t num)
{
	void* ret = dst;
	assert(dst && src);
	
	while (num--)
	{
		*(char*)dst = *(char*)src;
		dst = (char*)dst + 1;
		src = (char*)src + 1;
	}
	return ret;
}

注意:建议使用上面实现字节拷贝的方法(这种是没问题的),不建议使用*(char *)dst++ = *(char *)src++;这样的字节拷贝方法(在.c源文件下可以编过,但在.cpp源文件下不可以编过(这种方法是有问题的))。

补充:

#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dst, const void* src, size_t num)
{
	void* ret = dst;
	assert(dst && src);
	
	while (num--)//4 3 2 1
	{
		*(char*)dst = *(char*)src;
		dst = (char*)dst + 1;
		src = (char*)src + 1;
		//*(char*)dst++ = *(char*)src++;
	}
	return ret;
}

int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[20] = { 0 };
	my_memcpy(arr1+2, arr1, 20);
	return 0;
}

在这里插入图片描述
解析
在这里插入图片描述
注:memcpy函数应该拷贝不重叠的内存

注:C语言标准规定memcpy函数只要实现不重叠拷贝即可,而VS中的实现既可以拷贝不重叠也可以拷贝重叠内存

memmove

void * memmove ( void * destination, const void * source, size_t num );

memmove函数用于内存拷贝(包括内存重叠)

注:

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

memmove函数的使用:

#include<stdio.h>
#include<string.h>
int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	memmove(arr1+2, arr1, 20);
	return 0;
}

在这里插入图片描述
注:memcpy函数只要实现不重叠拷贝就可以了,而VS中实现即可以拷贝不重叠也可以拷贝重叠内存

memmove函数的模拟实现

分析
在这里插入图片描述

#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest, const void* source, size_t num)
{

	assert(dest && source);
	void* ret = dest;
	void* r = dest;
	void* s = source;
	if (dest < source)
	{
		//从前向后
		while (num--)
		{
			*(char*)dest = *(char*)source;
			dest = (char*)dest + 1;
			source = (char*)source + 1;
		}
		return ret;
	}
	else
	{
		//从后向前
		while (num--)
		{
			r=(char*)dest + num;
			s=(char*)source + num;
			*(char*)r = *(char*)s;
			//*((char*)dest + num) = *((char*)source + num);
		}
		return ret;
	}
}

memmcmp

int memcmp ( const void * ptr1, const void * ptr2, size_t num ); 

memcmp函数用于内存比较

注:

  • 比较从ptr1和ptr2指针开始的num个字节
  • 返回值与strcmp类似(返回值设计思路一样)

memcmp函数的使用:

int main()
{
	float arr1[] = { 1.0,2.0,3.0,4.0 };
	float arr2[] = { 1.0,3.0 };
	int ret=memcmp(arr1, arr2, 8);
	printf("%d\n", ret);
	return 0;
}

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

memset

 void * memset ( void * ptr, int value, size_t num ); 

memset函数用于内存设置

注:

  • 指的是前ptr所指向的num个字节的内容设置成指定的value的值
  • memset函数功能是以字节为单位设置内存的

memset函数的使用:

int main()
{
	int arr[10] = { 0 };
	memset (arr,1,20 );
	return 0;
}

在这里插入图片描述

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

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

相关文章

ChatGPT最强对手Claude如何无门槛使用?

Claude&#xff0c;一个冉冉升起的新星&#xff0c;由 chatgpt 团队出来的员工开发的&#xff0c;由于他们对模型的一些发展理念不同&#xff0c;单独融资创建了 Claude&#xff0c;总体来说表现可圈可点&#xff0c;但整体看可能还不如 chatgpt4.0。 ChatGPT 眼中的 Claude C…

【产品应用】一体化电机在卡盘设备中的应用

在现代工业生产中&#xff0c;自动化程度的提高和生产效率的提升对于生产设备的要求也越来越高。卡盘设备作为自动化生产线中的重要组成部分&#xff0c;其设计和制造也必须适应现代工业的需求。一体化电机在卡盘设备中的应用&#xff0c;不仅可以提高生产效率和精度&#xff0…

线程状态是五种还是六种

从操作系统层面上描述线程状态 初始状态&#xff1a;仅仅是语言层面创建了线程对象,还没有与操作系统相关联.比如new 了一个Thread对象还没有调用start方法可运行状态&#xff1a;仅仅是语言层面创建了线程对象,还没有与操作系统相关联.比如new 了一个Thread对象还没有调用s…

微服架构基础设施环境平台搭建 -(二)Docker私有仓库Harbor服务搭建

微服架构基础设施环境平台搭建 -&#xff08;二&#xff09;Docker私有仓库Harbor服务搭建 通过采用微服相关架构构建一套以KubernetesDocker为自动化运维基础平台&#xff0c;以微服务为服务中心&#xff0c;在此基础之上构建业务中台&#xff0c;并通过Jekins自动构建、编译、…

【数学杂记】表达式中的 s.t. 是什么意思

今天写题的时候遇见了这个记号&#xff1a;s.t.&#xff0c;查了一下百度。 s.t.&#xff0c;全称 subject to&#xff0c;意思是“使得……满足”。 比如这个&#xff1a; 意思是存在 i i i&#xff0c;使得 i i i 满足 A i ≠ B i A_i\neq B_i Ai​Bi​. 运用这个记号…

MySQL面试题1(索引)

目录 1.MySQL如何实现索引机制 1.1InnoDb与MyISAM索引实现区别是是什么&#xff1f; 1.2一个表中如果没有创建索引&#xff0c;还会创建B树么&#xff1f; 2.说一下B树索引实现原理&#xff08;数据结构&#xff09; 2.1聚簇索引和非聚簇索引在B树实现区别是什么&#xff1…

【Python每日一练】总目录(更新至2023.5.12)

Python 2023.05 2023.05.11-2023.05.12 20230512 1. 跳跃游戏 V 2. 跳跃游戏 VI 3. 跳跃游戏 VII 20230511 1. 跳跃游戏 Jump Game I 2. 跳跃游戏 Jump Game II 3. 跳跃游戏 Jump Game III 4. 跳跃游戏 Jump Game IV 2023.05.01-2023.05.10 20230510 1. 石子游戏 Ston…

[googletest] --- 简易使用教程

1 googletest下载/官方sample分析 1.1 googletest源码下载编译 源码下载编译 // 下载 git clone https://github.com/google/googletest // 现在官方已经把 gtest 和 gmock 一起维护&#xff0c;所以这个 git 仓库还包含了 gmock。// 编译、安装 cd googletest-main mkdir b…

【申请教程】ChatGPT访问互联网插件

https://openai.com/blog/chatgpt-plugins 大家好&#xff0c;我是章北海mlpy 申请ChatGPT插件很久了&#xff0c;一直没下文 最近看到两种套路&#xff0c;我早上试了一下&#xff0c;看能否快速成功吧。 方法一&#xff1a;用ChatGPT帮忙写申请文案 [外链图片转存失败,源…

大数据如何助力营销(2)用户画像

用户画像是指根据用户的数据&#xff0c;构建出用户的特征和兴趣&#xff0c;从而对用户进行分类和个性化的过程。用户画像可以帮助营销人员更有效地触达目标客户&#xff0c;提高营销效果和转化率。 用户画像的价值 用户画像的价值主要体现在以下几个方面&#xff1a; 提升用…

IP协议介绍

文章目录 一、IP协议的基本认识二、IP的协议头格式三、网段划分四、特殊的IP地址五、IP地址的数量限制六、私有IP地址和公网IP地址 一、IP协议的基本认识 IP在网络分层中属于网络层协议&#xff0c;传输层协议里的TCP协议解决的是可靠性问题&#xff0c;网络层协议里的IP协议能…

VScode自动滚屏cin、input输入问题解决方法

文章目录 前言一、输出自动滚屏二、解决cin或input之类的输入问题总结 前言 VScode 是一个轻量的文本编辑器&#xff0c;微软出品。很多人把它作为主要开发工具写代码&#xff0c;因为它几乎是万能的&#xff0c;想要什么功能就装什么插件&#xff0c;可以适用于几乎任何编程语…

如何和AI聊天

AI产品工具目录&#xff1a;AI产品目录 Prompt 在和AI聊天时&#xff0c;你得表明你需要啥&#xff0c;并且描述的越精确&#xff0c;AI回答的就越贴近你的预期&#xff0c;简单的对话&#xff0c;可以自己尝试&#xff0c;但是如果想做应用级别的就得学习这种聊天技术&#…

Flask celery异步发送邮件

首先安装celery pip install celery安装redis 一、Redis for Windows下载 之前微软维护了一份Windows版本的Redis&#xff0c;但是版本停留在3.2&#xff0c;并且也关闭了项目更新渠道。这里我们使用另外一位大神提供的Windows Redis&#xff0c;更新及时&#xff0c;用户量也…

[VAE] Auto-Encoding Variational Bayes

直接看paper看得云里雾里&#xff0c;李沐视频一语道破天机&#xff08;建议从30min左右开始看GAN到Diffusion的串讲&#xff09;。VAE的核心思路就是下面&#xff1a; 做生成&#xff0c;其实就是从随机向量&#xff08;z&#xff09;到目标图像&#xff08;x&#xff09;的过…

研报精选230512

目录 【行业230512山西证券】有色金属行业周报&#xff1a;基本金属普跌&#xff0c;锂价持续回弹 【行业230512湘财证券】新材料行业周报&#xff1a;五一前后各板块震荡下行&#xff0c;节后稀土价格跌后企稳&#xff0c;锂源现止跌迹象 【行业230512山西证券】基础化工2022年…

obj导入unity顶点数量改变

obj文件&#xff0c;是个cube&#xff0c;里面有8个顶点12个面。 # 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware # 创建的文件:11.04.2023 13:05:22# # object Box001 #v -15.0000 -15.0000 15.0000 v -15.0000 -15.0000 -15.0000 v 15.0000 -15.0000 -15.0…

C高级-day(5)-(分支语句、循环结构、函数....)

题目一、 有m1.txt m2.txt m3.txt m4.txt&#xff0c;分别创建出对应的目录&#xff0c;m1 m2 m3 m4 并把文件移动到对应的目录下 #! /bin/bashtouch m1.txt m2.txt m3.txt m4.txt for i in seq 1 1 4 domkdir m$imv m$i.txt m$i done 题目二、 使用break关键字打印九九乘法…

BERT-pytorch源码分析

​学习bert可以下载一些数据集练练手&#xff0c;目前打算选择官网给出GLUE的数据集。 bert整体代码框架结构如下&#xff1a; 首先从main文件开始解读&#xff0c;打开__main__.py。这里面只有import导入语句和一个train函数。 train函数里面首先是对一些路径参数的填写&a…

unity用ComputeShader做模型流体喷涂喷绘工具

最近在研究喷涂喷绘项目&#xff0c;需要做大量纹理图形运算&#xff0c;因此更适合用GPU来处理&#xff0c;在unity中用ComputeShader完成像素运算&#xff0c;SurfaceShader完成纹理渲染。 实现思路&#xff1a; 1.用射线碰撞模型&#xff0c;得到碰撞纹理坐标brushX和brus…