C语言 ——— 函数

目录

函数是什么

库函数

学习使用 strcpy 库函数

自定义函数

写一个函数能找出两个整数中的最大值 

写一个函数交换两个整型变量的内容

牛刀小试

写一个函数判断一个整数是否是素数

写一个函数判断某一年是否是闰年

写一个函数,实现一个整型有序数组的二分查找

函数的嵌套调用

函数的链式访问

一段有趣的代码

函数的声明、调用和定义

函数的定义

函数调用

函数声明 

函数递归 

什么是递归

递归的两个必要条件 

一个简单的递归

牛刀小试

要求使用函数递归实现:接受一个无符号整型值,按照顺序打印他的每一位

要求写一个函数:能实现求字符串的长度 

编写函数,不允许创建临时变量,求字符串的长度


函数是什么

在 C 语言里,函数和数学中的函数有相似之处

以数学函数 f(x)=2x+1 为例,当 x 取值不同时,函数会有不同的结果。比如 x=2 时,将 x=2 代入函数可得 f(2)=2×2+1=5;当 x=3 时,代入后得到 f(3)=2×3+1=7

同样,这个数学函数也能用 C 语言中的函数来表示。我们可以定义一个 C 语言函数,让它接收一个参数,在函数内部按照 2x+1 的规则进行计算并返回结果,从而实现与这个数学函数相同的功能

代码演示:

int f(int x)
{return 2*x + 1;
}int main()
{int x = 0;scanf("%d", &x);printf("%d\n", f(x));return 0;
}

库函数

在 C 语言里,为了方便使用常用功能,会将这些功能封装成一个个函数,这些函数被称为库函数,像 printf 函数、scanf 函数、strlen 函数等都属于库函数

需要注意的是,C 语言本身并没有直接实现这些库函数,而是制定了 C 语言的标准以及库函数的约定。比如对于 scanf 函数,C 语言标准规定了它的功能、函数名、参数和返回值等

而库函数的具体实现通常由编译器来完成,常见的编译器如 VS2022 编译器、gcc 编译器等,它们会依据 C 语言标准对库函数进行具体的编码实现,这样开发者就能在编程时直接使用这些库函数了

学习使用 strcpy 库函数

C/C++ 中的库函数信息,都可以在 cplusplus.com 网站 上查询到

如果想学习或了解某个库函数的用法、参数含义及功能,直接在这个网站搜索对应的函数名即可,它是编程中查阅库函数的实用资源

strcpy 库函数

“destination” 代表目的地字符串,“source” 代表源头字符串。当一个函数的返回值类型为 char* 时,意味着该函数返回的是目的地字符串的首地址

strcpy 是一个库函数,从其文档可知,它的功能是进行字符串拷贝。具体来说,就是把源头字符串的数据复制到目的地字符串,并且会覆盖目的地字符串原有的内容,同时还会将源头字符串末尾的结束符 '\0' 也一同复制过去

若要在代码中使用 strcpy 函数,需要包含相应的头文件,头文件代码如下:

#include<string.h>

代码演示:

char source[] =  "hello world";
char destination[] =  "xxxxxxxxxxxxxxxx";strcpy(destination, source);printf("%s\n", destination);

代码验证:


自定义函数

在编程中,自定义函数指的是开发者根据实际需求自己编写的函数。它和 C 语言中的库函数(如printfstrlen)一样,都遵循相同的基本结构,包括:

  • 返回类型:函数执行完毕后输出的数据类型(如intchar*);
  • 参数:函数执行时需要的输入信息(可以没有参数,也可以有多个);
  • 返回值:通过return语句返回的结果(若无需返回结果,返回类型为void

写一个函数能找出两个整数中的最大值 

代码演示: 

int get_max(int a, int b)
{return a > b ? a : b;
}int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);int max = get_max(a, b);printf("%d\n", max);return 0;
}

写一个函数交换两个整型变量的内容

代码演示:

void Swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);printf("交换前:a = %d;b = %d\n", a, b);Swap(&a, &b);printf("交换后:a = %d;b = %d\n", a, b);return 0;
}

在编写函数交换两个整型变量的值时,不能直接传递实参。这是因为在函数调用时,实参的值会被复制给形参,实参和形参分别占用不同的内存空间,也就是各自独立的空间。在函数内部对形参进行操作,只会改变形参的值,而不会影响到实参原本的值

