收集飞花令碎片——C语言(数组+函数)

article/2025/8/23 19:18:49

C语言的函数(Function)是程序的基本构建块,用于封装一段可重用的代码,完成特定任务。函数可以提高代码的模块化可读性复用性请添加图片描述

目录

  • 函数
    • 库函数
    • 标准库头文件
    • 自定义函数
      • (1)基本语法
      • (2)函数的调用
      • (3)函数的声明
      • (4)形参和实参
        • 实参
        • 形参
        • 形参和实参各自的内存空间
        • (重点)数组作函数参数
          • (1)数组作为函数参数的基本形式
          • (2)数组传参的本质
          • (3)数组大小信息的丢失
          • (4)数组参数与const限定符
          • (5)常见错误
            • 总结
          • 代码练习
      • (5)return 语句
    • 嵌套调用
    • 链式访问
    • 多个文件中定义函数
    • 函数重要关键字
      • 作用域和生命周期
      • (1)static
        • static修饰局部变量
        • static修饰全局变量
      • (2)extern
    • 总结
  • 如果你觉得这篇文章对你有帮助
  • 请给个三连支持一下哦

函数

函数包括库函数自定义函数
函数也被成为子程序,就是⼀个完成某项特定的任务的一小段代码

库函数

我们前⾯内容中学到的 printf 、 scanf 都是库函数,库函数也是函数,不过这些函数已经是现成的,我们只要学会就能直接使⽤了。有了库函数,⼀些常⻅的功能就不需要程序员⾃⼰实现了,⼀定程度提升了效率;同时库函数的质量和执⾏效率上都更有保证。

库函数相关头⽂件点这里

库函数是在标准库中对应的头⽂件中声明的,所以库函数的使⽤,务必包含对应的头⽂件,不包含是可能会出现⼀些问题的。

  • 实践
#include <stdio.h>  
#include <math.h>
int main()
{double d = 16.0;double r = sqrt(d);printf("%lf\n", r);return 0;
}


标准库头文件

C标准库的函数按功能分类在不同的头文件(.h)中,使用时需先包含对应头文件:

头文件主要功能常用函数示例
<stdio.h>标准输入输出printf, scanf, fopen, fgets
<string.h>字符串处理strcpy, strlen, strcat, strcmp
<math.h>数学运算sin, cos, sqrt, pow
<stdlib.h>内存管理、随机数、类型转换malloc, free, rand, atoi
<time.h>时间和日期处理time, clock, strftime
<ctype.h>字符分类和转换isalpha, tolower, isdigit


自定义函数

自定义函数由 函数名参数列表返回类型函数体构成

(1)基本语法

返回类型 函数名(参数列表) {// 函数体(代码逻辑)return 返回值; // 可选,取决于返回类型
}
  • 返回值类型
  1. 函数可以返回一个值(如 int、float、char 等)。

  2. 如果不需要返回值,使用 void

  • 函数名
  1. 遵循标识符命名规则(字母、数字、下划线,不能以数字开头)。

  2. 最好使用动词+名词形式(如 calculateSum、printArray)。

  • 参数列表
  1. 可以是零个或多个参数,用 , 分隔。

  2. 参数可以是值传递(默认)或指针传递(用于修改实参)。

  • 函数体
  1. 包含具体的执行代码。

  2. 如果返回类型不是 void,必须使用 return 返回值。

  • 代码示例
int add(int a, int b) {  // 返回类型:int | 函数名:add | 参数:int a, int breturn a + b;        // 返回计算结果
}


(2)函数的调用

//函数定义后,可以通过 `函数名 + 参数` 调用:
int result = add(3, 5);  // 调用 add(),传入 3 和 5
printf("3 + 5 = %d\n", result);  // 输出: 3 + 5 = 8
//无返回值函数的调用
greet();  // 调用 greet(),输出 "Hello, World!"
//指针参数的调用
int x = 10, y = 20;
swap(&x, &y);  // 传入地址,交换 x 和 y 的值
printf("x=%d, y=%d\n", x, y);  // 输出: x=20, y=10

