当前位置: 首页 > news >正文

Cpp快速入门语法(下)(2)

文章目录

  • 前言
  • 一、函数重载
    • 概念与使用
    • C++为何支持函数重载?
  • 二、引用
    • 概念
    • 语法
    • 特性
    • 权限(常引用)
    • 使用场景
    • 与指针的区别
  • 三、内联函数
  • 四、auto关键字(C++11)
  • 五、基于范围的for循环(C++11)
  • 六、指针空值nullptr(C++11)
  • 总结


前言

承前启后,正文开始!


一、函数重载

概念与使用

  函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,常用来处理实现功能类似数据类型不同的问题,而C语言不允许同名函数
  但是需要满足的条件是:函数的形参列表不同,即参数个数,类型,类型顺序不同

  在C语言中,我们如果要实现两数之和 Add 函数,如果需要int、double两种各一个,我们可能会命名为Addi、Addd,这很麻烦,而函数重载就可以解决这个问题,下面让我们来看具体实现代码:

#include<iostream>
using namespace std;// 1、参数类型不同
int Add(int x, int y)
{return x + y;
}
double Add(double x, double y)
{return x + y;
}// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(a)" << endl;
}// 3、参数类型顺序不同(本质还是参数类型不同)
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}int main()
{// 都可以对应到正确的函数Add(10, 20); Add(10.1, 20.2); f();f(10);f(10, 'a');f('a', 10);return 0;
}

另外你需要注意,只有返回类型不同不构成重载,原因会产生歧义,具体看以下代码

#include <iostream>
using namespace std;void f()
{cout << "void f()" << endl;
}
int f()
{cout << "int f()" << endl;return 0;
}int main()
{f(); // 调用哪一个不确定return 0;
}

C++为何支持函数重载?

  这里我们就需要回想前面学习C的时候有关预处理和编译的内容了
  在C/C++,程序运行之前,需要进行以下几个阶段: 预处理、编译、汇编、链接

关于链接,你可以尝试回想以下:

我们知道,在编译阶段会将程序中的每个源文件的全局范围的变量符号分别进行汇总。在汇编阶段会给每个源文件汇总出来的符号分配一个地址(若符号只是一个声明,则给其分配一个无意义的地址),然后分别生成一个符号表。最后在链接期间会将每个源文件的符号表进行合并,若不同源文件的符号表中出现了相同的符号,则取合法的地址为合并后的地址(重定位)

举个例子,我们观看下面两个同根.c文件内容:

	// sum.cint sum(int num1, int num2){return num1 + num2;}// main.cextern int sum(int num1, int num2);int main(){sum(1,2);return 0;}

  注意,在链接前两个.c文件都是单线不交互的,这时候,sum.c里面的sum函数有定义,而main.c里面的sum函数没有定义,等到两个.c文件经过汇编后,main.o形成如下符号表:

main 0x100
sum 0x000 (无意义的地址)

sum.o形成以下符号表

sum 0x800 (有意义的地址)

  接着,两个文件合成一个文件,错误的sum地址被改为正确的地址,而你想,假如有两个sum函数被定义,即有地址,那么它们单独来看都是有意义的地址,可是这时候要重定位哪个?哪怕只有一个文件,两个重名函数,那么你call的是哪个函数,这很明显有歧义

来验证一下吧,首先我们在Linux环境下采用gcc编译器
在这里插入图片描述
在这里插入图片描述
可以看到,Add就是Add,func就是func,没有半点修饰

接着我们再在Linux环境下采用g++编译器来编译
在这里插入图片描述

多试几个函数,其实你会发现修饰函数名字在此环境下的规律为 { _Z + 函数名长度 + 函数名 + 类型首字母 }

  也就是说,C++在进行符号汇总时,对函数的名字修饰做了改动,函数汇总出的符号不再单单是函数的函数名,而是通过其参数的类型和个数以及顺序等信息汇总出一个名字,这样一来,就算是函数名相同的函数,只要其参数的类型或参数的个数或参数的顺序不同,那么汇总出来的符号也就不同了,其实也从侧面说明了函数重载跟返回类型没关系