为了真正实现交换两个实参的值,我们需要传递实参的地址。由于实参是 int 类型,所以函数的形参要使用 int* 类型来接收这些地址。int* 类型的变量可以存储整型变量的地址。在函数内部,通过 * 这个解引用关键字,我们可以根据存储的地址找到对应的实参,进而对实参的值进行修改,这样就能实现两个实参值的交换


牛刀小试

写一个函数判断一个整数是否是素数

代码演示:

int is_prime(int tmp)
{if (tmp <= 1)return 0;for (int i = 2; i <= sqrt(tmp); i++){if (tmp % i == 0)return 0;}return 1;
}int main()
{int input = 0;scanf("%d", &input);if (is_prime(input))printf("is prime\n");elseprintf("not is prime\n");return 0;
}

代码解析:

我们要编写一个函数来判断一个整数是否为素数。素数是指大于 1 且只能被 1 和自身整除的正整数。所以在判断之前,首先要排除小于等于 0 的整数,因为它们显然不符合素数的定义

该函数的返回规则是:返回 0 表示这个数不是素数,返回 1 表示这个数是素数

对于输入的变量 input,我们需要判断它是否为素数。判断的方法是,用 input 对 2 到 input - 1 之间的数进行取模运算。可以使用 for 循环来遍历这个区间内的所有数。如果在遍历过程中,input 对某个数取模的结果为 0,那就说明 input 除了 1 和它本身之外,还能被其他数整除,那么它就不是素数,此时函数直接返回 0

不过,其实并不需要从 2 遍历到 input - 1,只需要遍历 2 到 sqrt(input)sqrt 是开平方函数)之间的数即可。这是因为如果一个数 input 不是素数,那么它一定可以分解为两个因数 m 和 n,即 input = m * n,其中 m 和 n 中至少有一个小于等于 sqrt(input)。所以,只要检查到 sqrt(input) 就可以判断 input 是否为素数了

如果 for 循环执行完毕都没有找到能整除 input 的数,那就说明 input 只能被 1 和它本身整除,即 input 是素数,此时函数返回 1

写一个函数判断某一年是否是闰年

代码演示:

int is_leap_year(int year)
{if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))return 1;elsereturn 0;
}int main()
{ int year = 0;scanf("%d", &year);is_leap_year(year);if (is_leap_year(year))printf("is leap year\n");elseprintf("not is leap year\n");return 0;
}

代码解析:

闰年的判断规则是能被 4 整除但不能被 100 整除,或能被 400 整除的年份

根据以上的规则编写出对应的逻辑代码,就能判断某一年是否是润年

写一个函数,实现一个整型有序数组的二分查找

代码演示:

int binary_search(int* parr, int size, int number)
{int left = 0;int right = size - 1;while (left <= right){int mid = (left + right) / 2;if (parr[mid] < number){left = mid + 1;}else if(parr[mid] > number){right = mid - 1;}else{return mid;}}return -1;
}int main()
{int arr[] = { 1,2,4,6,7,9,12,32,45,77,90 };int size = sizeof(arr) / sizeof(arr[0]);int input = 0;scanf("%d", &input);int ret = binary_search(arr, size, input);if (ret == -1)printf("number not found\n");elseprintf("number index is: %d\n", ret);return 0;
}

代码解析:

我们要实现一个二分查找函数,二分查找是一种高效的查找算法,它的前提是数组必须是有序的。在函数调用时,需要传递三个参数:数组的指针 arr,用于访问数组元素;数组的元素个数 size,这样能确定查找范围;要查找的整数 input,即我们要在数组中找到的目标值

函数的返回值规则是:如果在数组中找到了目标值 input,就返回该值在数组中的下标;如果没有找到,就返回 -1,因为数组的下标最小是从 0 开始的, -1 可以作为一个明确的未找到的标识

  1. 初始化查找范围:定义两个变量,left 作为左下标,初始值设为 0,它指向数组的起始位置;right 作为右下标,初始值设为 size - 1,它指向数组的末尾位置
  2. 开始循环查找:使用 while 循环来进行查找,循环的条件是 left <= right。只要满足这个条件,就说明还有元素没有被检查过,查找过程可以继续
  3. 计算中间下标:在每次循环内部,计算中间元素的下标 mid,计算公式为 mid = (left + right) / 2。通过这个中间下标,我们可以将数组分成两部分
  4. 比较中间元素与目标值
    • 如果 input 大于中间元素 arr[mid],说明目标值在数组的右半部分,此时更新 left 为 mid + 1,缩小查找范围到右半部分
    • 如果 input 小于中间元素 arr[mid],说明目标值在数组的左半部分,此时更新 right 为 mid - 1,缩小查找范围到左半部分
    • 如果 input 等于中间元素 arr[mid],说明已经找到了目标值,直接返回 mid,也就是目标值在数组中的下标
  5. 未找到目标值:如果 while 循环结束后还没有找到目标值,说明目标值不在数组中,此时返回 -1 即可

