C语言——详解字符函数和字符串函数(一)

Hi,铁子们好呀!今天博主来给大家更一篇C语言的字符函数和字符串函数~
具体讲的内容如下:


文章目录
- 🎆1.字符分类函数💯💯
- ⏩1.1 什么是字符分类函数的?💯💯
- ⏩1.2 字符函数的类型有哪些?💯💯
- ⏩1.3 字符函数`islower`介绍及模拟实现💯💯
- ⏩1.3.1`islower`函数具体介绍💯💯
- ⏩1.3.2`islower`函数代码实现及效果💯💯
- ⏩1.4字符分类函数练习💯💯
- 🎆2.字符转换函数💯💯
- ⏩2.1代码实现💯💯
- 🎆 3.strlen的使用和模拟实现💯💯
- ⏩3.1strlen函数的使用💯💯
- ⏩3.1.1 strlen函数相关练习💯💯
- ⏩3.2 strlen函数三种模拟实现💯💯
- ⏩3.2.1 创建临时变量count💯💯
- ⏩ 3.2.2 指针-指针💯💯
- ⏩ 3.2.3 递归法求字符串长度💯💯
- 🎆4.strcpy的使用和模拟实现💯💯
- ⏩4.1 strcpy的使用规则💯💯
- ⏩4.2 strcpy函数的基本使用💯💯
- ⏩4.3 strcpy函数的模拟实现💯💯
- ⏩4.3.1 strcpy函数的模拟实现方法1💯💯
- 🎆5.strcat的使用和模拟实现💯💯
- ⏩5.0.1 strcat函数简单介绍💯💯
- ⏩5.0.1.1什么是strcat函数呢?函数原型是什么?💯💯
- ⏩5.1 strcat的使用规则💯💯
- ⏩5.2 strcat的使用和模拟实现💯💯
- ⏩ 5.2.1strcat的使用💯💯
- ⏩ 5.2.2 strcat的模拟实现💯💯
前言: 在编程的过程中,我们经常要处理字符和字符串,C语言标准库中提供了一系列库函数,接下来我们就学习一下这些函数。
🎆1.字符分类函数💯💯
⏩1.1 什么是字符分类函数的?💯💯
众所周知,C语言中提供了一系列的字符函数,这些字符函数专门做字符分类的。
通俗点来讲: 这些函数就是判断这个字符是属于什么类型的字符的。
需要注意的是: 这些字符函数都需要包含头文件#include<ctype.h>。
⏩1.2 字符函数的类型有哪些?💯💯
如下图所示:
从图中,我们发现这些函数的使用方法其实非常类似,我们这里就讲一个字符函数
islower吧,其他函数的实现方法也是跟这个比较类似~
⏩1.3 字符函数islower介绍及模拟实现💯💯
islower函数原型如下:
int islower(int c);
⏩1.3.1islower函数具体介绍💯💯
如下两图所示:


分析: 从这两幅图,我们可以看出islower是判断它的函数参数部分的c是否为小写字母的。
我们可以通过返回值来说明是否是小写字母,如果是小写字母就返回非0的整数,如果不是小写字母,则返回0。
⏩1.3.2islower函数代码实现及效果💯💯

代码如下:
#include <stdio.h>
#include <ctype.h>
int main() {int ret = islower('C');printf("%d\n", ret);return 0;
}

从动图中: 我们直观地看出如果islower函数的参数部分是小写字母,返回的是非0的数字。如果参数部分是大写字母或者其他类型的字符,则返回0。
好,讲到这里,相信同学们就知道字符分类函数怎么用了,大家可以下去尝试一下,多实践~
⏩1.4字符分类函数练习💯💯
练习:
写一个代码,将字符串中的小写字母转大写,其他字符不变。
那这道题我们应该怎么思考呢?
我们来看下图:

我们来看下面的Ascll码值,可以看出大写字母'A'和'B'的Ascll码值分别为65和66,小写字母'a'和'b'的Ascll码值分别为97和98。
所以我们可以得出一个结论: 大写和小写的Ascll码值分别相差32。
当我们知道这个结论,这题就很好做了,我们可以先创建一个字符数组,用islower函数遍历每一个字符,如果是小写字母,就让它的ASCLL码值-32即可。
当我们把题目分析成这样,代码自然可以顺理成章地写出来。
#include <stdio.h>
#include <ctype.h>
int main() {int i = 0;char str[] = "Test String.";while (str[i]) {if (islower(str[i])) {str[i] -= 32;}i++;}printf("%s\n", str);return 0;
}
这里我们要提醒一下:我们知道
\0是字符串的结束标志,所以当while循环中的str[i]为\0时,也就是为假,这是为什么呢?
如下图:
我么可以看出\0对应的ASCLL码值为0,那0为假,便跳出while循环,然后我们再来看printf部分,它这里是以%s的形式打印,那以%s本质上就是从那个地址开始,往后打印字符串,直到遇到\0为止。而这里的str恰好是数组名,我们之前就在这篇文章:C语言-指针讲解(2)讲过数组名是数组首元素的地址。所以这里本质上就是从arr首字符地址开始打印,直到遇到\0为止。
🎆2.字符转换函数💯💯
C语言提供了2个字符转换函数
它们的函数原型如下:
1 int tolower ( int c ); //将参数传进去的大写字母转小写
2 int toupper ( int c ); //将参数传进去的小写字母转大写
上面我们写的代码将小写字母转换为大写,是ASCLL码值-32完成的效果。但有了转换函数,就可以直接使用tolower函数。
⏩2.1代码实现💯💯

#include <stdio.h>
#include <ctype.h>
int main() {int i = 0;char str[] = "Test String.";while (str[i]) {if (islower(str[i])) //判断该字符是否为小写字母{str[i] = toupper(str[i]);//将对应字符的小写字母转换为大写字母}i++;}printf("%s\n",str);//从str的首元素地址开始打印字符串,直到遇到'\0'为止。return 0;
}
vs运行效果图:
🎆 3.strlen的使用和模拟实现💯💯
它的函数原型如下:
size_t strlen( const char*str)
strlen的函数使用规则如下:
- 字符串以
'\0'作为结束标志,strlen函数返回到是在字符串中'\0'前面出现的字符个数(不包含'\0')。- 参数指向的字符串必须要以
'\0'结束。- 注意函数的返回值为
size_t,是无符号的(易错)strlen的使用需要包含头文件#include<string.h>
⏩3.1strlen函数的使用💯💯
好,这里首先讲一下strlen函数的基本使用
代码如下:
#include<stdio.h>
#include<string.h>
int main() {char arr[] = "abcdef";//字符串是以'\0'为结束标志的printf("%zd\n", strlen(arr));//这里因为strlen函数是size_t类型,所以最好用%zd打印,以防vs弹出警告//需要注意的是:strlen函数计算的是'\0'之前的字符个数return 0;
}
相信同学们看了上面的代码以及注释,应该能够理解代码的逻辑。
VS运行效果:
⏩3.1.1 strlen函数相关练习💯💯
刚刚我们讲到了要注意strlen函数的返回值为size_t,这是为什么呢?下面我们来看一下这个代码案例。
代码如下:
#include <stdio.h>
#include <string.h>
int main() {const char* str1 = "abcdef";const char* str2 = "bbb";if (strlen(str2) - strlen(str1) > 0) {printf("str2>str1\n");}else {printf("str1>str2\n");}return 0;
}
这道题想必很多同学是这么想: 由于那个str1和str2数组存放的是字符串首字符的地址,那strlen函数就是计算\0之前的字符个数。
那他们肯定觉得strlen函数计算str2数组的字符个数为3个,str1数组的字符个数为6个。所以肯定会认为strlen(str2)-strlen(str1)那个语句就是3-6=-3,是<0。
那肯定会打印str1>str2这句话。那这是不对的。
我们不妨先用VS测试这个代码,看看运行效果是怎么样先~

我们发现它确实执行else语句那句话,为什么呢?别急,接下来博主给你娓娓道来!

因为本质上那个strlen函数计算字符串的相加相减都本质上都是无符号的整数的减法,
那它们相减,得出的数也是无符号整数的,肯定也会大于0。这是为什么呢?
看下图:

相信同学们看了这个图,也能够理解更加理解这个无符号整数的意思。
因为无符号整数就是不会考虑符号位,只是关注数值位。并且无符号整数是使用该数的二进制补码来存储。因此它的数肯定是大于0的。
好,相信同学们听到这里,也会理解这个代码的逻辑了~
那如果说我们真想让代码执行>
str1>str2\n那句话,该怎么做呢?
我们可以这么做,将strlen这个函数无符号size_t类型强制转换为int整型,那这样就可以打印"str2>str1\n"那句话。
VS代码运行效果:
通过执行结果,我们发现程序的确执行str1>str2那句话。
好,相信讲到这里,同学们应该就理解了。那我们接着就讲三种模拟实现strlen函数~
⏩3.2 strlen函数三种模拟实现💯💯
⏩3.2.1 创建临时变量count💯💯
代码如下:
#include <stdio.h>
#include <stdio.h>
size_t my_strlen(char* s)//这里我们函数my_strlen类型写成size_t,这是因为字符串的长度绝对是大于0等于0的,因此我们直接就写成size_t类型就行{int count = 0;//创建临时变量count,初始化为0while (*s)//当*s=='\0','\0'对应的ASCLL码值为0,0为假,便跳出while循环。{count++;//随着变量字符指针s往后遍历,count变量的值不断自增s++;//字符指针往后遍历}return count;
}int main() {char str[] = "abcdef";size_t ret = my_strlen(str);//这里我们是将str首元素地址传过去printf("%zd\n", ret);//因为这是用size_t数据类型创建的变量ret,所以我们使用%zd来格式化输出。return 0;
}
相信同学们看了这个代码,以及这个注释,是能够理解这个代码逻辑的。
VS运行效果如下:
⏩ 3.2.2 指针-指针💯💯
代码如下:
#include <stdio.h>
#include <stdio.h>
size_t my_strlen(char* s)//这里我们函数my_strlen类型写成size_t,这是因为字符串的长度绝对是大于0等于0的,因此我们直接就写成size_t类型就行
{char* ptr = s;//这里是将字符串首元素地址赋给指针变量ptrwhile (*s)s++;//只要*s不是'\0',*s都往后遍历return s - ptr;//这里本质上把字符指针s最后的地址-ptr首元素的地址,这样就能得到两个指针相差的元素个数。
}
int main() {char str[] = "abcdef";size_t ret = my_strlen(str);//这里我们是将str首元素地址传过去printf("%zd\n", ret);//因为这是用size_t数据类型创建的变量ret,所以我们使用%zd来格式化输出。return 0;
}
相信同学们看了这个代码,以及这个注释,是能够理解这个代码逻辑的。
VS运行效果如下:
⏩ 3.2.3 递归法求字符串长度💯💯
这里的递归法求字符串长度估计很多同学比较懵,我们先画个图分析先:
如下:

相信同学们看了这个图,自己应该能够很好地理解递归这个方法,大家可以自己尝试自己用递归法实现这个算法~
要是还想不出来,博主这里直接上代码~

代码如下:
#include <stdio.h>
#include <stdio.h>
size_t my_strlen(char* s)//这里我们函数my_strlen类型写成size_t,这是因为字符串的长度绝对是大于0等于0的,因此我们直接就写成size_t类型就行
{if (*s == '\0') {return 0;//当*s指向的元素为'\0',直接返回0,用作递归的结束条件}else {return 1 + my_strlen(s + 1);//如果*s指向的元素不是'\0',那么说明字符串里面的字符最少都有1个,因此我们就返回1+后面字符串中字符的长度。}}int main() {char str[] = "abcdef";size_t ret = my_strlen(str);//这里我们是将str首元素地址传过去printf("%zd\n", ret);//因为这是用size_t数据类型创建的变量ret,所以我们使用%zd来格式化输出。return 0;
}
这里博主这里简单画了递归调用图,大家可以看一下理解理解~
VS运行效果图如下:
我们发现,用递归法实现的算法,它的结果也是6。
🎆4.strcpy的使用和模拟实现💯💯
strcpy它的函数原型如下:
char* strcpy(char * destination, const char * source );
这里我们来解读一下,这里
destination指的是目标位置的起始地址,source指的是所要拷贝那个字符串内容的起始地址。
好,我们就细细地讲一下它的规则吧~
⏩4.1 strcpy的使用规则💯💯
- 源字符串必须以’\0’结束。
- 会将源字符串中的’\0’拷贝到目标空间。
- 目标空间必须足够大,以确保能存放源字符串
- 目标空间必须可修改
好,当我们介绍了strcpy的规则后,接下来博主将给大家讲解strcpy的模拟实现。
⏩4.2 strcpy函数的基本使用💯💯
好,接下来博主给大家演示一下strcpy函数的基本使用。

代码如下:
#include<stdio.h>
#include<string.h>
int main() {char arr1[] = "abcdef";//这里的arr1数组是默认有'\0'的,因为字符串是以'\0'为结束标志的。char arr2[20];//这里初始化arr2数组的长度务必要确保目标内存区域足够大以容纳源字符串,否则会造成数组越界strcpy(arr2, arr1);//这里的strcpy库函数拷贝会顺便拷贝'\0'printf("%s\n", arr2);//这里打印是从arr2的首元素地址开始逐一打印字符串,直到遇到'\0'才停止。return 0;
}
相信大家看了博主写的代码以及注释,自己应该能够理解这个代码的逻辑。
VS运行效果如下:
⏩4.3 strcpy函数的模拟实现💯💯
这里可能很多同学是有点没思路的,没事,博主这里会提供思路,让大家能够深刻地理解
strcpy是怎么模拟实现的~
⏩4.3.1 strcpy函数的模拟实现方法1💯💯
首先,来看下图:

分析: 这里我们主要是通过数组遍历的方式来逐一拷贝,因为'\0'作为字符串的结束标志。所以只要arr1数组的内容不是'\0',就在while循环内部逐一进行拷贝,每拷贝一个字符,两个指针都向后偏移一个元素。
直到遇到'\0'为止。最后当arr1指向的内容为'\0',条件为假,便跳出while循环。最后我们再把arr1的内容拷到arr2中就行。
好,当我们分析成这样,代码也能顺理成章地写出来。
代码如下:
//}#include<stdio.h>
void my_strcpy(const char* src, char* dest)//*src指向的是arr1数组首元素的地址,*dest指向的是arr2数组首元素的地址
{while (*src)//当*src指向的元素是'\0',则表达式为假,便跳出while循环{*dest = *src;//将src字符串的内容一个一个地拷贝到dest中。dest++;//指针往后遍历src++;//指针往后遍历}*dest = *src;//由于之前因为*src指向的元素是'\0',所以跳出while循环,那因为\0是字符串的结束标志,之前我们没有把\0拷贝到指针变量dest中,所以这里就要把\0拷到dest。
}int main() {char arr1[] = "abcdef";char arr2[20];my_strcpy(arr1,arr2);//调用my_strcpy函数,把arr1作为源地址,将arr2作为作为目标地址printf("%s\n", arr2);//这里以%s打印实质上是拿到arr2首元素的地址,逐一往后打印字符串,直到遇到'\0'为止return 0;
}
相信同学们看了这个代码,应该是能够理解这个代码的逻辑。
vs运行效果:
但是我们认为这个代码还是有待改进的,接下来博主将细细讲一下。
首先,我们先打开官网查一下这个函数先。
如图:
从图中,我们可以看出函数返回值是char*类型的,并且我们发现它返回的是目标字符指针的起始地址,属于我们要创建个指针变量来充当destinmation的起始地址,到时直接返回这个指针变量即可。
如下:
题目分析:
//------1.参数顺序------
//函数的功能,停止条件
//3.assert判断字符串是否为空指针,assert函数头文件为:#include<assert.h>
//4.用const修饰源指针,使其内容不得修改
//5.函数返回值 char*
那同学们可以根据博主上面的改进代码分析,可以自己尝试改进上面的代码。一会我们会进行讲解~
好,如果大家看了上面的改进代码分析,还是想不到思路的话,可以看一下博主的代码以及注释,自己尝试理解消化一下。

代码如下:
#include<stdio.h>
#incldue<assert.h>
char* my_strcpy(const char* src, char* dest) //arr1,arr2
{assert(src!=NULL);//用assert断言一下,分别判断src和dest是否都为空指针assert(dest!=NULL);char* ret = dest;//创建个指针变量ret,将src字符指针首元素的地址赋给指针变量retwhile (*dest++=*src++)//这里首先是先对dest字符指针和src字符指针解引用,将src字符赋给dest,然后两个字符指针++,意思是说两个字符指针统一向后偏移一个元素,直到src字符指针指向的元素为'\0',那也就是整个表达式结果就为'\0',即为假,则跳出while循环。{;}return ret;//这里返回的是dest首元素的地址
}int main() {char arr1[] = "abcdef";char arr2[20];//创建这个arr2数组要比arr1数组空间要大,创建小了,如果源字符串的长度还比arr2数组还大,拷贝会造成数组越界my_strcpy(arr1, arr2);//调用my_strcpy函数,把arr1作为源地址,将arr2作为作为目标地址printf("%s\n", arr2);//这里以%s打印实质上是拿到arr2首元素的地址,逐一往后打印字符串,直到遇到'\0'为止return 0;
}
这个代码有个地方写得很好,就是
while (*dest++=*src++)这句话,为什么呢? 因为这里既能做到把arr1数组的内容全部拷贝到数组arr2,同时也能做到当*src='\0'的时候,表达式为假,便跳出while循环。
顺便提一下: 这个题目是出自<<高质量C/C++编程》书籍最后的试题部分。
对了,如果同学们想要这本书的电子版,可以私信博主领取,我私发给大家!
🎆5.strcat的使用和模拟实现💯💯
⏩5.0.1 strcat函数简单介绍💯💯
⏩5.0.1.1什么是strcat函数呢?函数原型是什么?💯💯
strcat函数是C语言中的一个字符串拼接函数,它的功能是在一个字符串后面追加上另外一个字符串。
它的函数原型如下:char * strcat ( char * destination, const char * source );具体函数介绍如下:
从图中: 和我们之前介绍的strcpy函数一样,返回的类型都是char*,然后它返回到也是字符指针destination的地址。
同时,我们需要注意的是:strcat函数在拼接字符串的时候会自动在合成字符串的末尾添加'\0'。
⏩5.1 strcat的使用规则💯💯
- 源字符串必须以’
\0’结束。- 目标字符串中也得有
'\0',否则没办法也不知道追加从哪里开始。- 目标空间必须有足够的大,能容纳源字符串的内容。
- 目标空间必须可修改。
⏩5.2 strcat的使用和模拟实现💯💯
⏩ 5.2.1strcat的使用💯💯
好,接下来给大家演示一下strcat是怎么用的,大家可以看一下下面的代码~
代码如下:
#include<stdio.h>
#include<string.h>
int main() {char arr1[20] = "hello ";char arr2[] = "world";strcat(arr1,arr2);//这里实质上是将arr2数组里面的内容拼接到arr1数组中,顺便带上'\0'。printf("%s\n", arr1);return 0;
}
这里如果同学们看了代码还是不太理解它strcat函数的如何进行拼接的话,不要紧~
博主刚刚对那个代码进行调试了一下,动图如下所示:

细心的话: 我们从动图可以看出,原本数组arr1的内容中的空格字符后面是跟着一个'\0'的,但是经过strcat函数的拷贝后,那个'\0'就给覆盖掉了。
另外,当strcpy函数把arr2全部内容都拷到arr1数组中,会自动在arr1合成字符串中添加一个'\0'字符。
那我们根据这个动图分析 ,自然也能将这个图给画出来,如下:

所以,它本质上还是用arr2数组中的'w'字符将'\0'给覆盖掉,在拼接后的字符串完的后面添加一个'\0',以此作为字符串的结束标志。
相信同学们看了这个图应该是能够大彻大悟的~
那博主接下来再用VS执行一下这个代码,看看分析得是否正确吧~

VS运行效果:
从运行结果来: 我们的分析是正确的,确实是把hellow world这个字符串给打印出来。
接下来,我们就讲一下那个strcat函数的模大家拟实现吧~
⏩ 5.2.2 strcat的模拟实现💯💯
这里可能也会有同学对于strcat不知道如何自己模拟实现,别急,博主分析一下你们就懂啦~
这里是我们实现strcat函数的步骤
如下图所示:

相信同学们看了这幅图,自己也许有点思路了,但是有些同学可能还是不太懂怎么实现这个算法。
那么博主这里就自己动手实践写了这个代码,并且写了详细的注释,希望同学们能够理解~
代码如下:
#include<stdio.h>
#include<string.h>
#include<assert.h>
char* my_strcat(const char*src,char*dest) //用const修饰源字符串src,以免被修改
{assert(src != NULL);assert(dest != NULL);//判断两个字符串是否为空指针//assert(src && dest);//assert断言写成这样也行,因为NULL的值就为0,&&只要左右两边任意一个表达式0,都是为假的char* ret = dest;//创建临时指针变量ret来接收dest的起始地址while (*dest) //找到dest字符串的'\0'的位置{dest++;//逐一开始往后遍历字符串dest}while (*dest++=*src++);//将src字符串的内容逐一拷贝到,直到遇到'\0'时,拷贝完成后,整个表达式为假,直接跳出while语句return ret;
}int main() {char arr1[20] = "hello ";char arr2[] = "world";char*tmp=my_strcat(arr2,arr1);//这里我们用tmp字符指针变量来接受返回的dest起始地址printf("%s\n", tmp);//这里的话主要是用arr1首元素的地址开始打印字符串,直到遇到'\0'才停止。return 0;
}
代码分析: 相信同学们看了博主写的代码以及注释,应该能够理解这个代码逻辑的,那接下来我们提一下有个代码是有改进之处的,我们发现那个
my_strcat函数中的assert断言是可以改写成assert(src && dest)。
或许有同学不理解,我们来解释一下~
如图:
我们发现那个空指针NULL是为0的。而因为之前我们讲&&逻辑与操作符的时候,但凡&&左右一侧为0,那整个表达式都为假。
好,解释了那么多,我们不妨用
VS测试一下我们的代码,看看它的运行结果是否符合我们的预期把~
VS运行效果如下:
我们发现,VS运行结果确实是符合我们预期的,就说明我们这个模拟实现strcat函数的代码逻辑上是没错的。
好,今天的内容我们暂时就讲到这里,希望大家好好吸收这篇博客中介绍的函数,下去多去用这些函数,这样才能学会的~
当然博主这次讲的字符函数和字符串函数(一)仅仅只是一小部分,后续博主会更深层地介绍其他C语言字符和字符串函数,大家就敬请期待吧~
**好,讲到这里,如果大家觉得这篇博客有哪些内容讲得还不太懂,可以私信一下博主,我会给你讲明白。 **

** 如果觉得博主不错的话,欢迎一键三连支持一下博主,谢谢大家!!!**
相关文章:
C语言——详解字符函数和字符串函数(一)
Hi,铁子们好呀!今天博主来给大家更一篇C语言的字符函数和字符串函数~ 具体讲的内容如下: 文章目录 🎆1.字符分类函数💯💯⏩1.1 什么是字符分类函数的?💯💯⏩1.2 字符函数的类型有哪…...
三款内衣洗衣机的顶级较量:希亦、小吉、由利,谁才是性价比之王?
洗衣机在我们的生活中可谓是非常常见的了,几乎每家每户都具备着一台。即便是有洗衣机,也有不少人不会将自己我贴身衣物直接扔在洗衣机里清洗,而是会自己手工手洗。这跟我们传统上的观念有很大的关系,认为把内衣、内裤等贴身衣物放…...
Java枚举多值映射应用
在日常系统交互中,经常遇到两个系统间定义的枚举不一致,在接口调用时需要转换,记录实现,方便备查。 场景 双方的支付方式定义不同,一侧为数字,一侧为英文,若使用 if 判断,则显得繁琐…...
css--浮动
一. 浮动的简介 在最初,浮动是用来实现文字环绕图片效果的,现在浮动是主流的页面布局方式之一。 二. 元素浮动后的特点 🤢脱离文档流。😊不管浮动前是什么元素,浮动后:默认宽与高都是被内容撑开࿰…...
基于有限状态机开发健壮的Nodejs/TCP客户端
有限状态机是一种数学计算模型,它描述了在任何给定时间只能处于一种状态的系统的行为。形式上,有限状态机有五个部分: 初始状态值 (initial state)有限的一组状态 (states)有限的一组事件 (events)由事件驱动的一组状态转移关系 (transition…...
javaEE13(网站第8章两个课后题)
1、对“jspservletjavabean实现分页查询”功能做如下补充: (1)记录批量删除:每个记录前添加复选框,点击批量删除,删除选中记录。 增加跳转到任意页功能。用户可改变每页记录条数。 页面&am…...
【Leetcode每日一题】 递归 - 反转链表(难度⭐)(35)
1. 题目解析 题目链接:206. 反转链表 这个问题的理解其实相当简单,只需看一下示例,基本就能明白其含义了。 2.算法原理 一、递归函数的核心任务 递归函数的主要职责是接受一个链表的头指针,并返回该链表逆序后的新头结点。递归…...
Unity基础学习
目录 基础知识点3D数学——基础Mathf三角函数坐标系 3D数学——向量向量模长和单位向量向量的加减乘除向量点乘向量叉乘向量插值运算 3D数学——四元数为何使用四元数四元数是什么四元数常用方法四元数计算 MonoBehavior中的重要内容延迟函数协同程序协同程序原理 Resources资源…...
Java并发编程学习笔记:AQS
Java并发编程学习笔记:AQS 一、底层原理核心功能同步状态管理CLH 队列和线程调度机制独占模式与共享模式模板方法设计模式自旋、阻塞与超时机制 运行流程 二、锁的公平性公平锁非公平锁 三、容器实现 JUC中的AQS(AbstractQueuedSynchronizer)…...
Github上哪些好用的工具
专注于web漏洞挖掘、内网渗透、免杀和代码审计,感谢各位师傅的关注!网安之路漫长,与君共勉! Qexo-爱写博客的师傅强烈推荐 漂亮的 Hexo 静态博客编辑器。该项目是基于 Django 的 Hexo 静态博客管理后台,支持文章管理、…...
如何确保面试流程标准化操作,避免人为因素影响**
一、背景 在招聘过程中,面试作为关键环节,其标准化操作至关重要。标准化不仅有助于提高面试效率和质量,还能减少人为因素的影响,确保公平、公正和客观。本文将从以下八个方面探讨如何确保面试流程的标准化操作。 二、明确面试标准 制定明确的面试标准和要求,确保所有面试…...
YOLOv7改进 | 更换主干网络之PP-LCNet
前言:Hello大家好,我是小哥谈。PP-LCNet是一个由百度团队针对Intel-CPU端加速而设计的轻量高性能网络。它是一种基于MKLDNN加速策略的轻量级卷积神经网络,适用于多任务,并具有提高模型准确率的方法。与之前预测速度相近的模型相比,PP-LCNet具有更高的准确性。此外,对于计…...
MySQL基础-----多表查询之子查询
目录 前言 子查询概述 1.概念 2.分类 一、标量子查询 二、列子查询 三、行子查询 四、表子查询 前言 上一期我们讲了内外连接查询以及自连接查询,那么本期我们就学习多表查询的子查询。本期会详细讲解什么是子查询,以及子查询的相关功能…...
nginx应用场景(附配置)
场景1:web服务器 server {listen 80;server_name example.com; # 替换为您的域名location / {root /data/wwwroot;index index.html index.htm;} }server {listen 443 ssl;server_name example.com; # 替换为您的域名ssl_certificate /path/to/certificate.crt;ssl…...
tvm android_rpc_test.py执行报错解决
执行 python3 tests/android_rpc_test.py 报错: Run CPU test ... Traceback (most recent call last): File "tests/android_rpc_test.py", line 129, in <module> test_rpc_module() File "tests/android_rpc_test.py", line …...
十、项目沟通管理
十、项目沟通管理 从马斯洛需求的各个层级上,都需要沟通的介入。如果缺乏沟通,甚至可能严重损伤身心健康。 沟通渠道 1、 规划沟通管理 规划沟通管理是基于每个相关方或相关方群体的信息需求、可用的组织资产,以及具体项目的需求&#x…...
SQL设计时增加说明列
后关闭sql Studio,然后打开注册表,注册表地址: 计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\SQL Server Management Studio\18.0_IsoShell\DataProject 如有版本不同,红色内容有所变化,修改内容如下: SSVPropViewColumnsSQL70,SSVPropViewColumnsSQL80 全修改为 1,2,6,7…...
前端提高性能——使用Intersection Observer API对图片视频进行懒加载
前言 最近做了一个项目是类似于商城的,需要放很多图片,在用户选择一页五十条时,页面加载速度会比较慢。为了提高性能,选择用Intersection Observer API 实现图片懒加载。 实现步骤 一、html代码: <img class&qu…...
杂七杂八111
MQ 用处 一、异步。可提高性能和吞吐量 二、解耦 三、削峰 四、可靠。常用消息队列可以保证消息不丢失、不重复消费、消息顺序、消息幂等 选型 一Kafak:吞吐量最大,性能最好,集群高可用。缺点:会丢数据,功能较单一。 二Ra…...
微信小程序(一)
WebView app.是全局配置,app.json是全局配置文件,在页面的.json配置文件中的配置会覆盖我们全局的配置 快捷键: .box 敲回车 ----- <view class"box"></view> .row*8 敲回车: .row{$}*8 敲回车 案例1&…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)
1.获取 authorizationCode: 2.利用 authorizationCode 获取 accessToken:文档中心 3.获取手机:文档中心 4.获取昵称头像:文档中心 首先创建 request 若要获取手机号,scope必填 phone,permissions 必填 …...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

从图中,我们发现这些函数的使用方法其实非常类似,我们这里就讲一个字符函数













