<C++>lesson1.C++入门上

news2024/12/23 23:26:21

在这里插入图片描述

文章目录

  • 1. C++关键字(C++98)💚
  • 2. 命名空间🤎
    • 2.1 命名空间定义
    • 2.2命名空间的使用
  • 3. C++输入/输出🖤
  • 4.缺省参数💙
    • 4.1 缺省参数概念
    • 4.2 缺省参数分类
  • 5. 函数重载❤️
    • 5.1 函数重载的概念
    • 5.2 C++支持函数重载的原理
  • 6. 引用💜
    • 6.1 引用概念
    • 6.2 引用特性
    • 6.3 常引用
    • 6.4 引用的使用场景
    • 6.5 指针和引用的区别

C++是在C的基础之上,容纳进去了 面向对象编程思想,并增加了许多有用的 ,以及 编程范式等。熟悉C语言之后,对C++学习有一定的帮助。

本章的主要目标:

  • 补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的,比如:作用
    域方面、IO方面、函数方面、指针方面、宏方面等
  • 为后面的面向对象打基础‘

1. C++关键字(C++98)💚

C++总共有63个关键字,C语言有32个关键字

ps:下面是C++98的关键字,我们不做讲解,以后会细讲
C语言也存在的关键字框起来了
在这里插入图片描述

2. 命名空间🤎

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的
在这里插入图片描述

2.1 命名空间定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}
中即为命名空间的成员

namespace bit
{
	//名称空间中可以定义变量,也可以定义函数、类...
	int rand = 10;
	int Add(int left, int right)
	{
		return left + right;
	}
	struct Node
	{
		int val;
		struct Node* next;
	};
}

//名称空间可以嵌套定义
namespace N1
{
	int a = 1;
	int b = 2;
	int Add(int i, int j)
	{
		return i + j;
	}
	namespace N2
	{
		int c = 3;
		int d = 4;
		int Sub(int i, int j)
		{
			return i - j;
		}
	}
}

/*这是另外一个文件*/
//不同文件的名称空间名字相同会合并名称空间
//namespace.h中的N2空间会和test.c中的N2空间合并
namespace N1
{
	int Mul(int a, int b)
	{
		return a * b;
	}
}

}

2.2命名空间的使用

  1. 可以通过::操作符来指定该使用哪个命名空间的变量
//名称空间的使用
int main()
{
  //可以通过::来使用bit空间中的rand
	printf("%d\n", bit::rand);

	return 0;
}

在这里插入图片描述

  1. 通过using编译指令引入某个命名空间的变量
int main()
{
  //可以通过::来使用bit空间中的rand
	using  bit::rand;
	printf("%d\n", rand);
	return 0;
}

在这里插入图片描述
3. 通过using namespace将整个命名空间引入

int main()
{
	//可以通过using语句来限定使用的名称空间
	using namespace N1;
	printf("a=%d\n", a);
	printf("b=%d\n", b);
	printf("Add(a,b)=%d\n", Add(a, b));
	printf("Mul(a,b)=%d\n", Mul(a, b));
	//必须调用在名称空间N1中才能使用名称空间N2
	using namespace N2;
	printf("c=%d\n", c);
	printf("d=%d\n", d);
	printf("Sub(c,d)=%d\n", Sub(c, d));
	return 0;
}

在这里插入图片描述

3. C++输入/输出🖤

C++兼容C,所以可以引入C标准库stdio.h使用C的标准输入输出函数进行输出输出,但是C++也存在自己独有的输出输出方式,下面来看一下C++是如何实现的

//C++输入输出
//引出C++标准输出输出文件
#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
	int n;
	cin >> n;
	for (int i = 0; i < n; i++)
	cout << "Hello world!!!" << endl;
	return 0;
}

说明:

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含头文件< iostream >以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。
  3. <<是流插入运算符,>>是流提取运算符。
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型。
  5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。后面我们还有有一个章节更深入的学习IO流用法及原理
#include <iostream>
using namespace std;
int main()
{
	int a;
	double b;
	char c;

	// 可以自动识别变量的类型(将从键盘输入的字符经过计算转换为所需要的类型)
	cin >> a;
	cin >> b >> c;

	cout << a << endl;
	cout << b << " " << c << endl;
	return 0;
}