函数的嵌套调用

在编程中,当我们定义了多个函数后,有时会需要在一个函数的执行过程中,调用另一个函数来完成特定任务。这种 在一个函数内部调用另一个函数的方式,就是函数的嵌套调用

代码演示:

void print()
{printf("hello world\n");
}void three_print()
{for (int i = 0; i < 3; i++){print();}
}int main()
{three_print();return 0;
}

在 three_print 函数中调用了 print 函数,这就是函数的嵌套调用 


函数的链式访问

函数的链式访问是一种编程技巧,它指的是将一个函数的返回值直接作为另一个函数的参数来使用

代码演示:

printf("%d\n", strlen("abcdef"));

把 strlen 函数的返回值作为 printf 函数的参数,这就是函数的链式访问 

函数的链式访问可以让代码更加简洁和紧凑,避免创建中间变量。不过,在使用链式访问时也要注意代码的可读性,如果链式访问的函数过多,可能会让代码变得难以理解和调试。所以,在实际编程中要根据具体情况合理使用函数的链式访问 

一段有趣的代码

代码演示:

printf("%d", printf("%d", printf("%d", 43)));

问:最后在控制台上输出的结果是多少?

需明确 printf 函数的返回值为其输出的字符个数:

如:printf("%d", 1); 的返回值就是 1,printf("%d", 123); 的返回值就是 3

具体执行过程如下:

  1. 执行最内层 printf("%d", 43),会先在控制台输出 43(共 2 个字符),返回值为 2
  2. 中间层 printf("%d", 2) 接收内层返回值,输出 2(1 个字符),返回值为 1
  3. 最外层 printf("%d", 1) 接收中间层返回值,输出 1(1 个字符)

综上,控制台输出结果为 4321

代码验证:


函数的声明、调用和定义

函数的定义

int Add(int a, int b)
{return a + b;
}

函数 Add 的功能为计算两个整数的和,其定义是实现该功能的具体代码逻辑,即通过设定参数接收两个整数输入,在函数体内执行加法运算,并将运算结果作为返回值输出,从而完成两个整数相加功能的程序实现

函数调用

int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);int sum = Add(a, b);printf("%d\n", sum);return 0;
}

在 main 函数里使用 Add 函数的操作,在编程中被称作函数调用,此操作可触发 Add 函数执行其预设功能

函数声明 

// 函数声明
int Add(int a, int b);int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);// 函数调用int sum = Add(a, b);printf("%d\n", sum);return 0;
}// 函数定义
int Add(int a, int b)
{return a + b;
}

在 C 程序设计中,若自定义函数的定义位于 main 函数之后,则需在 main 函数执行前进行函数声明

这是由于程序遵循从上至下的执行逻辑,编译器在处理 main 函数时若未预先知晓自定义函数的存在,会因无法识别函数名称而报错

按照模块化编程规范,函数声明通常被放置在头文件(.h)中,用于告知编译器函数的参数类型和返回值类型;而函数的具体实现(定义)则集中存储在对应的源文件(.c)中,这种分离式设计有助于代码的组织、维护及复用,确保程序在编译阶段能够正确解析函数调用关系


函数递归 

什么是递归

递归是函数直接或间接调用自身的编程方式。需定义基线条件(终止递归的条件)和递归条件(逐步逼近基线的逻辑),通过重复调用解决可分解为相似子问题的任务

递归的核心思维在于:把大事化小

递归的两个必要条件 

  1. 基线条件(终止条件):必须存在至少一个无需递归调用的终止条件,用于退出递归过程,避免无限循环;
  2. 递归条件:函数需通过自身调用逐步分解问题,且每次递归调用必须更接近基线条件,确保问题规模递减直至满足终止条件

一个简单的递归

int main()
{printf("hello\n");main();return 0;
}

若 main 函数直接调用自身,构成直接递归。由于该递归未设置基线条件(终止条件),程序会无限次递归调用自身,导致调用栈不断增长