这可能很抽象,毕竟有关编译甚至在大学还有专门的一门专业课《编译原理》,大家如有困惑可以自行查阅其他相关资料

二、引用

概念

  引用不是定义一个变量,而是已存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间

“李逵”、“铁牛”、“黑旋风”本质上都是一个人

语法

  类型说明符& 引用对象名 =引用实体(引用类型必须和引用实体是同种类型)

来个具体例子:

void TestPef()
{int a = 10;int& pa = a; // pa是a的别名// 从地址上,可以得出它和它引用的变量共用同一块内存空间printf("&a == %p\n", &a);printf("&pa == %p\n", &pa);
}

输出结果如下:
在这里插入图片描述

特性

  1. 引用在定义时必须初始化
int a = 10;
int& b = a; // right
  1. 一个变量可以有多个引用
int a = 10;
int& b = a; // right
int& c = a; // right
int& d = a; // right
  1. 引用一旦引用了一个实体,就不能再引用其他实体
	int a = 10;int& b = a;int c = 20;b = c; //你的想法:让b转而引用c,其实是c赋值给b

权限(常引用)

  我们知道,权限可以缩小或者平移,但是绝对不能放大

void TestConstRef()
{int a=0;int& b=a;const int& c=a; //支持->权限缩小const int x=10;int& y=x;//不支持-权限放大(此时的x只有读权限,没有写权限)const int& y=x;//支持权限相等//表达式的返回值是临时对象,而临时对象具有常性!!int& n = a+x = 临时对象 //这里是属于权限放大const int& n = a+x = 临时对象; //支持权限相等

使用场景

  1. 用作形参,因为是同一块内存空间,所以在一定程度上可以替代指针
//交换函数
void Swap(int& a, int& b)
{int tmp = a;a = b;b = tmp;
}
  1. 不用创建临时变量,提高效率
#include <ctime>
#include <iostream>
using namespace std;struct A { int a[10000]; };void TestFunc1(struct A& a) {}
void TestFunc2(struct A a) {}int main()
{A a;size_t begin1 = clock();for (int i = 0; i < 10000; i++)TestFunc1(a);size_t end1 = clock();size_t begin2 = clock();for (int i = 0; i < 10000; i++)TestFunc2(a);size_t end2 = clock();// 在某次错误时cout << "TestFunc1(struct A& a):" << end1 - begin1 << endl; // 0cout << "TestFunc1(struct A a):" << end2 - begin2 << endl; // 5return 0;
}

与指针的区别

  其实,引用不可像指针那样更改,注定了无法完全替代指针,像链表我们就必须用到指针

  在语法概念上,引用是一个别名,没有独立空间,同其引用实体共用同一块空间,但是在底层实现上,实际引用是有开辟空间的,由于引用是按照指针方式实现
在这里插入图片描述

总而言之,你需要记住以下几点:

1、引用在定义时必须初始化,指针没有要求。
2、引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体。
3、没有NULL引用,但有NULL指针。
4、在sizeof中的含义不同:引用的结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)。
5、引用进行自增操作就相当于实体增加1,而指针进行自增操作是指针向后偏移一个类型的大小。
6、有多级指针,但是没有多级引用。
7、访问实体的方式不同,指针需要显示解引用,而引用是编译器自己处理。
8、引用比指针使用起来相对更安全。

三、内联函数

  在C语言中,假设有一些小而频繁使用的函数如交换函数Swap,大量使用会建立栈帧,消耗时间,宏是C语言给出的解决方式,可这样太麻烦且易错

比如来个Add函数,宏的正确写法是 #define Add(x, y) ((x) + (y))

  基于此,对于C++来说,以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销,内联函数的使用可以提升程序的运行效率

事实上,C++相当不鼓励使用宏,理由有代码可读性差(导致调试不方便)、与函数相比没有类型检查(宏做的仅仅是替换),在有些场景下比较复杂(需要谨慎替换后运算符的优先级)等