关于cin和cout还有很多特殊的用法,比如控制输入输出格式,这里不详细展开

std命名空间的使用惯例
std是C++标准库的命名空间,如何展开std使用更合理呢?

  1. 在日常练习中,建议直接using namespace std即可,这样就很方便。
  2. 项目开发中使用,像std::cout这样使用时指定命名空间或者using std::cout展开常用的库对象/类型等方式。可以防止自定义变量/函数/对象和库中的重名

4.缺省参数💙

4.1 缺省参数概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参

using namespace std;
//缺省参数
void Fun(int a = 10)
{
	cout << "a=" << a << endl;
}
int main()
{
	Fun(1);//a=1
	Fun(2);//a=2
	Fun();//使用缺省参数a=10
	return 0;
}

4.2 缺省参数分类

  • 全缺省参数
//全缺省参数
void Fun(int a = 10, int b = 20, int c = 30)//设置a,b,c的缺省值
{
	cout << "a=" << a << " ";
	cout << "b=" << b << " ";
	cout << "c=" << c << " ";
	cout << endl;
}
int main()
{
	Fun();//a,b,c使用缺省值
	Fun(1);//b,c使用缺省值,a使用实参
	Fun(1, 2);//c使用缺省值,a,b使用实参
	Fun(1, 2, 3);//a,b,c使用实参
	return 0;
}
  • 半缺省参数
//半缺省参数
void Fun(int a, int b = 20, int c = 30)//设置b,c的缺省值
{
	cout << "a=" << a << " ";
	cout << "b=" << b << " ";
	cout << "c=" << c << " ";
	cout << endl;
}
int main()
{
	Fun(1);//b,c使用缺省值,a使用实参
	Fun(1, 2);//c使用缺省值,a,b使用实参
	Fun(1, 2, 3);//a,b,c使用实参
	return 0;
}

注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现(编译期不知道使用哪个的缺省参数),通常缺省参数在函数声明时给出来
  3. 缺省值必须是常量或者全局变量

5. 函数重载❤️

5.1 函数重载的概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

//函数重载
//参数类型不同
int Add(int left, int right)
{
	cout << "Add(int left, int right)\n";
	return left + right;
}

double Add(double left, int right)
{
	cout << "Add(double left, int right)\n";
	return left + right;
}

//参数个数不同
int Add(int left, int mid, int right)
{
	cout << "Add(int left, int mid, int right)\n";
	return left + mid + right;
}

//参数类型顺序不同

double Add(int left, double right)
{
	cout << "Add(int left, double right)\n";
	return left + right;
}

int main()
{
	Add(1, 2);
	Add(1.1, 2);
	Add(1, 1.1);
	Add(1, 2, 3);
	return 0;
}

注意:

函数支持重载必须是相同的函数名拥有不同的形参列表,和返回值没有任何关系,如果有不同的形参列表,那么编译器调用函数时可以根据实参调用对应匹配的重载函数。

5.2 C++支持函数重载的原理

原因:C++编译器在编译期间会对函数名进行修饰,修饰之后的名字中有关于函数名函数参数列表的信息,而重载的函数参数列表是不同的,所以在之后的链接过程中可以根据调用重载函数的参数列表执行对应的函数。C编译器修饰过的函数名不包含参数列表信息,所以在C程序中构造重载函数,在编译期间就会报错,因为编译器认为重载函数和原函数是一个函数因为它们在C编译器上修饰后的名字是一样的。

下面是gcc编译器对C函数名的修饰
在这里插入图片描述
可以发现gcc编译器对函数名几乎没做任何修饰

下面是g++编译器对C++函数名的修饰
在这里插入图片描述
g++编译器修饰后的函数名中包含了参数列表的信息

总结:C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。


6. 引用💜

6.1 引用概念

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

//引用
int main()
{
	int a = 1;
	int& ra = a;//ra是a的一个别名,共用同一块空间
	cout << &a << endl;
	cout << &ra << endl;
	return 0;
}

在这里插入图片描述

warnings:引用类型必须和实体类型是一致的!!

6.2 引用特性

  1. 引用必须在定义时初始化
  2. 一个变量可以有多个引用(别名)
  3. 每个引用只能绑定一个实体,一旦绑定不可以更改