当栈空间被耗尽时,将引发栈溢出错误,造成程序异常终止。这一现象体现了递归中终止条件的必要性 —— 缺少该条件会破坏递归的收敛性,最终导致内存资源耗尽

牛刀小试

要求使用函数递归实现:接受一个无符号整型值,按照顺序打印他的每一位

例如:

输入:1234 ;输入:1 2 3 4 

代码演示:

void print_every_one(int n)
{if (n > 9){print_every_one(n / 10);}printf("%d ", n % 10);
}

代码解析:

该函数实现按顺序打印无符号整数每一位的功能,核心通过数学运算 %10(取个位)和 /10(去除个位)分解数字,并结合递归逐层处理

算法思路:

数字分解原理

  1. 对于任意整数 nn % 10 可获取其个位数字(如 123 % 10 = 3
  2. n / 10 可去除个位,得到高位数字(如 123 / 10 = 12

通过重复这两步,可逐位拆解整数的每一位

递归过程分析(以 n = 123 为例):

首次调用与递归展开

  • 初始调用 print_every_one(123),因 123 > 9,触发递归调用 print_every_one(123 / 10 = 12)
  • 第二次调用 print_every_one(12),因 12 > 9,继续递归调用 print_every_one(12 / 10 = 1)

基线条件触发(递归终止)

  • 第三次调用 print_every_one(1),此时 1 <= 9,不满足递归条件,跳过 if 语句,直接执行 printf("%d ", 1 % 10),输出 1

逐层返回与后续打印

  • 返回上一层(第二次调用,n = 12),执行 printf("%d ", 12 % 10),输出 2
  • 再返回初始层(首次调用,n = 123),执行 printf("%d ", 123 % 10),输出 3

最终输出结果

控制台按递归返回顺序打印 1 2 3,实现从高位到低位的顺序输出

核心逻辑总结:

  • 递归特性:通过不断将问题规模缩小(n / 10),直至满足基线条件(n <= 9)时终止递归,再逐层返回处理当前层的打印逻辑
  • 执行顺序:递归调用时先处理高位(通过不断剥离个位),返回时再依次打印低位,利用调用栈的后进先出特性,自然实现从高位到低位的顺序输出

要求写一个函数:能实现求字符串的长度 

代码演示:

int my_strlen(const char* s)
{int count = 0;while (*s != '\0'){count++;s++;}return count;
}

代码解析:

此函数 my_strlen 用于计算字符串的长度。参数 s 是一个指向字符串首字符的指针

在 C 语言里,字符串以 '\0' 作为结束标志。函数利用 while 循环来遍历字符串,只要当前指针 s 所指向的字符不是 '\0',就表明还有字符需要统计

在循环内部,count 变量用于统计字符串中字符的数量,每统计一个字符,count 的值就加 1。同时,指针 s 通过 s++ 操作指向下一个字符,从而实现对字符串的逐字符遍历

当 s 指向 '\0' 时,意味着已经遍历完整个字符串,此时循环结束,count 变量中存储的数值就是字符串中字符的总个数,也就是该字符串的长度,最后将其作为函数的返回值返回

编写函数,不允许创建临时变量,求字符串的长度

代码演示:

int my_strlen(const char* s)
{if (*s == '\0')return 0;return 1 + my_strlen(s+1);
}

代码解析:

函数参数与返回值

该函数接受一个指向 const char 类型的指针 s 作为参数,const 表明此指针指向的字符串内容不能被修改。函数返回一个 int 类型的值,即字符串的长度

递归终止条件

在函数内部,首先会检查指针 s 所指向的字符是否为 '\0'。在 C 语言中,字符串以 '\0' 作为结束标志。如果当前字符是 '\0',则意味着已经到达字符串的末尾,此时函数将返回 0。这是递归的终止条件,它确保了递归调用不会无限进行下去,避免出现栈溢出的错误

递归调用逻辑

若当前字符不是 '\0',说明还未遍历完整个字符串。函数会将指针 s 向后移动一位(s + 1),使其指向下一个字符,然后再次调用 my_strlen 函数,以计算从下一个字符开始的子字符串的长度。由于当前字符也是字符串的一部分,所以在递归调用返回的结果上加 1,表示当前字符的长度。最终将这个累加后的结果作为当前字符串的长度返回

递归调用示例

假设传入的字符串为 "abc",递归调用过程如下:

  • 第一次调用 my_strlen("abc"),当前字符为 'a',不是 '\0',则进行递归调用 1 + my_strlen("bc")
  • 第二次调用 my_strlen("bc"),当前字符为 'b',不是 '\0',继续递归调用 1 + my_strlen("c")
  • 第三次调用 my_strlen("c"),当前字符为 'c',不是 '\0',再次递归调用 1 + my_strlen("")
  • 第四次调用 my_strlen(""),此时当前字符为 '\0',满足终止条件,返回 0
  • 返回到第三次调用,my_strlen("c") 返回 1 + 0 = 1
  • 返回到第二次调用,my_strlen("bc") 返回 1 + 1 = 2
  • 返回到第一次调用,my_strlen("abc") 返回 1 + 2 = 3

通过这种递归的方式,函数逐步缩小问题规模,直到满足终止条件,最终计算出整个字符串的长度

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

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

相关文章

笔记本电脑升级计划(2017———2025)

ThinkPad T470 (2017) vs ThinkBook 16 (2025) 完整性能对比报告 一、核心硬件性能对比 1. CPU性能对比&#xff08;i5-7200U vs Ultra9-285H&#xff09; 参数i5-7200U (2017)Ultra9-285H (2025)提升百分比核心架构2核4线程 (Skylake)16核16线程 (6P8E2LPE)700%核心数制程工…

具身系列——PPO算法实现CartPole游戏(强化学习)

完整代码参考&#xff1a; https://gitee.com/chencib/ailib/blob/master/rl/ppo_cartpole.py 执行结果&#xff1a; 部分训练得分&#xff1a; (sd) D:\Dev\traditional_nn\feiai\test\rl>python ppo_cartpole_v2_succeed.py Ep: 0 | Reward: 23.0 | Running: 2…

Python项目源码60:电影院选票系统1.0(tkinter)

1.功能特点&#xff1a;通常选票系统应该允许用户选择电影、场次、座位&#xff0c;然后显示总价和生成票据。好的&#xff0c;我得先规划一下界面布局。 首先&#xff0c;应该有一个电影选择的列表&#xff0c;可能用下拉菜单Combobox来实现。然后场次时间&#xff0c;可能用…

【全队项目】智能学术海报生成系统PosterGenius--图片布局生成模型LayoutPrompt(2)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;大模型实战训练营_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前…

Linux的时间同步服务器(附加详细实验案例)

一、计时方式的发展 1.古代计时方式​ 公元前约 2000 年&#xff1a;古埃及人利用光线留下的影子计时&#xff0c;他们修建高耸的大型方尖碑&#xff0c;通过追踪方尖碑影子的移动判断时间&#xff0c;这是早期利用自然现象计时的典型方式 。​商朝时期&#xff1a;人们开发并…

【无需docker】mac本地部署dify

环境安装准备 #安装 postgresql13 brew install postgresql13 #使用zsh的在全局添加postgresql命令集 echo export PATH"/usr/local/opt/postgresql13/bin:$PATH" >> ~/.zshrc # 使得zsh的配置修改生效 source ~/.zshrc # 启动postgresql brew services star…

(5)概述 QT 的元对象系统里的类的调用与联系,及访问接口

&#xff08;1&#xff09; QT 的元对象系统&#xff0c;这几个字大家都知道&#xff0c;那么 QT 的元对象系统里都包含哪些内容呢&#xff0c;其访问接口是如何呢&#xff1f; 从 QObject 类的实现里&#xff0c;从其数据成员里就可以看出来&#xff1a; QT 里父容器可以释放其…

打包 Python 项目为 Windows 可执行文件:高效部署指南

Hypackpy 是一款由白月黑羽开发的 Python 项目打包工具&#xff0c;它与 PyInstaller 等传统工具不同&#xff0c;通过直接打包解释器环境和项目代码&#xff0c;并允许开发者修改配置文件以排除不需要的内容&#xff0c;从而创建方便用户一键运行的可执行程序。以下是使用 Hyp…

MySQL JOIN详解:掌握数据关联的核心技能

一、为什么需要JOIN&#xff1f; 在关系型数据库中&#xff0c;数据通常被拆分到不同的表中以提高存储效率。当我们需要从多个表中组合数据时&#xff0c;JOIN操作就成为了最关键的技能。通过本文&#xff0c;您将全面掌握MySQL中7种JOIN操作&#xff0c;并学会如何在实际场景中…

Kdump 收集器及使用方式

以下是 Linux 系统中 Kdump 转储收集器的详细说明及其使用方法&#xff0c;涵盖核心工具、配置方法及实际示例&#xff1a; 一、Kdump 收集器分类及作用 Kdump 的核心功能是通过 捕获内核 生成内存转储文件&#xff08;vmcore&#xff09;&#xff0c;其核心收集器包括&#…

Error: error:0308010C:digital envelope routines::unsupported 高版本node启动低版本项目运行报错

我的问题就是高版本node启动旧版本项目引起的问题&#xff0c;单独在配置 package.json文件中配置并运行就可以&#xff0c;大概意思就是设置node的openssl "scripts": {"dev": "SET NODE_OPTIONS--openssl-legacy-provider && vue-cli-servi…

松下机器人快速入门指南(2025年更新版)

松下机器人快速入门指南&#xff08;2025年更新版&#xff09; 松下机器人以其高精度、稳定性和易用性在工业自动化领域广泛应用。本文将从硬件配置、参数设置、手动操作、编程基础到维护保养&#xff0c;全面讲解松下机器人的快速入门方法&#xff0c;帮助新手快速掌握核心操…

【CISCO】Se2/0, Se3/0:串行口(Serial) 这里串口的2/0 和 3/0分别都是什么?

在 Cisco IOS 设备上&#xff0c;接口名称通常遵循这样一个格式&#xff1a; <类型><槽号>/<端口号>类型&#xff08;Type&#xff09;&#xff1a;表示接口的物理或逻辑类型&#xff0c;比如 Serial&#xff08;串行&#xff09;、FastEthernet、GigabitEt…

开源无人机地面站QGroundControl安卓界面美化与逻辑优化实战

QGroundControl作为开源无人机地面站软件,其安卓客户端界面美化与逻辑优化是提升用户体验的重要工程。 通过Qt框架的界面重构和代码逻辑优化,可以实现视觉升级与性能提升的双重目标。本文将系统讲解QGC安卓客户端的二次开发全流程,包括开发环境搭建、界面视觉升级、多分辨率…

基于DDPG的自动驾驶小车绕圈任务

1.任务介绍 任务来源: DQN: Deep Q Learning &#xff5c;自动驾驶入门&#xff08;&#xff1f;&#xff09; &#xff5c;算法与实现 任务原始代码: self-driving car 在上一篇使用了DQN算法完成自动驾驶小车绕圈任务之后&#xff0c;学习了DDPG算法&#xf…

缓存置换:用c++实现最近最少使用(LRU)算法

在计算机的世界里&#xff0c;缓存就像一个“快速仓库”&#xff0c;它存储着我们频繁访问的数据&#xff0c;大大提升了数据的读取速度。但这个 “仓库” 空间有限&#xff0c;当它被装满时&#xff0c;就得决定舍弃一些数据&#xff0c;为新数据腾出位置&#xff0c;这个决策…

【YOLO11改进】改进Conv、颈部网络STFEN、以及引入PIOU用于小目标检测!

改进后的整体网络架构 改进一:RFD模块(Conv) YOLOv11模型的跨步卷积下采样虽然快速聚合了局部特征,并且实现了较高的计算效率,但其固有的信息压缩机制会导致细粒度特征的不可逆丢失。针对特征保留与计算效率的平衡问题,本文采用RFD模块替换跨步卷积下采样模块。RFD模块通…

设计模式每日硬核训练 Day 18:备忘录模式(Memento Pattern)完整讲解与实战应用

&#x1f504; 回顾 Day 17&#xff1a;中介者模式小结 在 Day 17 中&#xff0c;我们学习了中介者模式&#xff08;Mediator Pattern&#xff09;&#xff1a; 用一个中介者集中管理对象之间的通信。降低对象之间的耦合&#xff0c;适用于聊天系统、GUI 控件联动、塔台调度等…

java单元测试代码

import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import java.util.List;public class UserServiceTest {Testpublic void testSearchUserByTags() {// 模拟标签列表List<String> tagNameList List.of("tag1", "…

前端面经-VUE3篇(一)--vue3基础知识- 插值表达式、ref、reactive

目录 一、 插值表达式 1、插值表达式 ({{}}) 的本质与作用&#xff1a; 2、与 Vue 响应式系统关系&#xff1a; 二、指令 1、什么是 Vue 指令&#xff1f; 2、指令的分类 1、内置指令 ① 内容绑定&#xff1a;v-text 和 v-html ② 属性绑定&#xff1a;v-bind ③ 事件绑定…