而C++给出的方案是:
i, 用const和enum替代宏常量;
ii,用inline(内联函数)替代宏函数

还是来个具体例子吧,我们现在来观察调用普通函数和内联函数的汇编代码来进一步查看其优势:

int Add(int a, int b)
{return a + b;
}
int main()
{int ret = Add(1, 2);return 0;
}

在这里插入图片描述
  如果内联函数语句较多且多次不同地方调用,可能会使编译后的文件(可执行程序)变大,其实,这本质上就是一种以空间换时间的做法,但优点是减少了调用开销,提高了程序运行效率

  内联函数是对编译器的一个建议,对于我们实现的内联函数,编译器不一定执行,不同编译器关于inline函数得实现机制可能不同;一般情况下,建议将函数规模较小,不是递归且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性;

  inline函数不要让声明和定义分离,分离会导致链接错误;因为inline被展开,就不再调用函数,没有函数地址了,链接就会找不到

四、auto关键字(C++11)

  随着学习的深入,我们会发现1. 类型难于拼写 2. 含义不明确导致容易出错
  auto在C11就因此被赋予了新的含义:作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得

  1. 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时必须加&
#include <iostream>
using namespace std;int main()
{int a = 10;auto b = &a;   // 自动推导出b的类型为int*auto* c = &a;  // 自动推导出c的类型为int*auto& d = a;   // 自动推导出d的类型为int// 打印变量b,c,d的类型cout << typeid(b).name() << endl;// 打印结果为int*cout << typeid(c).name() << endl;// 打印结果为int*cout << typeid(d).name() << endl;// 打印结果为intreturn 0;
}
  1. 在同一行定义多个变量必须是同一类型
int main()
{auto a = 1, b = 2; // rightauto c = 3, d = 4.0; // err: “auto”必须始终推导为同一类型return 0;
}
  1. auto不能作为函数的参数
void TestAuto(auto x) {} // err
  1. auto不能直接用来声明数组
int main()
{int a[] = { 1, 2, 3 };auto b[] = { 4, 5, 6 };// errreturn 0;
}

五、基于范围的for循环(C++11)

  C++11中引入了基于范围的for循环。for循环后的括号由冒号分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

其实是抄的Python的作业

	int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//将数组元素值全部乘以2for (auto& e : arr) // 运用了引用{e *= 2;}//打印数组中的所有元素for (auto e : arr){cout << e << " ";}cout << endl;

范围for的使用是有条件的:

一、for循环迭代的范围必须是确定的
 对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。
二、迭代的对象要实现++和==操作
 这是关于迭代器的问题,大家先了解一下。

六、指针空值nullptr(C++11)

  前人挖坑,NULL其实是一个宏,在传统的C头文件(stddef.h)中可以看到如下代码:

/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL    0 // NULL 直接被替换为0
#else  /* __cplusplus */
#define NULL    ((void *)0)
#endif  /* __cplusplus */
#endif  /* NULL */

  我们之前都拿NULL当指针空值,而上述错误就可能导致以下BUG:

#include <iostream>
using namespace std;void f(int)
{cout << "f(int)" << endl;
}
void f(int*)
{cout << "f(int*)" << endl;
}
int main()
{f(0);f(NULL); // 我们想的是匹配第二个,结果是第一个,这就是错误的宏替换带来的后果f((int*)NULL);return 0;
}

所以,对于C++98中的问题,C++11引入了关键字nullptr

请注意:

  1. 在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为关键字引入的
  2. 在C++11中,sizeof(nullptr)与sizeof((void*)0)所占的字节数相同
  3. 为了提高代码的健壮性,在后序表示指针空值时建议最好使用nullptr

总结

  本节干货好多,函数重载原理的那一部分可能有些困难,加油!

相关文章:

Cpp快速入门语法(下)(2)

文章目录 前言一、函数重载概念与使用C为何支持函数重载&#xff1f; 二、引用概念语法特性权限(常引用)使用场景与指针的区别 三、内联函数四、auto关键字(C11)五、基于范围的for循环(C11)六、指针空值nullptr(C11)总结 前言 承前启后&#xff0c;正文开始&#xff01; 一、函…...