(3)函数的声明

如果函数定义在调用之后,需要先声明(告诉编译器函数的存在):

#include <stdio.h>// 函数声明(原型)
int add(int a, int b);  int main() {int sum = add(3, 5);  // 调用 add()printf("Sum: %d\n", sum);return 0;
}// 函数定义
int add(int a, int b) {return a + b;
}

(4)形参和实参

  • 举例代码
#include <stdio.h>
int Add(int x, int y)
{int z = 0;z = x + y;return z;
}
int main()
{int a = 0;int b = 0;//输⼊scanf("%d %d", &a, &b);//调⽤加法函数,完成a和b的相加//求和的结果放在r中int r = Add(a, b);  //17//输出printf("%d\n", r);return 0;
}
实参

在上⾯代码中,我们把第17行调用Add函数时,传递给函数的参数a和b,称为实际参数,简称实参

实际参数就是真实传递给函数的参数。

形参

在上⾯代码中,第2⾏定义函数的时候,在函数名 Add 后的括号中写的 x 和 y ,称为形式参数,简称形参

为什么叫形式参数呢?实际上,如果只是定义了 Add 函数,⽽不去调⽤的话, Add 函数的参数 x 和 y 只是形式上存在的,不会向内存申请空间,不会真实存在的,所以叫形式参数。形式参数只有在函数被调⽤的过程中为了存放实参传递过来的值,才向内存申请空间,这个过程就是形参的实例化


形参和实参各自的内存空间

当函数被调用时,形参在栈(Stack)中分配独立的内存空间。
函数执行结束后,形参的内存自动释放。

实参的内存空间在调用前已存在(可能是全局变量、栈变量或堆内存)。
实参的内存生命周期由定义它的作用域决定(如函数结束释放栈变量)。

在值传递时,实参的值会被拷贝给形参,二者占用不同内存空间。
在指针传递时,实参和形参共享同一内存地址(通过指针间接访问)。

特性形参实参
内存位置栈(函数调用时分配)由定义位置决定(栈/堆/全局)
生命周期函数执行期间依赖原作用域
修改是否影响实参值传递:否;指针传递:是直接修改自身
本质函数的局部变量调用时传入的具体数据


(重点)数组作函数参数

在C语言中,数组作为函数参数传递是一个重要且需要特别注意的概念。下面我将从多个方面详细讲解数组作为函数参数的使用方法、原理和注意事项。

(1)数组作为函数参数的基本形式
// 写法一:使用数组形式声明
void func(int arr[], int size) {// 函数体
}// 写法二:使用指针形式声明
void func(int *arr, int size) {// 函数体
}


(2)数组传参的本质

C语言中数组作为函数参数传递时,实际上传递的是数组首元素的地址,而不是整个数组的副本。

  • 代码展示
int main() {int arr[5] = {1, 2, 3, 4, 5};printArray(arr, 5);  // arr在这里退化为指向首地址的指针return 0;
}void printArray(int a[], int size) {// 实际上a是一个指针,不是数组
}


(3)数组大小信息的丢失

由于数组参数退化为指针,函数内部无法直接获取数组的实际大小
因此,通常需要额外传递数组大小作为参数。

void printSize(int arr[]) {printf("%zu\n", sizeof(arr));  // 输出指针大小(如8字节),不是数组大小
}int main() {int a[10];printf("%zu\n", sizeof(a));    // 输出40(假设int为4字节)printSize(a);                  // 输出8(64位系统指针大小)return 0;
}


(4)数组参数与const限定符

如果不希望函数修改数组内容,可以使用const限定符