//引用特性
int main()
{
	//定义时初始化
	int a = 10;
	int b = 20;
	//int& ra;//报错
	int& ra = a;
	ra = b;//不是让ra绑定b,而是将b的数据赋给ra
	//一个变量可以有多个引用
	int& ra2 = a;
	cout << a << " " << ra << " " << ra2 << endl;
	return 0;
}

6.3 常引用

绑定对象具有常属性的引用称为常引用👇

int main()
{
	int a = 10;
	int& ra = a;//ra是非常引用
	const int b = 20;//b是常量,具有常属性
	const int& rb = b;//rb是常引用
	return 0;
}

❗常引用可以绑定常量或变量,但是常量只能被常引用绑定❗

int main()
{
	int a = 10;
	const int& ra = a;//合法:常引用可以绑定变量
	const int b = 20;
	const int& rb = b;//合法:常引用可以绑定常量
	const int c = 30;
	int& rc = c;//不合法:常量只能被常引用绑定,不可以被非常引用绑定
	return 0;
}

我们将常量被常引用绑定,变量被非常引用绑定称为权限平移,变量被常引用绑定称为权限缩小,常量被非常引用绑定称为权限扩大
对于指针引用来说,不可以进行权限扩大,但是可以进行权限平移权限缩小

来看一个有意思的例子

int main()
{
	int a = 10;
	double& ra1 = a;//不合法
	const double& ra2 = a;//合法
	return 0;
}

在这里插入图片描述
与上述结论相关的例子还有如下代码

int main()
{
	char ch;
	int& rch = ch;//不合法:char会自动转换为int类型,需要用常引用来绑定存放转换后结果的临时变量
	const int& rch = ch;//合法
	
	double d;
	int& rd = d;//不合法
	const int& rd = d;//合法
	
	int a;
	double& ra = (double)a;//非法:绑定的是具有常属性的数据对象
	const double& ra = (double)a;
	
	return 0;
}

6.4 引用的使用场景

1. 引用传参
作用:(1).最输出型参数。(2). 减少拷贝. 提高效率

(1)引用传参可以实现需要指针的操作

//引用传参
extern void Swap(int& ra, int& rb);
int main()
{
	int a = 10, b = 20;
	int& ra = a;
	Swap(a, b);
	cout << "a=" << a << endl;
	cout << "b=" << b << endl;
	return 0;
}
//Swap参数为引用类型,可以改变参数对应的值
void Swap(int& ra, int& rb)
{
	int tmp = ra;
	ra = rb;
	rb = tmp;
}

C语言中链表中尾插需要传递二级指针,在C++中可以传递引用

typedef struct SLTNode
{
	int val;
	struct SLTNode* next;
}SLTNode, *PSLTNode;
//参数为二级指针
extern void SLTPushBack(SLTNode** pphead, int val);
//参数为引用
extern void SLTPushBack(SLTNode*& phead, int val);//phead是一个引用,引用的实体时结构体指针类型
//等价于
extern void SLTPushBack(PSLTNode& phead, int val);

(2)验证引用传参可以提高效率
函数参数传值时由于会对实参进行拷贝,而引用只给实参去了一个别名不进行拷贝,所以当传递的是大对象时,引用传参会比传值传参效率更高。

#include <time.h>
struct A { int a[100000]; };//大对象
void TestFunc1(A a) {}
void TestFunc2(A& a) {}
void TestRefAndValue()
{
	A a;
	// 以值作为函数参数
	size_t begin1 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc1(a);
	size_t end1 = clock();
	// 以引用作为函数参数
	size_t begin2 = clock();
	for (size_t i = 0; i < 10000; ++i)
		TestFunc2(a);
	size_t end2 = clock();
	// 分别计算两个函数运行结束后的时间
	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
}
int main()
{
	TestRefAndValue();
	return 0;
}

在这里插入图片描述

  1. 引用做函数返回值
    作用:(1).做输出型返回对象,调用者可以修改返回对象。(2).减少拷贝,提高效率