【GO开发】MacOS上搭建GO的基础环境-Hello World

文章目录 一、引言二、安装Go语言三、配置环境变量&#xff08;可跳过&#xff09;四、Hello World五、总结 一、引言 Go语言&#xff08;Golang&#xff09;因其简洁、高效、并发性强等特点&#xff0c;受到了越来越多开发者的喜爱。本文将带你一步步在Mac操作系统上搭建Go语…...

探索轻量级语言模型 GPT-4O-mini 的无限可能

随着人工智能技术的日益发展&#xff0c;语言模型正逐渐成为人们日常生活和工作中不可或缺的一部分。其中&#xff0c;GPT-4O-mini 作为一个轻量级大模型&#xff0c;以其强大的功能和易用性吸引了众多关注。本文将带您了解 GPT-4O-mini 的出色表现、应用场景以及如何免费使用这…...

CSS 笔记 1

1. CSS 优先级&#xff0c; 内部大于外部。 2. 几个属性&#xff1a; flex-grow: 1; 让 当前元素 在剩余空间中&#xff0c; 占据尽可能多的高度&#xff0c;确保它能在中间居中。 max-height: 300px; 限制最大高度 300 像素&#xff0c; flex-grow: 1; 导致占的太满了&#x…...

2024/9/16 dataloader、tensorboard、transform

一、pytorch两大法宝元素 假设有一个名为pytorch的包 dir()&#xff1a;用于打开包&#xff0c;看里面的内容 help():用于查看具体的内容的用处 二、python文件&#xff0c;python控制台和jupyter的使用对比 三、pytorch读取数据 pytorch读取数据主要涉及到两个类&#xff1…...