void printArray(const int arr[], int size) {for(int i = 0; i < size; i++) {printf("%d ", arr[i]);// arr[i] = 0;  // 编译错误,不能修改const数组}
}


(5)常见错误
  • 错误:试图计算数组参数的大小
void wrongFunc(int arr[]) {int size = sizeof(arr)/sizeof(arr[0]);  // 错误!结果是1或2(指针大小/元素大小)
}
  • 问题分析
  1. 当数组作为参数传递时,它会退化为指针
  2. sizeof(arr)返回的是指针大小(8字节),而不是数组大小
  3. 这种计算方式在函数内部完全不可靠
  • 修正方法

必须显式传递数组大小作为额外参数:sizeof(a)在main函数中仍然是完整的数组大小

// 正确写法
void correctFunc(int arr[], size_t size) {for(size_t i = 0; i < size; i++) {printf("%d ", arr[i]);}
}int main() {int a[5] = {1, 2, 3, 4, 5};correctFunc(a, sizeof(a)/sizeof(a[0]));  // 在调用处计算大小return 0;
}


总结

这里我们需要知道数组传参的⼏个重点知识:

• 函数的形式参数要和函数的实参个数匹配

// 正确:形参和实参个数匹配
void printArray(int arr[], int size) { ... }int main() {int a[5] = {1, 2, 3, 4, 5};printArray(a, 5);  // 两个实参:数组名 + 数组大小return 0;
}



• 函数的实参是数组,形参也是可以写成数组形式的

// 以下两种写法等价
void func1(int arr[]) { ... }  // 数组形式(推荐用于直观性)
void func2(int *arr)  { ... }  // 指针形式(推荐用于明确本质)


• 形参如果是⼀维数组,数组⼤⼩可以省略不写

// 以下三种声明完全等效
void funcA(int arr[])    { ... }  // 省略大小
void funcB(int arr[10])  { ... }  // 写了大小(但无效)
void funcC(int *arr)     { ... }  // 直接写指针



• 形参如果是⼆维数组,⾏可以省略,但是列不能省略

// 正确:列数必须明确
void printMatrix(int mat[][4], int rows) { ... }// 错误:列数未指定
void wrongFunc(int mat[][]) { ... }  // 编译报错!



• 数组传参,形参是不会创建新的数组的

void modifyArray(int arr[]) {arr[0] = 100;  // 修改会影响实参的数组
}int main() {int a[3] = {1, 2, 3};modifyArray(a);printf("%d", a[0]);  // 输出100,原数组被修改return 0;
}



• 形参操作的数组和实参的数组是同⼀个数组

void clearArray(int arr[], int size) {for (int i = 0; i < size; i++) {arr[i] = 0;  // 直接修改原始数组}
}int main() {int data[5] = {1, 2, 3, 4, 5};clearArray(data, 5);  // data数组被清空return 0;
}


代码练习
#include <stdio.h>
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr)/sizeof(arr[0]);
set_arr(arr, sz);//设置数组内容为-1
print_arr(arr, sz);//打印数组内容
return 0;
}void set_arr(int arr[], int sz)
{
int i = 0;for(i=0; i<sz; i++){arr[i] = -1;}
}
void print_arr(int arr[], int sz)
{
int i = 0;for(i=0; i<sz; i++){printf("%d ", arr[i]);}
printf("\n");
}


另外在这里强调一下
数组首地址首元素地址是一个概念


(5)return 语句

在函数的设计中,函数中经常会出现return语句,这⾥讲⼀下return语句使用的注意事项。

  • return后边可以是⼀个数值,也可以是⼀个表达式,如果是表达式则先执⾏表达式,再返回表达式
    的结果。
  • return后边也可以什么都没有,直接写 return; 这种写法适合函数返回类型是void的情况。
  • return语句执行后,函数就彻底返回,后边的代码不再执⾏。
  • return返回的值和函数返回类型不⼀致,系统会⾃动将返回的值隐式转换为函数的返回类型。
  • 如果函数中存在if等分⽀的语句,则要保证每种情况下都有return返回,否则会出现编译错误。
  • 函数的返回类型如果不写,编译器会默认函数的返回类型是int。
  • 函数写了返回类型,但是函数中没有使用return返回值,那么函数的返回值是未知的。


嵌套调用