在介绍引用做函数返回值之前,我们回顾一下关于函数栈帧的相关知识。
函数的返回值是通过寄存器或者临时变量带出来的,也就是说如果函数有返回值,那么在函数结束前会先将返回值的结果存放在寄存器或者内存中(取决于返回值的字节数),退出函数后再将预先存放的值赋给需要的变量。
更详细的可以看这篇文章syseptember的个人博客:图解函数栈帧的创建于销毁
其次我们需要知道的是函数返回值为引用类型的含义是返回返回对象的别名

错误返回引用👇

//引用做返回值
int& Count()
{
	int n = 0;
	n++;
	return n;
}
int main()
{
	int& ret = Count();
	cout << ret << endl;
	cout << ret << endl;
	cout << ret << endl;
	return 0;
}

在这里插入图片描述

上述代码等价于

int* Count()
{
	int n = 0;
	n++;
	return &n;
}
int main()
{
	int* ret = Count();
	cout << *ret << endl;
	cout << *ret << endl;
	cout << *ret << endl;
	return 0;
}

相比上面的返回引用的代码,我们更熟悉返回指针的代码,这段代码的结果和上述是一模一样的,在这段代码中,返回的是局部变量的地址,而局部变量出了作用域会销毁,因此打印的行为仍然是未定义的,这两段代码结果一样的根本原因是引用在底层上是通过指针实现的

int& Count()
{
	int n = 0;
	n++;
	return n;
}
int main()
{
	int ret = Count();
	cout << ret << endl;
	cout << ret << endl;
	cout << ret << endl;
	return 0;
}

在这里插入图片描述
上述代码等价于

int* Count()
{
	int n = 0;
	n++;
	return &n;
}
int main()
{
	int ret = *Count();
	cout << ret << endl;
	cout << ret << endl;
	cout << ret << endl;
	return 0;
}

该代码仍然存在返回的是局部变量地址的问题,所以结果是未定义的,这再次说明了引用的底层实现是通过指针来实现的

正确返回引用👇

//正确返回引用
int& Count()
{
	//创建非局部变量
	static int n = 0;
	n++;
	//返回非局部变量的地址
	return n;
}
int main()
{
	int& ret = Count();
	cout << ret << endl;
	cout << ret << endl;
	cout << ret << endl;
	return 0;
}

在这里插入图片描述
上述代码等价于

int* Count()
{
	static int n = 0;
	n++;
	return &n;
}
int main()
{
	int* ret = Count();
	cout << *ret << endl;
	cout << *ret << endl;
	cout << *ret << endl;
	return 0;
}

这次函数返回的不再是局部变量的地址,而是存储在静态区中的地址,所以结果是有效的

总结:如果函数返回时,出了函数作用域,如果返回对象没有被回收,则可以使用引用返回,如果已经还给系统了,则必须使用传值返回。

(1)输出型返回对象

#include <assert.h>
#include <stdlib.h>
typedef struct SeqList
{
	int *a;
	int sz;
	int capacity;
}SeqList;
void InitSeqList(SeqList& list)
{
	list.capacity = 4;
	list.sz = 4;
	list.a = (int*)malloc(sizeof(int) * list.capacity);
}

int& SeqListAt(SeqList& list, int pos)
{
	assert(pos >= 0 && pos <= list.capacity);
	return list.a[pos];
}
int main()
{
	SeqList list;
	InitSeqList(list);
	for (int i = 0; i < list.capacity; i++)
	{
		//引用做输出型返回值
		SeqListAt(list, i) = i + 1;
	}
	for (int i = 0; i < list.sz; i++)
	{
		cout << SeqListAt(list, i) << " ";
	}
	cout << endl;

}

验证引用返回比值返回效率更高

#include <time.h>
struct A { int a[10000]; };
A a;
// 值返回
A TestFunc1() { return a; }
// 引用返回
A& TestFunc2() { return a; }
void TestReturnByRefOrValue()
{
	// 以值作为函数的返回值类型
	size_t begin1 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc1();
	size_t end1 = clock();
	// 以引用作为函数的返回值类型
	size_t begin2 = clock();
	for (size_t i = 0; i < 100000; ++i)
		TestFunc2();
	size_t end2 = clock();
	// 计算两个函数运算完成之后的时间
	cout << "TestFunc1 time:" << end1 - begin1 << endl;
	cout << "TestFunc2 time:" << end2 - begin2 << endl;
}
int main()
{
	TestReturnByRefOrValue();
	return 0;
}

