[C] 第6章 C51函数
文章目录
- C51函数
- 函数概述
- 从函数定义角度分类
- 从函数有无返回值分类
- 从函数有无参数
- 函数定义的一般形式
- C51无参函数的一般形式
- C51有参函数的一般形式
- 函数的形式参数和实际参数
- 形式参数
- 实际参数
- 函数的返回值
- 一般形式为:
- 函数的形参和实参的特点
- 函数的调用
- 函数的调用一般形式有以下几种:
- 调用函数需要注意的事项
- 函数的嵌套调用
- 数组作为函数参数
- 用数组元素作实参
- 用数组名作实参
- 局部变量和全局变量
- 局部变量
- 局部变量的作用域
- 全局变量
- 使用全局变量的注意事项
- 变量的存储类型
- 静态局部变量
- 静态全局变量
- register变量
- 外部变量
- 中断函数定义和应用
- 中断函数的定义
- 使用中断函数应注意的事项
- 中断函数定义和应用
- 中断函数的定义
- 使用中断函数应注意的事项
C51函数
-
C51源程序由一个或多个函数组成的。
-
函数是C51程序的基本模块,通过对函数模块的调用实现特定的功能。
函数概述
(1)完整的C51程序:不限制,但void main(void)函数只能有1个;
(2)不能嵌套定义,即在一个函数的函数体内,不能再定义另一个函数;
(3)允许嵌套调用,函数之间允许相互调用;
(4)函数还可以自己调用自己,称为递归调用;
(5)main函数是主函数,它可以调用其他函数,而不允许被其他函数调用。
- 举例(递归:阶乘)
int factorial(int n) {if (n == 0) return 1;else return n * factorial(n-1);
}
从函数定义角度分类
- 库函数
由C51编译系统提供,用户无需定义,也不必再程序中作类型说明,在使用时只需要在程序前包含有该函数原型的头文件,即可在程序中直接带调用。如printf函数就是库函数。
- 用户定义函数
(1)由用户按特定需要所编写的函数称为用户自定义函数;
(2)用户定义函数,不仅要在程序中定义函数本身,而且要在主函数模块中还必须要对该被调函数进行类型说明,然后才能使用。
从函数有无返回值分类
- 有返回值函数
(1)此类函数被调用后,将向调用者返回执行结果,称为函数返回值。
(2)用户定义的这种需要返回函数值的函数,必须在函数定义和说明中明确返回值的函数。
- 举例(某单片机系统程序中的矩阵键盘的键值处理函数)
unsigned char KeyPad(unsigned char key) //说明函数返回值类型为unsigned char类型
{unsigned char keyID;switch(key){case 0x7e:keyID = 0;break; //0号按键被按下····省略的的代码}return keyID; //返回的键值
}
- 无返回值函数
(1)此类函数用于完成某项特别的任务,执行完成后不向调用者返回函数值。
(2)由于函数无需返回值,用户定义此类函数时可指定他的返回为“空类型”。空类型说明符为void。
- 举例(1ms的延时函数)
void delaytime(void) //函数返回值函数为空(void)
{unsigned char i = 125;while(i--);
}
从函数有无参数
- 无参函数
(1)无参函数在函数定义、函数说明及函数调用中均不带参数;
(2)主调函数和被调函数之间不进行参数传送;
(3)此函数通常用于完成一组指定的功能,可以返回或不返回函数值。
- 有参函数
(1)有参函数也称带参函数,在函数定义及函数说明时都有参数,称为形式参数(简称形参);
(2)在函数调用时也必须给出参数,称为实际参数(简称实参);
(3)进行函数调用时,主调函数将把实参的值传给形参,供被调函数使用。
- 举例(通过主函数调用延时函数)
void delaytime(unsigned char time); //声明延时函数,并定义其为带入口参数的函数,无返回值
void main(void)
{delaytime(100); //调用延时函数产生100ms的延时//其他程序
}
//延时函数的实际内容为下
void delaytime(unsigned char time) //函数返回值函数为空(void)
{unsigned char i; //定义循环条件控制变量while(time--){for(i=0;i<=125;i++){;} //延时1ms}
}
函数定义的一般形式
不同的函数形式具有不同的定义方式,下面从有无入口参数分类讲解函数的定义形式。
C51无参函数的一般形式
- 无参函数的一般形式如下:
类型说明符 函数名()
{类型说明语句
}
-
说明
- 说明符和函数名称为函数头。其中类型说明符说明了本函数的返回值类型;
- 函数名是由用户定义的标识符,函数名后有一个空括号,其中无参数,但括号不可少;
- {}中的内容成为函数体;
- 在函数体中也有类型说明,这是对函数体内部所用到的变量的类型说明;
- 在很多情况下都不要求无参函数有返回值,此时函数类型符可写为void(即无返回值函数)。
-
举例
void PrintfHello(void) //定义为void,无返回值
{printf("Hello ,world\n");
}
C51有参函数的一般形式
- 有参函数的一般形式:
类型说明符 函数名(形式参数表)
形式参数类型说明符
{类型说明语句
}
-
说明
- 有参函数比无参函数多了两项内容:形式参数和形式参数类型说明符;
- 在形式参数表中给出的参数称为形式参数,它可以是各种类型的变量,各参数之间用逗号间隔;
- 在进行函数调用时,主调函数将把实际的值赋予这些形式参数;
- 形式参数既然是变量,就必须给与类型说明。
-
举例(定义一个函数,用于求两个数中的大数)不常用
int max(a,b)
int a,b;
{if(a>b){return a;}else{return b;}
}
- 说明示例
(1)第一行说明max函数是一个整形函数,其返回的函数值是一个整数,形式参数为a,b;
(2)第二行说明a,b均为整数值;
(3)a,b的具体值是由主调函数在调用时传送过的;
(4)在{}中的函数体内,除形式参数外没有使用其他变量,因此只有语句而没有变量类型说明;
(5)上述这种方式称为“传统方式”。这种方式不利于编译器用时发生的数据传输是单向的检查,从而会引起细微而难以跟踪的错误;
(6)ANSI C的新标准把对形式参数的类型说明合并到形式参数表中,称为“现代模式”。
- 举例(上面max函数用现代格式可定义为)常用
int max(int a,int b)
{if(a>b){return a;}else{return b;}
}
- 注意
(1)在C语言程序中,一个函数的定义可以放在任意位置,即可放在主调函数之前,也可放在主调函数之后;
(2)如果放在被调函数之后,需要在程序开头声明次被调函数。
- 举例1(被调函数放在主调函数之前,可省略此被调函数的声明)
//被调函数放在主调函数之前
int max(int a,int b)
{if(a>b){return a;}else{return b;}
}
void main(void)
{int x,y,z;printf("input two numbers:\n");scanf("%d%d",&x,&y);z = max(x,y);printf("maxnum = %d",z);
}
- 举例2(被调函数放在主调函数之后,需要在程序开头声明此被调函数)
int max(int a,int b); //声明该被调函数
void main(void)
{int x,y,z;printf("input two numbers:\n");scanf("%d%d",&x,&y);z = max(x,y);printf("maxnum = %d",z);
}
//被调函数放在主调函数之后
int max(int a,int b)
{if(a>b){return a;}else{return b;}
}
函数的形式参数和实际参数
形式参数和实际参数都是函数的入口参数。
形式参数
(1)形式参数是在函数定义时,将定义一个或多个变量作为函数的入口参数;
(2)形式参数时概念上的定义,并不传递实际的值,缺为实际参数传入提供接口。
实际参数
实际参数是函数在被其他函数调用时,从其他传入的实际变量值。
函数的返回值
函数的返回值是函数处理后的结果,在调用函数的最后,通过return语句将函数的返回值返回给主调函数。
一般形式为:
return(表达式);
//或
return 表达式;
//或
return;
函数的形参和实参的特点
函数的形参和实参的特点:
(1)形式参数只有在被调用时才分配内存单元,在调用结束时,即可释放所分配的内存单元;
(1.1)形参只有在函数内部有效。函数调用结束并返回主调函数后,则不能再使用该形参变量。
(2)实参可以是常数、变量、表达式、函数等,无论实参时何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传给形参;
(2.1)实参应预先赋值、输入等办法使实参获得确定值。
(3)实参和形参在数量、类型、顺序上应严格一致,否则会发生“类型不匹配”的错误;
(4)函数调用中的数据传递是单向的,即只能把实参的值传给形参,而不能把形参的值反向传给实参;
(4.1)因此在函数调用过程中,形参的值发生改变,而实参中的值不会改变。
函数的调用
函数的调用一般形式有以下几种:
- 函数语句
//直接调用函数,实现某种特定功能:
delaytime();
Function();
printf("Hello,World!\n");
- 函数表达式
//通过函数表达式将函数的返回值赋给相应的变量
m = max(a,b) * 2;
keyvalue = KeyPad(key);
- 函数参数
//函数的实参直接使用被调函数的返回值作为实参:
printf("%d".max(a,b));
m = max(a.max(b,c));
Function(KeyPad(key));
调用函数需要注意的事项
- 先声明,后调用
(1)自定义功能子函数位于主调函数前面时,可以直接调用被调函数,无需声明被调函数;
(2)自定义功能子函数位于主调函数后面,需要声明语句声明子函数。
- 示例
void delay(void); /*声明子函数*/
void light1(void); /*声明子函数*/
void light2(void); /*声明子函数*/
- 函数的连接
当函数中子函数与主函数不在同一个函数文件时,需要连接的方法实现有效的调用。
- 外部声明,程序如下
extern void delay(void); /*声明该函数在其他文件中*/
extern void light1(void); /*声明该函数在其他文件中*/
extern void light2(void); /*声明该函数在其他文件中*/
- 文件包括,程序如下
#include <REG51.H>
#include "user.c"
/*包含文件user,一般情况下,user与主函数程序文件在同一文件夹下,即当前文件夹,与包含头文件也有所不同,是用双引号给出包含文件的文件名*/
函数的嵌套调用
在C51语句中,函数不可以嵌套定义,但可以嵌套调用。
- 示例(求3个数中最大值和最小值的差值)
int dif(int x,int y,int z);
int max(int x,int y,int z);
int min(int x.int y,int z);
/******************主函数**********************/
int main(void)
{int a,b,c,d;scanf("%d%d%d",&a,&b,&c);d = dif(a,b,c); //调用求差值函数printf("Max-Min = %d\n",d) //输出结果
}
/*****************求差值函数*******************/
int dif(int x,int y,int z)
{return max(x,y,z)-min(x,y,z);}
/*******************求最大数函数*****************/
int max(int x,int y,int z)
{int r;r = x>y?x:y;return (r>z?r:z)
}
/*********************求最小数函数*********************/
int min(int x,int y,int z)
{int r;r = x<y?x:y;return (r<z?r:z);
}
数组作为函数参数
用数组元素作实参
(1)用数组元素作实参时,只需要数组类型和函数的形参变量的类型一致,那么作为下标变量的数组元素的类型和函数形参变量的类型是一致的。因此,并不要求函数的形参也是下标变量;
(2)换句话说,对数组元素的处理是按普通变量对待的;
(3)在普通变量下或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元;
(4)在函数调用时发生的值传送是把实参变量的值赋予形参变量。
- 示例(某单片机系统程序中数码管的显示程序)
#include “reg51.h”
void delay(int time); //声明延时函数
sfr LED = 0XA0; //定义LED为P2口地址
unsigned char code LED_SUM[10] = {0XFC,0X61,0XDA,0XF2,0X66,0XB6,0XBE,0XE0,0XFE,0XF6}//0~9的显示编码存储于LED_SUM中
void Disp(unsigned char LedValue)
{LED = LedValue; //根据i的值将LED_SUM数组中的编码放到P2口显示
}
void delay(int time) //定义延时函数
{unsigned char i; //定义循环条件控制变量while(time--){for(i=0;i<=125;i++){;} //延时1ms}
}
void main(void)
{int i;for(i=0;i<=9;i++){Disp(LED_SUM[i]); //调用Disp函数delay(1000); //延时1ms}
}
用数组名作实参
(1)用数组名作函数参数时,要求形参与相对应的实参都必须是类型相同的数组,都必须有明确的数组说明;
(2)数组名是是数组的首地址;
(3)形参数组和实参数组的长度可以不相同,但操作时需确保不越界,否则会导致内存错误。因为在调用时,只传首地址而不检查形参数组的长度。当形参和实参数组长度不一致时,虽不至于出现语法错误(编译可以通过),但程序执行结果将与实际不符,应予以注意。
局部变量和全局变量
局部变量
(1)局部变量是在函数内做定义说明的。
(2)其作用域:仅限函数内部,离开函数在使用这种变量就是非法的。
- 举例(函数的局部变量定义)
/************a,b,c的作用域仅限于f1函数中*****************/
int f1(int a)
{int b,c;.....
}
/************x,y,z的作用域仅限于f2函数中*****************/
int f2(int x)
{int y,z;.....
}
/************m,n的作用域仅限于main函数中*****************/
void main(void)
{int m,n;
}
局部变量的作用域
注意:
(1)主函数和其他函数是平行关系。即主函数中定义的变量只能在主函数使用,主函数不能使用其他函数定义的变量;
(2)形参变量属于被调函数的局部变量,实参变量属于主调函数的局部变量;
(3)允许在不同函数中使用相同的变量名,他们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆;
(4)在复合语句中也可定义变量,其作用域只在复合语句范围内。
- 举例(复合语句的局部定义)
void main(void)
{int s,a;{int b;a = a+b;//b的作用域}//s,a的作用域
}
- 举例(主函数与复合语句内变量的作用范围)
void main(void)
{int i=3,j=2,k;k = i+j;{int k = 8;if(i == 3)printf("%d\n",k);}printf("%d\n%d\n",i,k);
}输出结果:
8
3
5
全局变量
(1)在函数外部定义的变量;
(2)它不属于哪个函数,它属于一个源程序文件;
(3)作用域:整个源文件;
(4)全局变量的说明符:extern。
- 举例(外部变量定义的方法)
int a,b; /*外部变量*/
void f1() /*函数f1*/
{....
}
float x,y; /*外部变量*/
int fz() /*函数fz*/
{....
}
void main(void) /*主函数*/
{....
} /*全局变量x,y作用域 全局变量a,b作用域*/
使用全局变量的注意事项
- (1)
extern
用于声明外部变量,而非定义
其一般形式为:
[extern] 类型说明符 变量名,变量名... //其中方括号里的extern可以省去不写
- 举例(外部变量的定义方法)
int a,b;
- 等效于
extern int a,b;
-
(2)尽量不要使用全局变量,函数的独立性降低(相反,但加强了函数模块间的数据联系);
-
(3)在同一源文件中,允许全局变量和局部变量同名。在局部变量的作用域内,全局变量不起作用。
-
举例(局部变量和全局变量重名)
int vs(int length,int width)
{extern int height;int v;v = length * width * height;return v;
}
void main(void)
{extern int width,height;int length = 5;printf("v = %d",vs(length,width));
}
int length = 3,width = 4,height = 5; //定义外部变量输出结果:
100
变量的存储类型
变量的存储类型是指变量占用空间的方式,也称存储方式。
静态局部变量
(1)静态函数变量在函数内定义,它的生存周期为整个源程序,而不像自动变量那样,当调用时就存在,退出函数时就消失;
(2)作用域:只能在定义该变量的函数内使用。退出该函数后,尽管该变量还继续存在(它仍占用一定的空间),但不能使用它;
(3)允许对构造类静态局部变量赋初值;
(4)基本类型的静态局部变量,若在说明时未赋以初值,则系统自动赋值0值。若自动变量不赋初值,则其值是不确定的;
(5)静态局部变量适用于多次调用一个函数时且要求在调用过程中保留某些变量的值时。
- 举例(自动变量使用示例)
void main(void)
{int i;void fun(); /*函数声明*/for(i=1;i<=5;i++){fun(); /*函数调用*/}while(1);
}
void fun() /*函数定义*/
{auto int j = 0;++j;printf("%d\n",j);
}
输出结果:
1
1
1
1
1
- 举例(静态局部变量使用)
void main(void)
{int i;void fun();for(i=1;i<=5;i++)fun();while(1);
}
void fun(void)
{static int j = 0;++j;printf("%d\n",j);
}输出结果:
1
2
3
4
5
静态全局变量
register变量
介绍:
(1)前面各类变量都存放在存储器中,因此当对一个变量频繁读写时,必须反复访问存储器,从而花费大量的存取时间;
(2)为此,C51语言提供了另一种变量,即寄存器变量,这种变量存放在CPU的寄存器中,不需要访问内存,而直接从寄存器中读写,这样可以提高效率;
(3)寄存器变量的说明符时register。形式举例:
register a,b = 0; //说明变量a,b为寄存器类型
外部变量
- 外部变量的类型说明符为extern。
特点(补充前面):
(1)外部变量和全局变量是对同一类变量的两种角度的提法。全集变量是根据他的作用域提出的,外部变量是根据它的存储方式提出的,表示了它的生存期;
(2)当一个源程序由若干源文件组成时,在一个源文件中定义的外部变量在其他文件中也有效。
- 举例(外部变量使用)
如有一个源程序由源文件Fun1.c和Fun2.c组成。/*************Fun1.c的内容如下:****************/
int a,b; /*外部变量定义*/
char c;
void main(void) /*外部变量定义*/
{....
}/*************Fun2.c的内容如下:****************/
extern int a,b; /*外部变量声明*/
extern char c; /*外部变量声明*/
void func(int x,y)
{....
}解释说明:
(1)Fun1.c和Fun2.c这两个文件都是用使用了a,b,c三个变量;
(2)在Fun1.c文件中把a、b、c都定义为外部变量;
(3)在Fun2.c文件中用extern把3个变量说明为外部变量,表示这些变量已经在其他文件中定义,编译系统不再为它们分配内存空间。
中断函数定义和应用
- 中断函数是C51语言定义的用于响应51单片机中断的函数,中断函数通过使用interrupt关键字和中断号n(n = 0~31)来实现。
中断函数的定义
- 定义方式
void 函数名() interrupt n [using m]特点:
(1)中断号n和中断向量取决于单片机的型号,编译器从8n+3处产生中断向量;
(2)using m是一个可选项,用于指定中断函数所使用的寄存器组;
(3)m取值为 0~3,对应 8051 的 4 组工作寄存器(0 为默认组)。
使用中断函数应注意的事项
(1)中断函数不能进行参数传递;
(2)中断函数没有返回值;
(3)任何情况下都不能调用中断函数,否则会产生编译错误;
(4)如果中断函数中用到浮点运算,必须保存浮点寄存器的状态,当没有其他程序执行浮点运算时可以不保存;
(5)由于中断产生的随机性,中断函数对其他函数可能形成违规调用,需要时可能被中断函数所调用的其他函数定义为可重入函数。
- 举例
如有一个源程序由源文件Fun1.c和Fun2.c组成。/*************Fun1.c的内容如下:****************/
int a,b; /*外部变量定义*/
char c;
void main(void) /*外部变量定义*/
{....
}/*************Fun2.c的内容如下:****************/
extern int a,b; /*外部变量声明*/
extern char c; /*外部变量声明*/
void func(int x,y)
{....
}解释说明:
(1)Fun1.c和Fun2.c这两个文件都是用使用了a,b,c三个变量;
(2)在Fun1.c文件中把a、b、c都定义为外部变量;
(3)在Fun2.c文件中用extern把3个变量说明为外部变量,表示这些变量已经在其他文件中定义,编译系统不再为它们分配内存空间。
中断函数定义和应用
- 中断函数是C51语言定义的用于响应51单片机中断的函数,中断函数通过使用interrupt关键字和中断号n(n = 0~31)来实现。
中断函数的定义
- 定义方式
void 函数名() interrupt n [using m]特点:
(1)中断号n和中断向量取决于单片机的型号,编译器从8n+3处产生中断向量;
(2)using m是一个可选项,用于指定中断函数所使用的寄存器组;
(3)m取值为 0~3,对应 8051 的 4 组工作寄存器(0 为默认组)。
使用中断函数应注意的事项
(1)中断函数不能进行参数传递;
(2)中断函数没有返回值;
(3)任何情况下都不能调用中断函数,否则会产生编译错误;
(4)如果中断函数中用到浮点运算,必须保存浮点寄存器的状态,当没有其他程序执行浮点运算时可以不保存;
(5)由于中断产生的随机性,中断函数对其他函数可能形成违规调用,需要时可能被中断函数所调用的其他函数定义为可重入函数。
相关文章:
[C] 第6章 C51函数
文章目录 C51函数函数概述从函数定义角度分类从函数有无返回值分类从函数有无参数 函数定义的一般形式C51无参函数的一般形式C51有参函数的一般形式 函数的形式参数和实际参数形式参数实际参数函数的返回值一般形式为: 函数的形参和实参的特点 函数的调用函数的调用…...
docker 配置代理
docker 配置代理有 2 中方法 1.Daemon configuration 直接在 /etc/docker/daemon.json 文件中配置 {"proxies": {"http-proxy": "http://proxy.example.com:3128","https-proxy": "https://proxy.example.com:3129",&quo…...
Redis 深度解析:从核心原理到生产实践
Redis 深度解析:从核心原理到生产实践 一、Redis 核心定位与数据结构 1. 核心能力矩阵深度解析 Redis 作为高性能内存数据库,核心能力覆盖缓存、数据存储、消息中间件等场景,其设计哲学围绕速度优先、内存高效、功能丰富展开: …...
从零搭建高可用分布式限流组件:设计模式与Redis令牌桶实践
一、需求背景与设计目标 在分布式系统中,面对突发流量时需要一种精准可控的流量控制手段。我们的组件需要具备: 多维度限流(用户/IP/服务节点/自定义表达式)分布式环境下精准控制开箱即用的Spring Boot Starter集成高扩展性的架…...
基于霍尔效应传感器的 BLDC 电机梯形控制方案详解
基于霍尔效应传感器的 BLDC 电机梯形控制方案解读 使用霍尔效应传感器的无刷直流(BLDC)电机梯形控制 一、系统核心架构与技术优势 (一)BLDC 电机与霍尔传感器控制原理 BLDC 电机作为永磁同步电机的一种,其核心特征是转子反电动势为梯形波,定子电流为 120 电角度宽度的矩…...
Pikachu靶场-File Inclusion
文件包含漏洞(File Inclusion Vulnerability)是Web应用程序中的一种常见安全漏洞,通常由于开发者未对用户输入进行严格过滤,导致攻击者能够包含并执行恶意文件。这种漏洞主要分为两种类型: 1. 漏洞类型 本地文件包含&a…...
如何模拟黑客攻击(Red Teaming)以测试服务器安全性
模拟黑客攻击(Red Teaming)是评估服务器安全性的有效方法,但需严格遵循**合法授权**和**道德准则**。以下是专业且安全的操作流程: --- ### **1. 前期准备** - **法律授权** - 获得目标系统的**书面授权**,明确测…...
分页查询优惠券
文章目录 概要整体架构流程技术细节小结 概要 接口分析 一个典型的带过滤条件的分页查询,非常简单。按照Restful风格设计即可,我们关注的点有两个: 请求参数 返回值格式 请求参数包含两部分,一个是分页参数,另一…...
QTcpSocket 和 QUdpSocket 来实现基于 TCP 和 UDP 的网络通信
在 Qt 中,您可以通过 QTcpSocket 和 QUdpSocket 来实现基于 TCP 和 UDP 的网络通信。以下是如何使用 Qt 实现这两种通信方式的简要示例。 1. TCP 网络通信 TCP 是面向连接的协议,确保数据的可靠传输。下面是一个简单的 TCP 客户端和服务器示例。 TCP …...
从岗位依附到能力生态:AI革命下“什么叫就业”的重构与价值
在人工智能(AI)技术深刻重塑社会生产关系的当下,“就业”这一概念正经历着从“职业绑定”到“能力变现”的范式转移。本文将从传统就业观的解构、AI赋能艺术教育的价值逻辑、以及未来就业形态的进化方向三个维度,探讨技术驱动下就业的本质变革,并揭示AI技术如何通过教育创…...
2025上海车展 | 移远通信全栈车载智能解决方案重磅亮相,重构“全域智能”出行新范式
2025年4月23日至5月2日,第二十一届上海国际汽车工业展览会在国家会展中心(上海)盛大启幕。作为车载智能解决方案领域的领军企业,移远通信以“全域智能 驭见未来”为主题,携丰富的车载解决方案及客户终端惊艳亮相8.2馆8…...
LVGL在VScode的WSL2中仿真
目录 一、前言 二、开始部署 1.拉取github的库 2.在WSL安装一些必要的库或者包 3.开始编译 三、注意事项 一、前言 相信有不少兄弟因为苦于没有外设而无法学习LVGL,这里我提供一种WSL中仿真LVGL工程的方法。结果图如下: 二、开始部署 1.拉取github…...
React-组件和props
1、类组件 import React from react; class ClassApp extends React.Component {constructor(props) {super(props);this.state{};}render() {return (<div><h1>这是一个类组件</h1><p>接收父组件传过来的值:{this.props.name}</p>&…...
驱动开发系列53 - 一个OpenGL应用程序是如何调用到驱动厂商GL库的
一:概述 一个 OpenGL 应用程序调用 GPU 驱动的过程,主要是通过动态链接库(libGL.so)来完成的。本文从上到下梳理一下整个调用链,包含 GLVND、Mesa 或厂商驱动之间的关系。 二:调用关系 1. 首先一个 OpenGL 应用程序(比如游戏或图形渲染软件)在运行时会调用 OpenGL 提供…...
【python】一文掌握 markitdown 库的操作(用于将文件和办公文档转换为Markdown的Python工具)
更多内容请见: python3案例和总结-专栏介绍和目录 文章目录 一、markitdown概述1.1 markitdown介绍1.2 MarkItDown支持的文件1.3 为什么是Markdown?二、markitdown安装2.1 pip方式安装2.2 源码安装2.3 docker方式安装三、基本使用3.1 命令行方式3.2 可选依赖项配置3.3 插件方…...
【网络入侵检测】基于Suricata源码分析NFQ IPS模式实现
【作者主页】只道当时是寻常 【专栏介绍】Suricata入侵检测。专注网络、主机安全,欢迎关注与评论。 1. 概要 👋 本文聚焦于 Suricata 7.0.10 版本源码,深入剖析其 NFQ(Netfilter Queue)模式的实现原理。通过系统性拆解初始化阶段的配置流程、数据包监听机制的构建逻辑,以…...
驱动开发硬核特训 · Day 19:从字符设备出发,掌握 Linux 驱动的实战路径(含 gpio-leds 控制示例)
视频教程请关注 B 站:“嵌入式 Jerry” 一、背景说明:字符设备驱动的角色定位 在 Linux 内核驱动体系中,**字符设备驱动(Character Device Driver)**扮演着关键的桥梁作用,它直接向用户空间程序提供 read/…...
项目——高并发内存池
目录 项目介绍 做的是什么 要求 内存池介绍 池化技术 内存池 解决的问题 设计定长内存池 高并发内存池整体框架设计 ThreadCache ThreadCache整体设计 哈希桶映射对齐规则 ThreadCache TLS无锁访问 CentralCache CentralCache整体设计 CentralCache结构设计 C…...
几种查看PyTorch、cuda 和 Python 版本方法
在检查 PyTorch、cuda 和 Python 版本时,除了直接使用 torch.__version__ 和 sys.version,我们还可以通过其他方式实现相同的功能 方法 1:直接访问属性(原始代码) import torch import sysprint("PyTorch Versi…...
如何实现跟踪+分割的高效协同?SiamMask中的多任务损失设计
如何实现跟踪分割的高效协同?SiamMask中的多任务损失设计 一、引言二、三大分支损失函数详解2.1 分类分支损失2.2 回归分支损失2.3 Mask分支损失 三、损失加权策略与系数选择3.1 常见超参数设定3.2 动态权重(可选) 四、训练实践:平…...
MODBUS转EtherNetIP边缘计算网关配置优化:Logix5000与ATV340高效数据同步与抗干扰方案
一、行业背景 智能制造是当前工业发展的趋势,智能工厂通过集成各种自动化设备和信息技术,实现生产过程的智能化、自动化和高效化。在某智能工厂中,存在大量采用ModbusTCP协议的设备,如智能传感器、变频器等,而工厂的主…...
从代码学习深度学习 - 图像增广 PyTorch 版
文章目录 前言一、图像增广的基本概念二、PyTorch中的图像增广实现三、数据加载与处理四、模型训练与评估五、实验设置与执行六、实验结果与分析七、讨论总结前言 在深度学习中,数据是关键。尤其是在计算机视觉任务中,高质量且丰富多样的数据对模型性能有着决定性的影响。然…...
从机械应答到智能对话:大模型为呼叫注入智慧新动能
引言 在当今竞争激烈的商业环境中,高效和有效的客户沟通对于企业的成功至关重要。智能外呼系统已成为企业与潜在客户和现有客户互动的重要工具。最近,大模型(如大型语言模型或 LLMs)的出现为这些系统带来了显著的提升,…...
深入浅出 Python 协程:从异步基础到开发测试工具的实践指南
Python 的异步编程近年来越来越受欢迎,尤其在需要同时处理大量 I/O 请求的场景中,它展现了出色的性能。而协程是异步编程的核心,也是开发高效异步测试工具的关键技术。 这篇文章将用通俗的语言带你快速入门 Python 协程,结合实际…...
算法之分支定界
分支定界 分支定界概述核心思想与步骤常见变体复杂度分析案例分析1. 0-1背包问题2. 最短路径问题(分支定界法)3. 旅行商问题(TSP) 分支定界 概述 分支定界(Branch and Bound)是一种用于解决组合优化问题的…...
Hugging Face上面找开源的embedding模型
问题 想找一个支持中文的embedding模型(把一段文本转化成多维度的向量)。Hugging Face平台上面共享了很多开源模型,算是这年头(2025年),大家都把自己开源模式都往上放的地方了吧。现在去这个平台上面找一个…...
docker部署Jenkins工具
环境准备 1.当前安装在Windows系统下的Docker-Desktop 下载地址:Docker Desktop: The #1 Containerization Tool for Developers | Docker 2.下载后进行安装并进行配置启动docker 3.创建一个空的文件夹,用于后面的启动时做文件路径映射 下载镜像 d…...
Pgvector+R2R搭建RAG知识库
背景 R2R是一个采用Python编写的开源AI RAG框架项目,与PostgreSQL技术栈集成度高,运行需求资源少(主要是本人的Macbook air m1内存只有8G)的特点,对部署本地私有化化AI RAG应用友好。 Resource Recommendations Whe…...
Qt本地化 - installTranslator不生效
bool QCoreApplication::installTranslator(QTranslator *translationFile)注意这里输入的是QTranslator对象指针,如果QTranslator是局部变量,一旦离开其作用域就会导致翻译失效 错误代码示范: void ApplyTranslator(const QString& qmf…...
精益数据分析(19/126):走出数据误区,拥抱创业愿景
精益数据分析(19/126):走出数据误区,拥抱创业愿景 在创业与数据分析的探索之旅中,我们都渴望获取更多知识,少走弯路。今天,我依然带着和大家共同进步的想法,深入解读《精益数据分析…...
六、初始化与清理(Initialization cleanup)
六、初始化与清理(Initialization & cleanup) 本章内容主要介绍C中的 构造函数 和 析构函数 的作用与用法,以及默认构造、聚合初始化等相关特性 封装 和 *访问控制 *在提升库使用的便捷性方面迈出了重要的一步。在安全性方面࿰…...
Python - 爬虫-网页解析数据-库lxml(支持XPath)
lxml是 Python 的第三方解析库,完全使用 Python 语言编写,它对 Xpath 表达式提供了良好的支持,支持HTML和XML的解析,支持XPath解析方式,而且解析效率非常高 XPath,全称XML Path Language,即XML…...
单片机 + 图像处理芯片 + TFT彩屏 触摸滑动条控件
触摸滑动条控件使用说明 一、项目概述 本项目基于单片机和RA8889/RA6809图形处理芯片的TFT触摸屏滑动条控件。该控件支持水平和垂直滑动条,可自定义外观和行为,并支持回调函数进行值变化通知。 硬件平台:51/ARM均可(测试时使用STC8H8K64U单…...
LeetCode每日一题4.24
2799. 统计完全子数组的数目 题目 问题分析 完全子数组 的定义:子数组中不同元素的数目等于整个数组不同元素的数目。 子数组 是数组中的一个连续非空序列。 思路 统计整个数组的不同元素数目: 使用 set 来获取整个数组的不同元素数目。 遍历所有子数…...
LeetCode238_除自身以外数组的乘积
LeetCode238_除自身以外数组的乘积 标签:#数组 #前缀和Ⅰ. 题目Ⅱ. 示例0. 个人方法一:暴力循环嵌套0. 个人方法二:前缀和后缀分别求积 标签:#数组 #前缀和 Ⅰ. 题目 给你一个整数数组 nums,返回 数组 answer &#…...
基于 Spring Boot 的银行柜台管理系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...
LeetCode 2799.统计完全子数组的数目:滑动窗口(哈希表)
【LetMeFly】2799.统计完全子数组的数目:滑动窗口(哈希表) 力扣题目链接:https://leetcode.cn/problems/count-complete-subarrays-in-an-array/ 给你一个由 正 整数组成的数组 nums 。 如果数组中的某个子数组满足下述条件&am…...
卡尔曼滤波解释及示例
卡尔曼滤波的本质是用数学方法平衡预测与观测的可信度 ,通过不断迭代逼近真实状态。其高效性和鲁棒性,通常在导航定位中,需要融合GPS、加速度计、陀螺仪、激光雷达或摄像头数据,来提高位置精度。简单讲,卡尔曼滤波就是…...
在vue项目中实现svn日志打印
在vue项目中实现svn日志打印 实现svnlog创建svn-log脚本 convert-svn-log.js配置命令 package 实现svnlog 项目工程 类似于git的conventional-changelog 创建svn-log脚本 convert-svn-log.js 在项目根目录创建convert-svn-log.js const fs require(fs-extra); const xml2j…...
使用vue2开发一个医疗预约挂号平台-前端静态网站项目练习
对于后端开发的我,最近一直在学习前端开发,除了要学习一些前端的基础知识外,肯定少不了一些前端项目练习,就通过前端的编程知识 就简单做一个医疗预约挂号前端静态页面。这个网站主要是使用了vue2 的相关技术实现的。 主要实现了这…...
Redis的过期删除策略和内存淘汰策略
🤔 过期删除和内存淘汰乍一看很像,都是做删除操作的,这么分有什么意思? 首先,设置过期时间我们很熟悉,过期时间到了,我么的键就会被删除掉,这就是我们常认识的过期删除,…...
Langchain检索YouTube字幕
创建一个简单搜索引擎,将用户原始问题传递该搜索系统 本文重点:获取保存文档——保存向量数据库——加载向量数据库 专注于youtube的字幕,利用youtube的公开接口,获取元数据 pip install youtube-transscript-api pytube 初始化 …...
服务器上安装node
1.安装 下载安装包 https://nodejs.org/en/download 解压安装包 将安装包上传到/opt/software目录下 cd /opt/software tar -xzvf node-v16.14.2-linux-x64.tar.gz 将解压的文件夹移动到安装目录(/opt/nodejs)下 mv /opt/software/node-v16.14.2-linux-x64 /opt/nodejs …...
React:什么是Hook?通俗易懂的讲讲
什么是Hook 1.Hook 是什么?2.React 内置的 Hook3. 自定义 Hook4. 总结 1.Hook 是什么? 可以理解为:函数组件的工具/功能插件 Hook是 React 16.8 以后提供的一种新特性, 让你在函数组件里“钩入”React 的功能(比如状态…...
树莓派安装GStreamer ,opencv支持, 并在虚拟环境中使用的安装方法
首先是我在树莓派中 使用OpenCV 读取网络视频流, 如海康威视 通过rtsp协议地址读取 会发生延迟和丢包的情况 后来使用ffmpeg和OpenCV 读取视频流 丢报的问题减少了 但是长时间运行 还是会造成延迟和卡顿 最后直接卡死画面 后来试了一下GStreamer 管道流 是树莓派支持的 但是原生…...
从节点重排看React 与 Vue3 的 Diff 算法
一个有趣的问题 之前我写了一篇狗教我 React——原理篇之 Diff 算法 - 掘金 (juejin.cn)简单介绍了 diff 算法,收到了一个有意思的疑问: 大佬讲得非常易懂,我有个疑惑就是都说 diff 处理节点前移比较差,比如 a→b→c→d 更新为 d→a→b→c,如果第一遍循环到第一个就截止了…...
【FAQ】PCoIP 会话后物理工作站本地显示器黑屏
# 问题 工作人员从家里建立了到办公室工作站的 PCoIP 连接,该工作站安装了 HP Anyware Graphics Agent,并且还连接了本地显示器。然后,远程用户决定去办公室进行本地工作,工作站显示器显示黑屏(有时没有信号ÿ…...
springboot基于hadoop的酷狗音乐爬虫大数据分析可视化系统(源码+lw+部署文档+讲解),源码可白嫖!
摘要 本酷狗音乐爬虫大数据分析可视化系统采用B/S架构,数据库是MySQL,网站的搭建与开发采用了先进的Java语言、Hadoop、爬虫技术进行编写,使用了Spring Boot框架。该系统从两个对象:由管理员和用户来对系统进行设计构建。前台主要…...
基于大模型的食管平滑肌瘤全周期预测与诊疗方案研究
目录 一、引言 1.1 研究背景与意义 1.2 研究目的 1.3 国内外研究现状 二、大模型技术原理与应用概述 2.1 大模型介绍 2.2 在医疗领域的应用现状 2.3 用于食管平滑肌瘤预测的可行性分析 三、食管平滑肌瘤术前预测 3.1 预测指标选取 3.2 数据收集与预处理 3.2.1 数据…...
26考研 | 王道 | 数据结构 | 第七章 查找
第七章 查找 文章目录 第七章 查找7.1 查找概念7.2 顺序查找7.3 折半查找7.4 分块查找7.5 二叉排序树7.6 平衡二叉树平衡二叉树的插入平衡二叉树的删除 7.7 红黑树7.7.1 为什么要发明红黑树?7.7.2 红黑树的定义和性质7.7.3 红黑树的插入和删除插入删除 7.8 B树和B树…...