嵌套调⽤就是函数之间的互相调⽤,每个函数就像⼀个乐⾼零件,正是因为多个乐⾼的零件互相⽆缝的配合才能搭建出精美的乐⾼玩具,也正是因为函数之间有效的互相调⽤,最后写出来了相对⼤型的程序。
禁止函数嵌套定义
下面我们用一段代码来展示

计算某年某月某日有多少天

  • is_leap_year():根据年份确定是否是闰年
  • get_days_of_month():调⽤is_leap_year确定是否是闰年后,再根据月计算这个⽉的天数
#include <stdio.h>// 判断闰年函数
int IsLeapYear(int year) {if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {return 1;}else {return 0;}
}// 获取月份天数函数
int get_days_of_month(int year, int month) {int arr[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 修正数组顺序int day = arr[month];// 如果是闰年且2月,天数加1if (IsLeapYear(year) && month == 2) {day += 1;}return day;
}int main() {int y = 0;int m = 0;printf("请输入年份和月份:");scanf("%d %d", &y, &m);  // 使用标准scanfint d = get_days_of_month(y, m);printf("%d年%d月有%d天\n", y, m, d);return 0;
}


链式访问

所谓链式访问就是将⼀个函数的返回值作为另外⼀个函数的参数,像链条⼀样将函数串起来就是函数的链式访问。

#include <stdio.h>
int main()
{
int len = strlen("abcdef");	//1.strlen求⼀个字符串的⻓度printf("%d\n", len);		//2.打印⻓度
return 0;
}

把strlen的返回值直接作为printf函数的参数,就是⼀个链式访问的例⼦

#include <stdio.h>
int main()
{printf("%d\n",strlen("abcdef"));
return 0;
}


  • 我们再看下面一个有趣的代码
#include <stdio.h>
int main(){printf("%d",printf("%d",printf("%d",43)))return 0;
}

printf是打印屏幕上的字符个数

我们就第一个printf打印的是第二个printf的返回值,第二个printf打印的是第三个printf的返回值。
第三个printf打印43,在屏幕上打印2个字符,再返回2
第二个printf打印2,在屏幕上打印1个字符,再放回1
第一个printf打印1
所以屏幕上最终打印:4321


多个文件中定义函数

  • 基本概念
    ⼀般在企业中我们写代码时候,代码可能比较多,不会将所有的代码都放在⼀个文件中;我们往往会根据程序的功能,将代码拆分放在多个文件中。

声明: 告诉编译器"这个函数存在"(放在.h头文件)
定义: 实际实现函数功能(放在.c源文件)
一般情况下,函数的声明、类型的声明放在头文件(.h)中,函数的定义与功能的实现放在源文件(.c)当中

调用函数时候记得包含头文件————用"头文件名.h"

  • 标准做法示例
    文件结构
project/
├── main.c       # 主程序
├── utils.h      # 函数声明(头文件)
└── utils.c      # 函数定义


函数重要关键字

在讲解关键字之前,我们先讲讲作用域生命周期

作用域和生命周期

  • 作用域指变量/函数在代码中的可见范围
  1. 局部作用域(块作用域)
void func() {int x = 10;  // 局部变量,只在func内可见if (1) {int y = 20;  // 只在if块内可见}// y 这里不可用
}
  1. 全局作用域
int global = 100;  // 全局变量,从定义处到文件末尾都可见void func1() {global++;  // 可以访问
}void func2() {global--;  // 可以访问
}
  1. 文件作用域(static全局变量)
static int file_scope = 50;  // 只在当前.c文件可见void func() {file_scope = 60;  // 可以访问
}// 其他文件无法访问file_scope


  • 生命周期指变量存活的时间
  1. 自动存储期(局部变量)
void func() {int auto_var = 10;  // 函数调用时创建,函数结束时销毁
}
  1. 静态存储期()
int global_var;       // 程序启动时创建,结束时销毁(初始化为0)
static int static_var; // 同上,但作用域受限void func() {static int local_static = 0;  // 只会初始化一次,之后就保持值local_static++;
}
  1. 动态存储期(malloc分配)