C/C++语言基础--从C到C++的不同(下),15个部分说明C与C++的不同

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 1-10在上篇C/C语言基础–从C到C的不同(上&#xff09;&#xff1b;当然C和C的不同还有很多&#xff0c;本人暂时只总结这些&#xff0c;其他的慢慢更新&#xff1b;上一篇C/C语言基础–从C到C的不同(上&…...

物理感知扩散的 3D 分子生成模型 - PIDiff 评测

PIDiff 是一个针对蛋白质口袋特异性的、物理感知扩散的 3D 分子生成模型&#xff0c;通过考虑蛋白质-配体结合的物理化学原理来生成分子&#xff0c;在原理上&#xff0c;生成的分子可以实现蛋白-小分子的自由能最小。 一、背景介绍 PIDiff 来源于延世大学计算机科学系的 Sang…...

蓝桥杯-基于STM32G432RBT6的LCD进阶(LCD界面切换以及高亮显示界面)

目录 一、页面切换内容详解 1.逻辑解释 2.代码详解 code.c&#xff08;内含详细讲解&#xff09; code.h main.c 3.效果图片展示 ​编辑 二、页面选项高亮内容详解 1.逻辑解释 2.读入数据 FIRST.第一种高亮类型 code.c&#xff08;内含代码详解&#xff09; code.…...

2022高教社杯全国大学生数学建模竞赛C题 问题一(1) Python代码

目录 问题 11.1 对这些玻璃文物的表面风化与其玻璃类型、纹饰和颜色的关系进行分析数据探索 -- 单个分类变量的绘图树形图条形图扇形图雷达图 Cramer’s V 相关分析统计检验列联表分析卡方检验Fisher检验 绘图堆积条形图分组条形图 分类模型Logistic回归随机森林 import matplo…...

【3D打印】3D打印机运动控制“Gcode”

一、Gcode是什么&#xff1f; Gcode是一种用于控制数控机床&#xff08;包括3D打印机&#xff09;的语言。它由一系列指令组成&#xff0c;每个指令控制机器的一个特定动作。 二、基础术语 G指令&#xff1a;用于控制机器的运动。M指令&#xff1a;用于控制机器的其他功能&a…...

针对Chsrc换源工具的简单脚本

此脚本目前只是针对 X86和aarch64系统&#xff0c;可根据自身需求进行修改&#xff0c;点赞自取 关于工具的详细介绍请看上一篇文章&#xff1a;全平台通用的换源工具Chsrc #!/bin/bashtag1"https://gitee.com/RubyMetric/chsrc/releases/download/pre/chsrc-x64-linux&…...

vscode中如何配置c/c++环境

“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 前言文章有误敬请斧正 不胜感恩&#xff01;一、准备工作二、安装 VSCode 插件三、配置 VSCode1. 配置编译任务&#xff08;tasks.json&#xff09;2. 配置调试器&#xff08;launch.json&#xff09; 四、运行和调…...

【梯度消失|梯度爆炸】Vanishing Gradient|Exploding Gradient——为什么我的卷积神经网络会不好呢?

【梯度消失|梯度爆炸】Vanishing Gradient|Exploding Gradient——为什么我的卷积神经网络会不好呢&#xff1f; 【梯度消失|梯度爆炸】Vanishing Gradient|Exploding Gradient——为什么我的卷积神经网络会不好呢&#xff1f; 文章目录 【梯度消失|梯度爆炸】Vanishing Gradi…...

MAC 地址简化概念(有线 MAC 地址、无线 MAC 地址、MAC 地址的随机化)

一、MAC 地址 MAC 地址&#xff08;Media Access Control Address&#xff09;&#xff0c;即媒体访问控制地址&#xff0c;也称为物理地址、硬件地址或链路层地址 MAC 地址有时也被称为物理地址&#xff0c;但这并不意味着 MAC 地址属于网络体系结构中的物理层&#xff0c;它…...

SQL_yog安装和使用演示--mysql三层结构

目录 1.什么是SQL_yog 2.下载安装 3.页面介绍 3.1链接主机 3.2创建数据库 3.3建表操作 3.4向表里面填内容 3.5使用指令查看效果 4.连接mysql的指令 4.1前提条件 4.2链接指令 ​编辑 4.3创建时的说明 4.4查看是不是连接成功 5.mysql的三层结构 1.什么是SQL_yog 我…...

蓝桥杯-STM32G431RBT6(解决LCD与LED引脚冲突的问题)

一、LCD与LED为什么会引脚冲突 LCD与LED引脚共用。 网上文章是在LCD_WriteRAM、LCD_WriteRAM_Prepare、LCD_WriteReg中添加&#xff0c;但问题并没有解决。 二、使用步骤 在如下函数中加入uint16_t tempGPIOC->ODR; GPIOC->ODRtemp; LCD_Init(); void LCD_C…...

ESP-01S,ESP8266设置客户端透传模式

ESP-01S,ESP8266设置透传(透明传输)模式 例子 ATCWMODE_DEF1 //station模式 ATRST //重启 ATCWLAP //查看周围热点 ATCWJAP_DEF"ssid","password" //连接热点 ATCIFSR //查看ip ATCIPSTA_DEF"192.168.82.66","192.168.6.1&…...

NFT Insider #147:Sandbox 人物化身九月奖励上线;Catizen 付费用户突破百万

市场数据 加密艺术及收藏品新闻 Doodles 动画特别剧《Dullsville and The Doodleverse》在多伦多国际电影节首映 Doodles 最近在多伦多国际电影节&#xff08;TIFF&#xff09;首映了其动画特别剧《Dullsville and The Doodleverse》&#xff0c;这是该品牌的一个重要里程碑。…...

103.WEB渗透测试-信息收集-FOFA语法(3)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;102.WEB渗透测试-信息收集-FOFA语法&#xff08;2&#xff09; FOFA使用实例 组件框架 …...

SpringDataJPA基础增删改查

添加&#xff1a;save(对象) 删除&#xff1a;delete&#xff08;主键或者带有主键的对象&#xff09; 修改&#xff1a;save&#xff08;对象&#xff09; 对象中没有id&#xff0c;执行添加操作 对象中有id id不存在&#xff1a;执行添加 id存在&#xff1a; 其余数据…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...