【C++ 四】函数、指针
函数、指针
文章目录
- 函数、指针
- 前言
- 1 函数
- 1.1 概述
- 1.2 函数定义
- 1.3 函数调用
- 1.4 值传递
- 1.5 函数常见样式
- 1.6 函数声明
- 1.7 函数分文件编写
- 1.8 函数默认参数
- 1.9 函数占位参数
- 1.9 函数重载
- 1.9.1 函数重载概述
- 1.9.2 函数重载注意事项
- 2 指针
- 2.1 指针基本概念
- 2.2 指针变量定义和使用
- 2.3 指针所占内存空间
- 2.4 空指针和野指针
- 2.5 const 修饰指针
- 2.6 指针和数组
- 2.7 指针和函数
- 2.8 指针、数组、函数
- 总结
前言
本文包含函数概述、函数定义、函数调用、值传递、函数常见样式、函数声明、函数份文件编写、函数默认参数、函数占位参数、函数重载、指针基本概念、指针变量定义和使用、指针所占内存空间、空指针和野指针、const修饰指针、指针和数组、指针和函数、指针数组函数。
1 函数
1.1 概述
作用: 将一段经常使用的代码封装起来,减少重复代码
一个较大的程序,一般分为若干个程序块,每个模块实现特定的功能
1.2 函数定义
函数的定义一般主要有5个步骤:
(1)、返回值类型
(2)、函数名
(3)、参数表列
(4)、函数体语句
(5)、return 表达式
语法:
返回值类型 函数名 (参数列表)
{函数体语句return表达式}
(1)、返回值类型 :一个函数可以返回一个值。在函数定义中
(2)、函数名:给函数起个名称
(3)、参数列表:使用该函数时,传入的数据
(4)、函数体语句:花括号内的代码,函数内需要执行的语句
(5)、return 表达式: 和返回值类型挂钩,函数执行完后,返回相应的数据
示例: 定义一个加法函数,实现两个数相加
// 返回值类型:int
// 函数名:add
// 参数列表:(int num1, int num2)
// 函数体语句:int sum = num1 + num2;
// return 表达式:return sum;
int add(int num1, int num2)
{int sum = num1 + num2;return sum;
}
1.3 函数调用
功能: 使用定义好的函数
语法: 函数名(参数)
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 函数定义
int add(int num1, int num2) // 定义中的num1,num2称为形式参数,简称形参
{int sum = num1 + num2;return sum;
}int main() {int a = 10;int b = 10;// 调用add函数int sum = add(a, b); // 调用时的a,b称为实际参数,简称实参cout << "sum = " << sum << endl; // 20cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

1.4 值传递
(1)、所谓值传递,就是函数调用时实参将数值传入给形参
(2)、值传递时,如果形参发生,并不会影响实参
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 定义函数,实现两个数字进行交换
void swap(int num1, int num2) // 如果函数不需要返回值,声明的时候可以写void
{cout << "交换前:" << endl;cout << "num1 = " << num1 << endl;cout << "num2 = " << num2 << endl;int temp = num1;num1 = num2;num2 = temp;cout << endl;cout << "交换后:" << endl;cout << "num1 = " << num1 << endl;cout << "num2 = " << num2 << endl;//return ; // 当函数声明时候,不需要返回值,可以不写return
}int main() {int a = 10;int b = 20;cout << "mian中的 a = " << a << endl; // 10cout << "mian中的 b = " << b << endl; // 20swap(a, b); // 当我们做值传递的时候,函数的形参发生改变,并不会影响实参cout << endl;cout << "mian中的 a = " << a << endl; // 10cout << "mian中的 b = " << b << endl; // 20cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

1.5 函数常见样式
常见的函数样式有4种:
(1)、无参无返
(2)、有参无返
(3)、无参有返
(4)、有参有返
// 函数常见样式#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 1、无参无返
void test01()
{//void a = 10; //无类型不可以创建变量,原因无法分配内存cout << "this is test01" << endl;//test01(); 函数调用
}// 2、有参无返
void test02(int a)
{cout << "this is test02" << endl;cout << "a = " << a << endl;
}// 3、无参有返
int test03()
{cout << "this is test03 " << endl;return 10;
}// 4、有参有返
int test04(int a, int b)
{cout << "this is test04 " << endl;int sum = a + b;return sum;
}int main() {test01();cout << endl;test02(10);cout << endl;cout << test03() << endl;cout << endl;cout << test04(20, 30) << endl;cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

1.6 函数声明
作用: 告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义
函数的声明可以多次,但是函数的定义只能有一次
// 函数常见样式#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 声明
int max(int a, int b); // 提前告诉编译器函数的存在,可以利用函数的声明;声明后,函数的定义可以写在main函数之后// 定义
int max(int a, int b)
{return a > b ? a : b; // 比较函数,实现两个整型数字进行比较,返回较大的值
}int main() {int a = 100;int b = 200;cout << max(a, b) << endl; // 调用函数cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

1.7 函数分文件编写
作用: 让代码结构更加清晰
函数分文件编写一般有4个步骤:
(1)、创建后缀名为.h的头文件
(2)、创建后缀名为.cpp的源文件
(3)、在头文件中写函数的声明
(4)、在源文件中写函数的定义
swap.h
#include <iostream> // 包含输入输出流;不写引用cout时会提示:未定义
using namespace std; // 框架;命名空间;域// 实现两个数字交换的函数声明
void swap(int a, int b);
swap.cpp
#include "swap.h" // ""代表自定义的头文件void swap(int a, int b)
{int temp = a;a = b;b = temp;cout << "a = " << a << endl;cout << "b = " << b << endl;
}
main.cpp
#include <iostream>
using namespace std;#include "swap.h"int main() {int a = 100;int b = 200;swap(a, b);cout << endl;system("pause");return 0;
}

1.8 函数默认参数
在 C++ 中,函数的形参列表中的形参是可以有默认值的
语法: 返回值类型 函数名 (参数= 默认值){}
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 如果我们自己传入数据,就用自己的数据,如果没有,那么用默认值
// 语法:返回值类型 函数名 (形参 = 默认值) {}
int func(int a, int b = 10, int c = 10) {return a + b + c;
}// 注意事项:
// 1. 如果某个位置参数有默认值,那么从这个位置往后,从左向右,必须都要有默认值
// 2. 如果函数声明有默认值,函数实现的时候就不能有默认参数
int func2(int a = 10, int b = 10);
int func2(int a, int b) { // 二义性;如果定义func2中给形参a,b默认值,调试程序时会报错;声明和实现只能有一个默认参数return a + b;
}int main() {cout << "ret = " << func(20, 20) << endl; // 50cout << "ret = " << func(100) << endl; // 120cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

1.9 函数占位参数
C++ 中函数的形参列表里可以有占位参数,用来做占位,调用函数时必须填补该位置
语法: 返回值类型 函数名 (数据类型){}
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 语法:返回值类型 函数名 (数据类型) {}
// 函数占位参数 ,占位参数也可以有默认参数 ; {int a, int = 10}
void func(int a, int) {cout << "this is func" << endl;
}int main() {func(10, 10); // 占位参数必须填补cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

1.9 函数重载
1.9.1 函数重载概述
作用: 函数名可以相同,提高复用性
函数重载满足条件:
(1)、同一个作用域下
(2)、函数名称相同
(3)、函数参数类型不同 或者 个数不同 或者 顺序不同
注意: 函数的返回值不可以作为函数重载的条件
// 函数重载:可以让函数名相同,提高复用性#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 函数重载的满足条件
// 1、函数重载需要函数都在同一个作用域下
// 2、函数名称相同
// 3、函数参数类型不同,或者个数不同,或者顺序不同
void func()
{cout << "func 的调用!" << endl;
}void func(int a)
{cout << "func (int a) 的调用!" << endl;
}void func(double a)
{cout << "func (double a)的调用!" << endl;
}void func(int a, double b)
{cout << "func (int a ,double b) 的调用!" << endl;
}void func(double a, int b)
{cout << "func (double a ,int b)的调用!" << endl;
}// 函数返回值不可以作为函数重载条件
//int func(double a, int b)
//{
// cout << "func (double a ,int b)的调用!" << endl;
//}int main() {func();func(10);func(3.14);func(10, 3.14);func(3.14, 10);cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

1.9.2 函数重载注意事项
(1)、引用作为重载条件
(2)、函数重载碰到函数默认参数
// 函数重载注意事项#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 1、引用作为重载条件
void func(int& a)
{// int &a = 10;不合法;引用必须要有合法的内存空间(堆区、栈区);10在常量区cout << "func (int &a) 调用 " << endl;
}void func(const int& a) // 函数重载;int和const int类型不同;const int &a = 10;合法;const会做优化,创建一个临时的数据,&a指向临时的内存空间
{cout << "func (const int &a) 调用 " << endl;
}// 2、函数重载碰到函数默认参数
void func2(int a, int b = 10)
{cout << "func2(int a, int b = 10) 调用" << endl;
}void func2(int a)
{cout << "func2(int a) 调用" << endl;
}int main() {int a = 10;func(a); // 调用无const(int &a);a是变量,可读可写;const只可读func(10); // 调用有const(const int &a) //func2(10); // 碰到默认参数产生歧义,需要避免;二义性cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

2 指针
2.1 指针基本概念
指针的作用: 可以通过指针间接访问内存
(1)、内存编号是从0开始记录的,一般用十六进制数字表示
(2)、可以利用指针变量保存地址
2.2 指针变量定义和使用
指针变量定义语法: 数据类型 * 变量名;
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间int main() {// 1、指针的定义int a = 10; // 定义整型变量a// 指针定义语法: 数据类型 * 变量名 ;int* p;// 指针变量赋值p = &a; // 指针指向变量a的地址cout << &a << endl; // 打印数据a的地址 ; 00FFA5Ccout << p << endl; // 打印指针变量p ; 00FFA5C// 2、指针的使用// 通过*操作指针变量指向的内存cout << "*p = " << *p << endl; // 10 ; 通过解引用的方式来找到指针指向的内存中的数据cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

指针变量和普通变量的区别:
(1)、普通变量存放的是数据,指针变量存放的是地址
(2)指针变量可以通过" * "操作符,操作指针变量指向的内存空间,这个过程称为解引用
2.3 指针所占内存空间
提问: 指针也是种数据类型,那么这种数据类型占用多少内存空间?
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间int main() {int a = 10;int* p = &a; // 指针指向数据a的地址cout << *p << endl; // * 解引用 ; 10// 在32位操作系统下,指针是占4个字节空间大小,不管是什么数据类型// 在64位操作系统下,指针是占8个字节空间打下cout << sizeof(p) << endl; // 8cout << sizeof(char*) << endl; // 8cout << sizeof(float*) << endl; // 8cout << sizeof(double*) << endl; // 8cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

2.4 空指针和野指针
空指针: 指针变量指向内存中编号为0的空间
用途: 初始化指针变量
注意: 空指针指向的内存是不可以访问的
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间int main() {// 指针变量p指向内存地址编号为0的空间int* p = NULL;// 访问空指针报错 // 内存编号0 ~255为系统占用内存,不允许用户访问cout << *p << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}
野指针: 指针变量指向非法的内存空间
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间int main() {// 指针变量p指向内存地址编号为0x1100的空间int* p = (int*)0x1100; // 0x1100十六进制;(int *)强转为指针类型;没有权利操作编号为0x1100的内存空间// 访问野指针报错 cout << *p << endl; // 引发异常:读取访问权限冲突system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}
2.5 const 修饰指针
const 修饰指针有三种情况:
(1)、const 修饰指针 — 常量指针

(2)、const 修饰常量 — 指针常量

(3)、const 即修饰指针,又修饰常量

#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间int main() {int a = 10;int b = 10;// 1、常量指针// const 修饰的是指针,指针指向可以改,指针指向的值不可以更改const int* p1 = &a;p1 = &b; // 正确// *p1 = 100; 报错// 2、指针常量// const 修饰的是常量,指针指向不可以改,指针指向的值可以更改int* const p2 = &a;//p2 = &b; // 错误*p2 = 100; // 正确// 3、const 既修饰指针又修饰常量const int* const p3 = &a;// p3 = &b; // 错误// *p3 = 100; // 错误system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}
2.6 指针和数组
作用: 利用指针访问数组中元素
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间int main() {int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr; // 指向数组的指针;arr就是数组首地址cout << "第一个元素: " << arr[0] << endl; // 1cout << "指针访问第一个元素: " << *p << endl; // 1p++; // 让指针向后偏移4/8个字节(看不同操作系统)cout << "指针访问第二个元素: " << *p << endl; // 2cout << endl;p--;for (int i = 0; i < 10; i++){//利用指针遍历数组cout << *p << endl;p++;}cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

2.7 指针和函数
作用: 利用指针作函数参数,可以修改实参的值
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 值传递
void swap1(int a, int b)
{int temp = a;a = b;b = temp;
}// 地址传递
void swap2(int* p1, int* p2)
{int temp = *p1;*p1 = *p2;*p2 = temp;
}int main() {int a = 10;int b = 20;swap1(a, b); // 值传递不会改变实参swap2(&a, &b); // 地址传递会改变实参cout << "a = " << a << endl; // 20cout << "b = " << b << endl; // 10cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

2.8 指针、数组、函数
案例描述: 封装一个函数,利用冒泡排序,实现对整型数组的升序排序
例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
#include <iostream> // 包含标准输入输出流文件
using namespace std; // 使用标准命名空间// 冒泡排序函数
void bubbleSort(int* arr, int len) // int * arr 也可以写为int arr[];数组首地址;数组长度
{for (int i = 0; i < len - 1; i++){for (int j = 0; j < len - 1 - i; j++){if (arr[j] > arr[j + 1]){int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}
}// 打印数组函数
void printArray(int arr[], int len)
{for (int i = 0; i < len; i++){cout << arr[i] << " ";}cout << endl;
}int main() {int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };int len = sizeof(arr) / sizeof(int); // 数组长度bubbleSort(arr, len);printArray(arr, len); // 1,2,3,4,5,6,7,8,9,10cout << endl;system("pause"); // 相当于在本地 Windows 调试器中的:请按任意键继续...;暂停,方便看清楚输出结果return 0; // 程序正常退出
}

总结
(1)、函数定义里小括号内称为形参,函数调用时传入的参数称为实参;
(2)、值传递时,形参是修饰不了实参的;
(3)、我们可以通过 & 符号 获取变量的地址;
(4)、利用指针可以记录地址;
(5)、对指针变量解引用,可以操作指针指向的内存;
(6)、所有指针类型在32位操作系统下是4个字节;
(7)、空指针和野指针都不是我们申请的空间,因此不要访问;
(8)、技巧:看const右侧紧跟着的是指针还是常量,是指针就是常量指针,是常量就是指针常量;
(9)、如果不想修改实参,就用值传递,如果想修改实参,就用地址传递;
(10)、当数组名传入到函数作为参数时,被退化为指向首元素的指针。
相关文章:
【C++ 四】函数、指针
函数、指针 文章目录 函数、指针前言1 函数1.1 概述1.2 函数定义1.3 函数调用1.4 值传递1.5 函数常见样式1.6 函数声明1.7 函数分文件编写1.8 函数默认参数1.9 函数占位参数1.9 函数重载1.9.1 函数重载概述1.9.2 函数重载注意事项 2 指针2.1 指针基本概念2.2 指针变量定义和使用…...
虚拟人与娱乐传媒融合,推动综艺新模式
经过多年的更新迭代和市场的推动,虚拟人技术正在逐渐迈向成熟:3D虚拟形象的制作变得越来越精致且真实,并且出现了越来越多功能丰富使用便捷的动捕设备。因此,包括综艺影视在内的诸多领域,开始尝试将虚拟人技术融入行业…...
Linux_红帽8学习笔记分享_5
Linux_红帽8学习笔记分享_5 文章目录 Linux_红帽8学习笔记分享_51. UMASK反掩码1.1如何查看反掩码umask1.2 UMASK反掩码的作用1.2.1对于目录来说1.2.2对于文件来说 1.3如何修改UMASK反掩码1.4普通用户反掩码的测试 2.whereis的使用3. SUID权限弥补(主要针对文件,所有者执行位变…...
网络编程及项目思路
计算机和计算机之间通过网络进行数据传输 常见的软件架构: C/S:客户端/服务器 画面可以做的非常精美,用户体验好需要开发客户端,也需要开发服务端用户需要下载和更新的时候太麻烦 B/S:浏览器/服务器 不需要开发客户端,只需要…...
GD(兆易创新)系列FLASH进行FPGA和ZYNQ配置固化相操作
写在前面 本文主要针对使用GD(兆易创新)系列的FLASH做启动配置片时,遇到的相关问题进行简单整理复盘,避免后人踩坑。 本人操作固化芯片型号为:ZYNQ7045、690T(复旦微替代型号V7 690T)。 7系列…...
通过一个小例子来看一下C语言指针 p、*p、p、*p、*p分别代表什么
前言 在C语言中,指针是非常重要的概念。指针是一个变量,其值为另一个变量的地址。使用指针可以直接访问内存中的数据,这使得C语言非常灵活和强大。在学习C语言时相比大家都已经知道了&和*的区别了,但是你知道*&p和&*…...
【内摹访谈】谈谈AI爆发前夜的B端设计
本文来自摹客产品设计团队(MPD)的设计专栏“内摹访谈”。专栏介绍:专栏名称来源于西方美学理论「内摹仿说」,意指审美活动与摹仿活动紧密相连,审美不只针对表象动作,其核心在于由物及我,从表观带…...
Redis—AOF持久化
一、AOF定义 保存写操作命令到日志的持久化方式,就是 Redis 里的 AOF(Append Only File) 持久化功能 定义:以日志的形式记录每个操作,记录写指令不记录读指令,只许追加⽂件不允许修改,AOF保存的是appendonly.aof⽂件…...
OpenCV实例(五)指纹识别
OpenCV实例(五)指纹识别 1.指纹识别概述1.1概述1.2原理 2.指纹识别算法2.1特征提取2.2MCC匹配方法2.3尺度不变特征变换(SIFT) 3.显示指纹的关键点4.基于SIFT的指纹识别 作者:Xiou 1.指纹识别概述 1.1概述 指纹识别&…...
第二章 法的内容与形式
目录 第一节 法的内容与形式的概念 一、法的内容与形式的含义 二、法的内容和形式的关系 第二节 法律权利与法律义务 一、权利和义务的概念 二、权利和义务的分类 三、权利与义务的联系 第三节 法的成文形式与不成文形式 一、历史上各种法的表现形式 二、成文法与不成文…...
外包干了四年,感觉废了..
先说一下自己的情况,大专生,18年通过校招进入湖南某软件公司,干了接近4年的功能测试,今年年初,感觉自己不能够在这样下去了,长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...
Git如何推送当前代码到远程仓库
第一种方法 (建立在已经配置好用户变量和ssh基础上) 在本地创建git仓库 git init 绑定远程仓库,origin是给远程仓库起的别名,也可以起其他名字,但是如果用origin,git push时可以不指出名字,如果…...
第五章 工厂模式
文章目录 一、简单工厂模式1、传统方式实现披萨订购( 可以忽略)披萨父类 Pizza子类胡椒披萨 PepperPizza子类印度披萨 GreekPizza订购披萨 OrderPizza订购披萨的 客户端 PizzaStore运行结果传统的方式的优缺点,新增子类需要修改的地方牵扯太多传统方式的究极耦合 2、…...
Spring MVC 参数解析(13)
目录 简介 调用流程 1. 首先,还是需要进行到前端控制器的doDispatch方法,这是我们的调用Spring MVC的核心入口方法 2. 在doDispatch方法内部,我们调用到了HandlerAdapter.handle(*****) 方法 3. 最终,我们会来到 RequestMappi…...
探索 Qt WebEngineWidgets:从底层原理到高级应用与技巧
探索 Qt WebEngineWidgets:从底层原理到高级应用与技巧 (Exploring Qt WebEngineWidgets: From Fundamentals to Advanced Applications and Techniques 一、Qt WebEngineWidgets 模块简介及原理 (Introduction and Principles of Qt WebEngineWidgets Module)1. Qt…...
leetcode160. 相交链表
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数返回结果后&…...
核心业务7:放款实现
核心业务7:放款实现 1.放款实现流程 -------------------未完成生成借款人还款计划和投资人回款计划-------------- 2.数据库表 3.前端流程 4.汇付宝流程 5.尚融宝后端流程 -------------------未完成生成借款人还款计划和投资人回款计划-------------- -------------…...
STM32F4系列芯片RTC模块介绍
RTC是“实时时钟”的缩写,它是一种芯片,在计算机等电子产品中广泛应用。RTC提供了实时时钟计时功能和存储时间的能力,即时钟模块,常用于控制和记录时间的应用场合。 RTC的工作原理 RTC主要由时钟电路、电源管理电路、晶振电路、…...
MySQL 在线人数 场景分析
一般在直播或者游戏中经常会统计用户在线人数,主要分为求每个时刻的在线人数和求某个时刻的在线人数两种。 【场景】:某个时刻的在线人数、每个时刻的在线人数 【知识点】:窗口函数、时间函数、sum(tag) over (order by dt,tag desc rows b…...
使用mybatis和dynamic-datasource-spring-boot-starter动态切换数据源操作数据库
记录:415 场景:使用mybatis和dynamic-datasource-spring-boot-starter动态切换数据源操作数据库。 版本:JDK 1.8,Spring Boot 2.6.3,dynamic-datasource-spring-boot-starter-3.3.2,mybatis-3.5.9。 源码:https://github.com/b…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