void func() {int *p = malloc(sizeof(int));  // 手动分配*p = 100;free(p);  // 手动释放
}
  1. 动态存储期(malloc分配)后面讲指针的时候会说
void func() {int *p = malloc(sizeof(int));  // 手动分配*p = 100;free(p);  // 手动释放
}


  • 总结
  1. 局部变量的⽣命周期是:进⼊作⽤域变量创建,生命周期开始,出作⽤域⽣命周期结束。
  2. 全局变量的⽣命周期是:整个程序的⽣命周期。


(1)static

static修饰局部变量

我们先来看下面的两端代码

  • 代码一
#include <stdio.h>void test()
{int i = 0;i++;printf("%d ", i);
}int main()
{int i = 0;for (i = 0; i < 5; i++){test();}return 0;
}

代码1的test函数中的局部变量i是每次进⼊test函数先创建变量(⽣命周期开始)并赋值为0,然后++,再打印,出函数的时候变量⽣命周期将要结束(释放内存)。

  • 代码二
#include <stdio.h>void test()
{// static修饰局部变量static int i = 0;i++;printf("%d ", i);
}int main()
{int i = 0;for (i = 0; i < 5; i++){test();}return 0;
}

代码2中,我们从输出结果来看,i的值有累加的效果,其实 test函数中的i创建好后,出函数的时候是不会销毁的,重新进⼊函数也就不会重新创建变量,直接上次累积的数值继续计算。

  • 结论

static修饰局部变量改变了局部变量的生命周期,生命周期的改变本质上就是改变了变量的存储类型
本来局部变量是存储在内存的栈区的,但是被static修饰后存储到了静态区。
存储在静态区的变量的生命周期和全局变量的生命周期是一样,直到程序结束,变量才销毁,内存才收回


  • 使用建议

未来⼀个变量出了函数后,我们还想保留值,等下次进入函数继续使用,就可以使用static修饰。


static修饰全局变量
//test.c
#include <stdio.h>
extern int g_val;
int main()
{
printf("%d",g_val);
return 0;
}
//add.c
int g_val = 2018;



使用建议:如果⼀个全局变量,只想在所在的源⽂件内部使用,不想被其他文件发现,就可以使用static 修饰。

static对函数也同样适用

(2)extern

extern 是C语言中用于声明变量或函数的外部链接性的关键字,它告诉编译器"这个标识符的定义在其他文件中。

  • 基本用法
  1. 声明外部变量:
extern int globalVar; // 声明globalVar在其他文件中定义
  1. 声明外部函数(函数声明默认就是extern的,所以通常省略):
extern void someFunction(); // 等同于 void someFunction();
  • 主要作用
  1. 跨文件访问变量:

在一个源文件中定义变量:

// file1.c
int globalVar = 10; // 定义

在另一个源文件中使用:

// file2.c
extern int globalVar; // 声明
void foo() {printf("%d\n", globalVar); // 使用
}
  1. 在头文件中声明变量:
// globals.h
extern int globalVar;
  1. 与const变量一起使用:
extern const int MAX_SIZE; // 声明在别处定义的const变量


总结

函数的主要内容就到此为止了,下一章我们将结合知识点,编写一款扫雷游戏

如果你觉得这篇文章对你有帮助

请给个三连支持一下哦

在这里插入图片描述


http://www.hkcw.cn/article/phDWjsATYA.shtml

相关文章

2013-2021年各省电子商务数据

2013-2021年各省电子商务数据 1、时间&#xff1a;2013-2021年 2、来源&#xff1a;国家统计局、各省年鉴 3、指标&#xff1a;统计年度、地区代码、地区名称、电子商务销售额 4、范围&#xff1a;31省 5、指标说明&#xff1a;电子商务销售额是指通过电子商务平台进行商品…

企业级开发的 “技术主权保卫战”:iVX 源码自主性实践指南