在这里插入图片描述

6.5 指针和引用的区别

语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
底层实现上实际是有空间的,因为引用是按照指针方式来实现的

int main()
{
int a = 10;
int& ra = a;
ra = 20;
int* pa = &a;
*pa = 20;
return 0;
}

反汇编代码
在这里插入图片描述

引用和指针的不同点❗

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
    一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
    位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

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

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

相关文章

Day4_Springboot集成Mybatis

上一节使用springboot框架搭建了项目&#xff0c;并创建了数据库user表&#xff0c;接下来集成mybatis对用户表实现增删改查操作~~~~ 目录 SpringBootApplication.java 创建model/entity文件夹&#xff0c;存放实体类 UserDao.java UserController.java 浏览器Json插件&am…

Leetcode刷题日志3.0

目录 前言&#xff1a; 1.相对名次​​​​​​ 2.学生出勤记录 I 3.重塑矩阵 4.分糖果 5.最长和谐子序列 6.种花问题 前言&#xff1a; 今天我就分享一下最近在leetcode刷到的题&#xff0c;希望对大家有所帮助。编程语言&#xff1a;Python3。好了废话不多讲了&…

消息队列使用场景介绍

消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用耦合&#xff0c;异步消息&#xff0c;流量削锋等问题 实现高性能&#xff0c;高可用&#xff0c;可伸缩和最终一致性架构 使用较多的消息队列有ActiveMQ&#xff0c;RabbitMQ&#xff0c;ZeroMQ&#xff0c;Ka…

【华中农业大学2023年十二届程序设计竞赛(同步赛)】B. 写信

文章目录 题目描述思路代码 题目描述 思路 错位排序&#xff0c;可搜索引擎。复杂度太高 递推式&#xff1a; f [ n ] ( n − 1 ) ∗ ( f [ n − 1 ] f [ n − 2 ] ) f[n](n-1)*(f[n-1]f[n-2]) f[n](n−1)∗(f[n−1]f[n−2]) 正解&#xff1a;打表&#xff01;YYDS 1e9的数…

12.Hadoop练习题

1.网络问题 &#xff08;1&#xff09;机器联网出现问题 情况&#xff1a;ping一下百度&#xff0c;发现百度ping不通 sudo vim /etc/sysconfig/network-scripts/ifcfg-ens33检查GATEWAY是否正确&#xff0c;修改过来之后保存退出&#xff0c;重启虚拟机 sudo systemctl re…

图论 (Java) 从入门到入土 /第一部分 图的基础-图的定义/

零.前言 图&#xff0c;是一种比较复杂的数据结构。和树的一个节点只和上层一个节点相连不同&#xff0c;在图中&#xff0c;任意两个节点都可能相连&#xff0c;且可能具有方向性&#xff0c;并且节点的边具有权重&#xff0c;因此&#xff0c;图被用于描述各种复杂的数据对象…

python:tkinter 生成 buttonBar 示例

tk_test1.py # -*- coding: utf-8 -*- import os import tkinter as tk from tkinter import filedialogroot tk.Tk() root.title("生成 buttonBar 示例 ") var tk.StringVar() # 动态字符串 label tk.Label(root, textvariablevar) listbox tk.Listbox(root, s…

题集-快慢指针的应用(链表)

1.中心结点 代码&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* middleNode(struct ListNode* head) {if(head->nextNULL) return head;struct ListNode* fast head,*slow …

初阶数据结构——顺序表和链表(单链表)

目录 1.线性表2.顺序表SeqList.hSeqList.cTest.c数组习题移除元素删除有序数组中的重复项合并两个有序数组 顺序表的问题及思考 3.链表SList.hSList.cTest.c 1.线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中…

BI技巧丨计算组折线图

PowerBI中&#xff0c;通常我们会使用折线图来展示数据的趋势情况。但是当数据类别过多的时候&#xff0c;需求也在进一步深入&#xff0c;往往还需要我们将用户关注的重要节点标注出来&#xff0c;例如&#xff1a;最大值和最小值。 很早之前&#xff0c;白茶曾经写过一篇关于…

HTML学习笔记一

目录 HTML学习笔记 一、HTML标签 1、HTML语法规范 1.1标签的语法概述 1.2标签关系 2、HTML基本结构标签 2.1第一个HTML 2.2基本结构标签总结 3、开发工具 4、HTML常用标签 4.1标签的语义 4.2标题标签 4.3段落和换行标签 4.4文本格式化标签 4.5div和span标签 4.…

Linux云服务器的使用,以及运行Python程序、相关Linux指令

目录 1、使用Linux云服务器的软件 2、Linux系统运行Python程序 3、Linux系统查看包、虚拟环境、安装包等 以下几个深度学习服务器都不错&#xff1a;智星云、AutoDL、恒源云 1、使用Linux云服务器的软件 MobaXterm_Personal 推荐MobaXterm_Personal mobaxterm是一款方便网站…

基于Flask的留言板的设计与实现

这是《Flask Web开发实战:入门、进阶与原理解析》这本书中的一个小项目&#xff0c;我在学习后根据书中的教程实现了留言板的功能&#xff0c;并结合我的思路将代码做了一些调整。 下面这是实现后的展示图片 文章目录 设计思路项目代码exts.pymodels.pyforms.pyerrors.pycomma…

DMDTS:DM迁移到SQL脚本

DMDTS:DM迁移到SQL脚本 环境介绍1 注册工程2 新建迁移3 迁移工具介绍4 选择迁移方式5 配置数据源6 配置SQL脚本文件7 配置源端获取对象方式和迁移策略8 选择指定对象复制9 选择迁移对象9.1 迁移对象的配置 - - 转换 设置表的映射关系 10 审阅迁移任务11 完成迁移 环境介绍 DM管…

一文了解使用Moonbeam原生跨链的潜力项目

跨链互连合约是Moonbeam独特的原生跨链解决方案&#xff0c;不仅帮助开发团队在Moonbeam网络即可解锁不同公链的特色功能&#xff0c;而且各类去中心化应用的终端使用者能因此获得更便捷安全的跨链体验。 Moonbeam的原生跨链解决方案包含Polkadot生态、不同异构链和Moonbeam生…

hitcontraining_uaf

1&#xff0c;三连 基本信息&#xff1a;x86-32-el,堆题思路&#xff1b; 保护&#xff1a;Partial RELRO。 堆题多看一个Libc&#xff1a; 2,IDA分析 main功能&#xff1a; add_note()功能&#xff1a; malloc了两次&#xff1a; 8字节填充&#xff08;利用点之一&#xf…

Markdown快速入门教程

Markdown 的目标是实现「易读易写」&#xff0c;并强调它的「可读性」&#xff0c;因此Markdown 的语法全由标点符号所组成&#xff0c;并经过严谨慎选&#xff0c;是为了让它们看起来就像所要表达的意思&#xff1b;以下是Markdown 大部分的语法。 常用语法- 文字样式 文字字…

Allegro过孔盖油和过孔开窗设置(部分过孔开窗)

Allegro设置一部分过孔盖油&#xff0c;另一部分过孔开窗。 过孔开窗&#xff1a;过孔部分去除阻焊&#xff0c;便于调试和散热&#xff1b; 过孔盖油&#xff1a;过孔盖上阻焊油墨&#xff0c;防止过孔连锡短路。 总结 使用pad designer设计两种via pad&#xff0c;一种不开…

分布式事务的几种解决方案

一.基础概念 1. 什么是事务 事务可以看做是一次大的活动&#xff0c;它由不同的小活动组成&#xff0c;这些活动 要么全部成功&#xff0c; 要么全部失败 2.本地事务 在计算机系统中&#xff0c;更多的是通过 关系型数据库来控制事务&#xff0c;这是利用数据库 本身的事务特性…

基于Qt的教务管理系统的设计与实现

获取代码&#xff1a; (1) 下载链接: https://download.csdn.net/download/kese7952/87741551 (2) 添加博主微信获取,备注来源: mryang511688 项目描述 技术&#xff1a;C、QT等 摘要&#xff1a; 随着学校规模的不断扩大&#xff0c;学生的流动变迁导致了学校在管理学生信息…