在数字化转型的浪潮中&#xff0c;技术主权已成为企业核心竞争力的关键组成部分。iVX 作为全栈可视化开发平台&#xff0c;通过源码自主性实践&#xff0c;为企业构建了从开发工具到行业落地的全栈解决方案&#xff0c;在安全架构、国产替代、合规优势三大领域实现了技术突破与…

Python-12(函数)

函数的主要功能是可以打包代码&#xff0c;最大程度的实现代码的重用&#xff0c;减少冗余代码&#xff0c;可以将不同功能的代码进行封装&#xff0c;从而降低结构的复杂度&#xff0c;提高代码的可读性。 创建和调用函数 使用def语句来定义函数。 def myFunc():print(&quo…

罗德里格斯公式动图演示

一. 罗德里格斯公式形式: R o t ( ω ^ , θ ) e [ ω ] ^ θ I s i n θ [ ω ^ ] ( 1 − c o s θ ) [ ω ^ ] 2 Rot(\hat{\bold{\omega}}, \theta)e^{\hat{\bold{[\omega]}}_{\times} \theta}\bold{I}sin\theta[\hat{\bold{\omega}}]_{\times}(1-cos\theta)[\hat{\bo…

多家医院回应药企向上百名医生行贿 调查正在进行中

近日,一则关于某药企被举报向四川多家医院上百名医生行贿的消息引发广泛关注。举报材料中提及了四川省内包括成都市、绵阳市、广安市在内的多个城市的37家医疗机构。达州市第一人民医院工作人员表示,举报信中提到的医生并不在院方员工名单中,且该院去年才成立,往年员工名单…

高密爆炸警钟长鸣:AI为化工安全戴上“智能护盾”

一、高密爆炸&#xff1a;一声巨响&#xff0c;撕开化工安全“伤疤” 2025年5月27日&#xff0c;山东高密友道化学有限公司的车间爆炸声&#xff0c;像一把利刃划破了化工行业的平静。剧烈的冲击波将车间夷为平地&#xff0c;黑色蘑菇云腾空而起&#xff0c;刺鼻的化学气味弥漫…

微软 Azure AI Foundry(国际版)十大重要更新

2025 年被广泛视为 “AI 智能体元年”。在过去半年&#xff0c;微软密集发布众多创新技术&#xff0c;构建起从基础设施层、开发工具层到场景应用层的完整技术矩阵&#xff0c;加速推动诸多具备自主决策能力的 “超级助理” 智能体落地&#xff0c;形成完整的 AI 赋能生态&…

撒贝宁在广东水陆两栖过端午,广东过端午到底有多嗨?

撒贝宁在广东水陆两栖过端午。“龙舟漂移”惊险刺激,荔枝让苏轼灵感迸发,还有机器人参与的赛博端午节……广东过端午到底有多嗨?撒贝宁近日现身佛山叠滘,沉浸式体验龙舟季活动。在蜿蜒狭窄的河道上,他勇敢挑战龙舟漂移,完成高难度C弯动作时,自信高呼粤语有各位大哥在这里…

【HarmonyOS 5】鸿蒙中的UIAbility详解(二)

【HarmonyOS 5】鸿蒙中的UIAbility详解&#xff08;二&#xff09; 一、前言 今天我们继续深入讲解UIAbility&#xff0c;根据下图可知&#xff0c;在鸿蒙中UIAbility继承于Ability&#xff0c;开发者无法直接继承Ability。只能使用其两个子类&#xff1a;UIAbility和Extensi…

滚珠导轨:电子制造“纳米级”精度的运动基石

在电子制造与半导体设备追求“微米级工艺、纳米级控制”的赛道上&#xff0c;滚珠导轨凭借高刚性、低摩擦与高洁净特性&#xff0c;成为精密运动系统的核心载体。从芯片封装到晶圆检测&#xff0c;其性能直接定义了设备生产的极限精度与可靠性。滚珠导轨在电子制造与半导体设备…

高端装备制造企业如何选择适配的项目管理系统提升项目执行效率?附选型案例

高端装备制造项目通常涉及多专业协同、长周期交付和高风险管控&#xff0c;因此系统需具备全生命周期管理能力。例如&#xff0c;北京奥博思公司出品的 PowerProject 项目管理系统就是一款非常适合制造企业使用的项目管理软件系统。 国内某大型半导体装备制造企业与奥博思软件达…

MS37549/MS37545三相无感正弦波 BLDC 驱动

产品简述 MS37549 和 MS37545 是无感三相直流电机预驱芯片&#xff0c;采用 正弦波驱动方式&#xff0c;具有低噪声及低震动的特点。 芯片通过一个速度控制脚来控制电机的速度。并且电源电压 可以低到 4V 来适应调整电机的转速。 MS37549 和 MS37545 采用 QFN16 …

TCP协议

有连接&#xff0c;可靠传输&#xff0c;面向字节流 16位源端口号 16位目的端口号 4位首部长度 报头的长度&#xff0c;报头中包含了“选项” optional >可选择的&#xff0c;0 - 15 &#xff0c;4个字节&#xff0c;TCP 报头的最大长度是 60 字节 保留位&#xff08;6位…

国标GB28181设备管理软件EasyGBS视频监控平台:社会治安防控的高效解决方案

一、引言​ 随着城市的快速发展和人口的不断增长&#xff0c;社会治安问题日益受到关注。为了有效提升社会治安防控能力&#xff0c;保障人民群众的生命财产安全&#xff0c;视频实时监控系统成为现代城市治理的重要手段之一。EasyGBS作为一款基于GB28181标准的视频监控平台&a…

Spring AI 之对话记忆(Chat Memory)

大型语言模型&#xff08;LLMs&#xff09;是无状态的&#xff0c;这意味着它们不会保留关于之前交互的信息。当想在多次交互中保持上下文或状态时&#xff0c;这可能会成为一个限制。为了解决这一问题&#xff0c;Spring AI 提供了对话记忆功能&#xff0c;允许你在与大型语言…

专家:特朗普对待留学生方式很恐怖 审查似抓间谍

专家:特朗普对待留学生方式很恐怖 审查似抓间谍。特朗普政府计划暂停接受国际学生签证面谈预约,并准备扩大审查申请者的社交媒体账号。这可能意味着对部分国家和地区留学生,以及申请特定大学如哈佛、哥伦比亚大学的留学生和访问学者进行更严格的审查,甚至直接拒绝签证。已经…

常见的SQLserver问题排查

前言&#xff1a; 在日常工作中&#xff0c;SQL Server的管理和维护是一个不可或缺的部分&#xff0c;但随之而来的各种问题也不可避免。面对这些问题时&#xff0c;有效地利用SQL Server自带的功能以及借助第三方工具来进行深入的问题诊断分析变得尤为重要。这样做不仅能够帮助…

代码随想录算法训练营第60期第五十一天打卡

大家好&#xff0c;昨天我们结束了动态规划的题目&#xff0c;其实我们可能还没有完全理解那些题目的真正含义&#xff0c;那其实很正常大家多复习几遍就可以了&#xff0c;那我们今天就将开始一个全新的章节&#xff0c;它就是单调栈&#xff0c;那关于什么是单调栈&#xff0…

苹果Siri升级搁浅:轻资产路线受阻 AI竞争暴露短板

据外媒Business Insider报道,谷歌上周高调发布AI视频工具Flow之际,苹果被迫推迟了生成式AI版Siri的核心升级计划。这一突发状况暴露了苹果在技术上的短板:缺乏自研AI芯片、数据中心依赖谷歌设施、训练数据受限于隐私政策。与谷歌25年来构建的12层技术栈相比,苹果自研AI芯片…

RV1126 + FFPEG多路码流项目

代码主体思路&#xff1a; 一.VI,VENC,RGA模块初始化 1.先创建一个自定义公共结构体&#xff0c;用于方便管理各个模块 rkmedia_config_public.h //文件名字#ifndef _RV1126_PUBLIC_H #define _RV1126_PUBLIC_H#include <assert.h> #include <fcntl.h> #include …