MFC - 一文带你从小白到项目应用(全套1)
文章篇幅可能会比较长,从入门到基本能上项目的全部内容。建议观看的过程中,用电脑跟着学习案例。
持续输出优质文章是作者的追求,因为热爱,所以热爱。
最近看动漫被一句鸡汤感动到了,也送给各位朋友:
只要有一息尚存,战斗便永不停止...
windows消息机制
如果想要更好的学习掌握MFC,必须要先了解WIndows程序的内部运行机制。
windows编程基础 -- win32程序
在windows平台下,提供了很多函数可以调用,这些函数是由windows操作系统本身提供的。windows应用程序API函数是通过C语言实现的,所有主要的windows函数都在windows.h头文件中进行了声明。Windows操作系统提供了1000多种API函数。
窗口和句柄
窗口是windows应用程序中一个非常重要的元素,一个windows应用程序至少要有一个窗口,称为主窗口。窗口是屏幕上的一块矩形区域,是windows应用程序与用户进行交互的接口。利用窗口可以接收用户的输入以及显示输出。
窗口又分为客户区(中间空白的部分)和非客户区(蓝色那部分)。
客户区是窗口的一部分,应用程序通常在客户区中显示文字或者绘制图形。 应用程序则主要管理客户区的外观及操作
非客户区也是窗口的一部分,通常将标题栏、菜单栏、系统菜单、最小化框和最大化框、可调边框统称为窗口的非客户区,它们由windows系统来管理,
总结来说:我们写代码主要控制客户区部分、非客户区部分通常由操作系统控制。
窗口是windows中一个很重要的概念,是一个几部组件部分。窗口有父窗口和子窗口,除了上图所示类型的窗口外,对话框和消息框也是一种窗口。在对话框上通常还包含很多子窗口,这些窗口的形式也按钮、单选按钮、复选按钮、组框、文本编辑等。
操作窗口是通过一个指针来控制的(可以将窗口近似的理解为一个结构体的一个变量),有一个指针指向这个对象,通过这个指针就可以对这个结构体变量中的成员进行操作,比如大小、背景颜色、按钮的响应等。所以想要操作某一个窗口,就必须先拿到这个窗口的指针,在windows中习惯称为句柄(HWDN)。
句柄(HANDLE)是一个非常重要的概念,在windows程序中,定义了很多结构体,操作这些结构体变量(也是各种各样的资源)通常情况需要使用句柄。系统在创建这些资源时会为它们分配内存,并返回标识这些资源的标识号。比如:图标句柄、光标句柄、画刷句柄等。
消息与消息队列
通常情况下,我们写的程序是一行一行执行的,也就是DOS方式的程序设计方式。而windows程序并不是这样的,它是一种事件驱动模式,这中框架模式思想很值得我们了解。
每一个windows应用程序开始执行后,系统都会为该程序创建一个消息队列,这个消息队列用来存放程序创建的窗口的消息。(这些消息比如:鼠标左键按下)
一个应用程序可以有多个窗口,这些窗口会有一个窗口标记,也就是上面说的窗口句柄,通过这个窗口句柄,操作系统就知道在哪个窗口上进行相应的处理。
整个框架的流程:
1.用户在客户区按下了鼠标左键,此时操作系统会感知到用户按下了鼠标左键这个事件。
2.操作系统将这个事件包装成一个消息,并将这个消息放到消息队列中,等待应用程序从队列中取出消息并进行处理。
3.应用程序从消息队列中取出消息,然后进行响应
4.这个响应过程,通常应用程序交给操作系统进行处理,操作系统会调用消息处理函数(回调函数),这个函数被称为窗口过程。
步骤4:整个响应过程就是一个回调
Windows编程模型
一个完整的win32程序实现的功能就是创建一个窗口,然后在这个窗口中响应键盘、鼠标消息。这个窗口可以有一些子窗口...本质上就是这样的,并不复杂。
大致步骤:
1.windows函数定义
2.创建一个窗口
3.进行消息循环
4.编写窗口过程函数
创建一个win32的空项目
编写一个简单的WIN32程序
1.主函数定义(WinMain)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR IpCmdLine, int nShowCmd) {return 0; }
WINAPI:是一个宏,表示参数从右往左入栈,同时在函数返回前自动清空堆栈
hInstance:(当前应用程序的句柄)一个应用程序的的实例句柄,一个应用程序可以运行多个实例,每一个运行的应用程序都会有一个句柄,通过hInstance传递给WinMain函数
hPrevInstance:当前实例的前一个实例句柄,通常传NULL
IpCmdLine:一个字符串数组,传给给应用程序的命令行参数,相当于 char* argv[]
nShowCmd:窗口显示的方式,最大化/最小化/正常显示/隐藏显示
2.创建一个窗口
创建一个WIN32窗口,通常有4个步骤: 设计一个窗口类,注册窗口类,创建窗口,显示和更新窗口(Windows.h中有现成的API可以调用)
步骤1:设计一个窗口类
这一步可以用来指定在我们这个窗口中的光标的样子、背景色、图标等这些属性。
也就是说,在创建一个窗口前,必须对给类型的窗口进行设计,指定窗口的特征。在windows中,窗口的特征由WNDCLASS结构体来定义的,我们只需要给WNDCLASS结构体对应的成员进行赋值就可以完成窗口类的设计。
WNDCLASS结构体的定义:
style:指定窗口的样式
CS_HREDRAW ==> 当窗口水平方向上的宽度发生变化时, 将重新绘制整个窗口。如果没有指定这一样式,那么在水平方向上调整窗口宽度时,将不会重绘窗口。
CS_VREDRAW ==> 当窗口垂直方向上的高度发生变化时,将重新绘制整个窗口。如果没有指定这一样式,那么在垂直方向上调整窗口高度时,将不会重绘窗口。
CS_NOCLOSE ==> 禁用系统菜单的 Close 命令,这将导致窗口没有关闭按钮。
CS_DBLCLKS ==> 当用户在窗口中双击鼠标时,向窗口过程发送鼠标双击消息。
lpfnWndProc:指定一个窗口回调函数,是一个函数的指针
当应用程序收到给某一窗口的消息时,就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己完成,由操作系统来完成。上面说的回调过程。每一个窗口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。
cbClsExtra:类的附加内存,通常数情况下为0
cbWndExtra:窗口附加内存,通常情况下为0
hInstance:当前实例句柄,用WinMain中的形参hInstance为其赋值
hIcon:指定窗口类的图标句柄,设置为NULL,则使用默认图标
hCursor:指定窗口类的光标句柄,设置为NULL,则使用默认图标,也可用如下函数进行赋值:
hbrBackground:指示窗口的背景颜色,可用如下函数进行赋值:
lpszMenuName:指定菜单资源的名字。如果设置为NULL,那么基于这个窗口类创建的窗口将没有默认菜单
lpszClassName:指定窗口类的名字
步骤2:注册窗口类
设计完窗口类(WNDCLASS)后, 需要调用RegisterClass函数对其进行注册,注册成功后,才可以创建该类型的窗口。
步骤3:创建窗口
设计好窗口类并且将其成功注册之后, 即可用CreateWindow函数产生这种类型的窗口了。
lpClassName:指定窗口类的名称,此名字必须和WNDCLASS的lpszClassName成员指定的名称一样。
lpWindowName:指定窗口的名字,即窗口的标题。
dwStyle:指定创建的窗口的样式,常指定为指WS_OVERLAPPEDWINDOW类型,这是一种多种窗口类型的组合类型。
x, y:指定窗口左上角的x,y坐标。如果参数x被设为CW_USEDEFAULT,那么系统为窗口选择默认的左上角坐标并忽略y参数。
nWidth,nHeight:指定窗口窗口的宽度,高度。如果参数nWidth被设为 CW_USEDEFAULT,那么系统为窗口选择默认的宽度和高度,参数nHeight被忽略。
hWndParent:指定被创建窗口的父窗口句柄,没有父窗口,则设置NULL。
hMenu:指定窗口菜单的句柄,没有,则设置为NULL。
hInstance:窗口所属的应用程序实例的句柄,用WinMain中的形参hInstance为其赋值。
lpParam:作为WM_CREATE消息的附加参数lParam传入的数据指针。通常设置为NULL。
返回值:如果窗口创建成功,CreateWindow函数将返回系统为该窗口分配的句柄,否则,返回NULL。
步骤4:显示和更新窗口
显示窗口函数原型:
更新窗口函数原型:
示例:
3.消息循环
我们需要编写一个消息循环,不断地从消息队列中取出消息,并进行响应。在Windows程序中,消息是由MSG结构体来表示的。
MSG结构体的定义如下:
hWnd:消息所属的窗口。我们通常开发的程序都是窗口应用程序,一个消息一般都是与某个窗口相关联的。例如,在某个活动窗口中按下鼠标左键,产生的按键消息就是发给该窗口的。
message:消息的标识符,是由一个数值来表示的,不同的消息对应不同的数值。例如,鼠标左键按下消息是WM_LBUTTONDOWN,键盘按下消息是WM_KEYDOWN,字符消息是 WM_CHAR。
wParam: 指定消息的附加信息,如键盘按下会触发WM_KEYDOWN消息,但是,具体按下哪个按键需要wParam区分。
time:标识一个消息产生时的时间。
pt:表示产生这个消息时光标或鼠标的坐标。
取消息:
要从消息队列中取出消息,我们需要调用GetMessage()函数。
lpMsg:指向一个消息结构体(MSG)
hWnd:指定接收属于哪一个窗口的消息。通常我们将其设置为NULL,用于接收属于调用线程的所有窗口的窗口消息。
wMsgFilterMin:指定消息的最小值。
wMsgFilterMax:指定消息的最大值。如果wMsgFilterMin和wMsgFilterMax都设置为0, 则接收所有消息。
返回值:GetMessage函数接收到除 WM_QUIT 外的消息均返回非零值。对于WM_QUIT消息,该函数返回零。如果出现了错误,该函数返回-1,例如,当参数hWnd是无效的窗口句柄或lpMsg是无效的指针时。
建立消息循环
TranslateMessage:用于翻译、处理和转换消息并把新消息投放到消息队列中,并且此过程不会影响原来的消息队列。
DispatechMessage:用于把收到的消息传到窗口回调函数进行分析和处理。
4.窗口过程处理函数
在完成上述步骤后,剩下的工作就是编写一个窗口过程函数,用于处理发送给窗口的消息。窗口过程函数的名字可以随便取, 如WinProc, 但函数定义的形式必须和下面声明的形式相同:
示例:
LRESULT CALLBACK WinProc(HWND hWnd, //信息所属的窗口句柄UINT uMsg, //消息类型WPARAM wParam, //附加信息(如键盘按键)LPARAM lParam //附加信息(如鼠标点击坐标)) {switch (uMsg){case WM_KEYDOWN: //键盘按下//……break;case WM_LBUTTONDOWN: //鼠标右键按下//……break;case WM_PAINT: //绘图事件//……break;case WM_DESTROY:PostQuitMessage(0);break;case WM_CLOSE: DestroyWindow(hWnd); break;default://以windows默认方式处理return DefWindowProc(hWnd, uMsg, wParam, lParam);break;}return 0; }
DefWindowProc函数:DefWindowProc函数调用默认的窗口过程,对应用程序没有处理的其他消息提供默认处理
WM_CLOSE:对WM_CLOSE消息的响应并不是必须的,如果应用程序没有对该消息进行响应,系统将把这条消息传给DefWindowProc函数而 DefWindowProc函数则调用DestroyWindow函数来响应这条WM_CLOSE消息
WM_DESTROY:DestroyWindow函数在销毁窗口后,会给窗口过程发送 WM_DESTROY消息,我们在该消息的响应代码中调用PostQuitMessage函数。PostQuitMessage函数向应用程序的消息队列中投递一条WM_QUIT消息并返回。WinMain函数中,GetMessage 函数只有在收到WM_QUIT消息时才返回0,此时消息循环才结束,程序退出。传递给 PostQuitMessage函数的参数值将作为WM_QUIT消息的wParam参数,这个值通常用做WinMain函数的返回值。
完整代码:
#include <Windows.h>LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR IpCmdLine, int nShowCmd) {// 1.设计一个窗口类WNDCLASS wc; // 窗口类变量wc.cbClsExtra = 0; // 类附加内存wc.cbWndExtra = 0; // 窗口附加对象wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 设置背景色wc.hCursor = (HCURSOR)LoadCursor(NULL, IDC_HELP); // 帮助光标wc.hIcon = (HICON)LoadIcon(NULL, IDI_ERROR); // 警告图标wc.hInstance = hInstance; // 应用程序实例wc.lpfnWndProc = WindowProc; // 窗口过程函数名字wc.lpszClassName = TEXT("MyWin"); // 类的名字wc.lpszMenuName = NULL; // 没有菜单wc.style = 0; // 默认风格// 2.注册窗口类RegisterClass(&wc);// 3.创建窗口HWND hWnd = CreateWindow(TEXT("MyWin"), TEXT("测试"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);// 4.显示和更新窗口ShowWindow(hWnd, SW_SHOWNORMAL);UpdateWindow(hWnd);// 5,建立消息循环MSG msg;while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}return msg.lParam; }LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {switch (uMsg){case WM_KEYDOWN: // 键盘按下MessageBox(hWnd, TEXT("键盘按下"), TEXT("键盘"), MB_OK);break;case WM_LBUTTONDOWN: // 鼠标左键按下MessageBox(hWnd, TEXT("鼠标左键按下"), TEXT("鼠标"), MB_OK);break;case WM_DESTROY:PostQuitMessage(0);break;default:return DefWindowProc(hWnd, uMsg, wParam, lParam);}}
MFC入门
MFC(Microsoft Foundation Classese)是微软公司提供一个类库,以C++形式(上面使用的WIN32是C风格的接口)封装了Windows API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量。其中包含的类包括大量Windows句柄封装类和很多Windows的内建控件和组件的封装类。
MFC把Windows SDK API函数包装成了几百个类,MFC给Windows操作系统提供了面向对象的接口,支持可重用性、自包含性以及其他OPP原则。MFC通过编写类来封装窗口、对话框以及其他对象,引入某些关键的虚函数(覆盖这些虚函数可以改变派生类的功能)来完成,并且MFC设计者使类库带来的总开销降到了最低。
第一个MFC程序
编写MFC程序需要包含#include<afxwin.h>头文件:
程序的执行流程:
1.程序开始时,先实例化应用程序对象(有且只有一个)
2.执行程序入口函数InitInstance()
3.给框架类MyFrame对象动态分配空间(自动调用它的构造函数)
4.管家类对象显示窗口 CWnd::ShowWindows
5.框架类对象更新窗口 CWnd::UpdateWindow
6.保存框架类对象指针 CWinTread::m_pMainWnd
代码分析:
1.CFrameWnd框架窗口类
CFrameWnd是从CWnd(窗口基类)派生出来的。CFrameWnd模仿框架窗口行为,我们
可以把框架窗口作为顶层窗口看待,它是应用程序与外部世界的主要接口。
如果想创建一个窗口,可以在此类中调用CWnd::Create或CWnd::CreateEX函数
一般情况下,前6个参数使用默认值。lpszClassName指定了窗口基于WNDCLASS类的名称,为此将其设定为NULL将创建一个基于已注册的WNDCLASS类的默认框架窗口。lpszWindowName参数指定将在窗口的标题栏出现的文字。
2.CWinApp应用程序类
MFC应用程序的核心就是基于CWinApp类的应用程序对象。CWinApp提供了消息循环来检索消息并将消息调度给应用程序窗口。它还包括可被覆盖的、用来自定义应用程序行为的主要虚函数。
一个MFC程序可以有且仅有一个应用程序对象,此对象必须声明为在全局范围内有效,以便它在程序开始时即在内存中被实例化。
3.InitInstance函数
CWinApp::InitInstance函数是一个虚函数,其默认操作仅有一条语句:
InitInstance的目的是给应用程序提供一个自身初始化的机会,其返回值决定了框架接下来要执行的内容,如果返回FALSE将关闭应用程序,如果初始化正常返回TRUE以便允许程序继续进行。此函数是MFC应用程序的入口。
4.m_pMainWnd成员变量
在CWinApp中有一个名为CWinTread::m_pMainWnd的成员变量。该变量是一个CWnd类型的指针,它保存了应用程序框架窗口对象的指针。也就是说,是指向CFramWnd对象(框架窗口类对象)的指针。
消息映射机制:
消息映射是一张将消息和成员函数相互关联的表。比如,框架窗口接收到了一个鼠标左击消息,MFC将搜索该窗口的消息映射,如果存在一个处理WM_LBUTTONDOWN消息的处理程序,就会去调用。
消息映射的步骤:
1.所操作类中,声明消息映射宏
2.通过放置标识的宏来执行消息映射,相应的类将在对BEGIN_MESSAGE_MAP和END_MESSAGE_MAP的调用之间处理消息。
3.对应消息处理函数分别在类中声明,类外定义
Widnows字符集
多字节字符集(8位的ANSI字符集)
在Windows98以及以前的版本使用8位ANSI字符集,它类似于我们程序员熟悉的ASCII字符集。
宽字符集(16位的Unicode字符集)
在WindowsNT中和Windows2000后开始使用16位的Unicode字符集,它是ANSI字符集的一个超集。Unicode适用于国际市场销售应用程序,因为它包含了各种各样来自非U.S.字母表的字符,比如:中文、日文、韩文、西欧等
TEXT(_T)宏
MFC中的TEXT宏可以自动适应字符类型,如果定义了预处理器程序符号_UNICODE,那么编译器将使用Unicode字符,如果没有定义该预处理程序符号,那么编译器将使用ANSI字符。
TCHAR类型
如果定义了_UNICODE符号TCHAR将变成wchar_t类型。如果没有定义_UNICODE符号,TCHAR将变成普通古老的char类型。
用向导生成一个MFC应用程序
类视图
文档/视图结构体系
MFC应用程序框架结构的基础是文档/视图体系结构,这种结构依靠文档对象保存应用程序的数据,并依靠视图对象控制视图中显示的数据,把数据本身与它的显示分离开。
数据的存储和加载由文档类来完成,数据的显示和修改则由视图类来完成。MFC在类CDocument和CView中为视图提供了基础结构。
CWinApp、CFrameWnd和其他类与CDocument和CView合作,把所有的片段连在一起。CView类也派生于CWnd类,框架窗口是视图窗口的一个父窗口。
主框架窗口(CFrameWnd)是整个应用程序外框架所包含的部分,而视图类窗口只是主框架中空白的地方。
消息处理添加
在主框架类中添加WM_LBUTTONDOWN消息的响应函数:
从类视图中找到CMainFrame(继承自CFrameWnd),选择此类然后从属性面板中找到消息按钮,在消息列表中找到WM_LBUTTONDOWN消息,添加。
工程文件增加的改变:
1.在框架类头文件中添加了鼠标左键消息函数的函数声明
2.在框架类cpp文件中添加了消息映射宏
3.在框架类cpp文件中添加了处理鼠标左键消息的函数定义
我们再此OnLButtonDown函数中添加一个MessageBox消息,鼠标左键按下弹出一个提示框,然后执行程序。我们会惊奇的发现程序并未如我们所愿弹出消息框。
因为,框架窗口是视窗口的父窗口,那么视类窗口就应该始终覆盖在框架类窗口之上。就好比框架窗口是一面墙,视类窗口就是墙纸,它始终挡在这面墙前边。也就是说,所有操作,包括鼠标单击、鼠标移动等操作都只能有视类窗口捕获。
我们通过上述同样的操作在视图类中添加鼠标响应消息,看程序运行的结果
相关文章:
MFC - 一文带你从小白到项目应用(全套1)
文章篇幅可能会比较长,从入门到基本能上项目的全部内容。建议观看的过程中,用电脑跟着学习案例。 持续输出优质文章是作者的追求,因为热爱,所以热爱。 最近看动漫被一句鸡汤感动到了,也送给各位朋友: 只要有…...
(2596. 检查骑士巡视方案leetcode,经典深搜)-------------------Java实现
(2596. 检查骑士巡视方案leetcode,经典深搜)-------------------Java实现 题目表述 骑士在一张 n x n 的棋盘上巡视。在 有效 的巡视方案中,骑士会从棋盘的 左上角 出发,并且访问棋盘上的每个格子 恰好一次 。 给你一个 n x n …...
Docker 部署 Bitwarden RS 服务
Bitwarden RS 服务是官方 Bitwarden server API 的 Rust 重构版。因为 Bitwarden RS 必须要通过 https 才能访问, 所以在开始下面的步骤之前, 建议先参考 《Ubuntu Nginx 配置 SSL 证书》 配置好域名和 https 访问。 部署 Bitwarden RS 拉取最新版本的 docker.io/vaultwarden…...
python与mongodb交互-->pymongo
from pymongo import MongoClient# 创建数据库连接对象 client=MongoClient(ip,27017)# 选择一个数据库 db=client[admin]db.authenticate(python,python)# 选择一个集合 col=client[pydata][test]col.insert({"class":"python"})col.find() for data in c…...
【网络】计算机网络基础
Linux网络 对网络的理解 在网络传输中存在的问题: 找到我们所需要传输的主机解决远距离数据传输丢失的问题怎么进行数据转发,路径选择的问题 有问题,就有解决方案; 我们把相同性质的问题放在一起,做出解决方案 解…...
(1)输入输出函数:cin和cout(2)数学函数:sqrt、pow、sin、cos、tan等
输入输出函数:cin 和 cout 在C编程语言中,为了与用户进行交互和显示程序的结果,我们使用了两个非常重要的函数:cin 和 cout。这两个函数分别用于输入和输出。 cin是C中的标准输入流对象,它用于从键盘接收用户的输入。…...
ArmSom-W3开发板之PCIE的开发指南(一)
1. 简介 RK3588从入门到精通本⽂介绍RK平台配置pcie的方法开发板:ArmSoM-W3 2、PCIE接口概述 PCIe(Peripheral Component Interconnect Express)是一种用于连接计算机内部组件的高速接口标准。以下是关于PCIe接口的简要介绍: …...
Android 13.0 framework修改AlertDialog对话框的button样式
1.概述 在13.0系统产品开发中 在AlertDialog 系统对话框原生的确定和取消 两个button 按钮中,由于产品觉得字体默认颜色的不太好看,由于产品的需求修改button字体的颜色,所以需要找到AlertDialog的字体样式然后修改就可以了 2.framework修改AlertDialog 对话框的button样式…...
如何使用ArcGIS Pro提取河网水系
DEM数据除了可以看三维地图和生成等高线之外,还可以用于水文分析,这里给大家介绍一下如何使用ArcGIS Pro通过水文分析提取河网水系,希望能对你有所帮助。 数据来源 本教程所使用的数据是从水经微图中下载的DEM数据,除了DEM数据&a…...
python pytesseract 中文文字批量识别
用pytesseract 来批量把图片转成文字 1、安装好 pytesseract 包 2、下载安装OCR https://download.csdn.net/download/m0_37622302/88348824https://download.csdn.net/download/m0_37622302/88348824 Index of /tesseracthttps://digi.bib.uni-mannheim.de/tesseract/ 我是…...
Python 之plt.plot()的介绍以及使用
文章目录 介绍代码实例 介绍 plt.plot() 是Matplotlib库中用于绘制线图(折线图)的主要函数之一。它的作用是将一组数据点连接起来,以可视化数据的趋势、关系或模式。以下是 plt.plot() 的详细介绍: plt.plot(x, y, fmt, **kwarg…...
自动化生成代码:MyBatis 的 Generator与MyBatis-Plus 的 AutoGenerator
文章目录 Mybatis Generator自动化生成代码MyBatis Generator概述使用Java代码形式1. 在 Maven 或 Gradle 中添加 MyBatis Generator 的依赖:2. 编写配置文件 GeneratorConfig.xml,配置需要生成的数据库表和对应的生成器:3. 在命令行中使用 M…...
达梦数据库-DW-国产化--九五小庞
武汉达梦数据库股份有限公司成立于2000年,是国内领先的数据库产品开发服务商,国内数据库基础软件产业发展的关键推动者。公司为客户提供各类数据库软件及集群软件、云计算与大数据等一系列数据库产品及相关技术服务,致力于成为国际顶尖的全栈…...
LeetCode 753. 破解保险箱【欧拉回路,DFS】困难
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
深度学习概念(术语):Fine-tuning、Knowledge Distillation, etc
文章目录 1.Fine-tuning (微调)2.Transfer Learning (迁移学习)3.Knowledge Distillation (知识蒸馏)4.Meta Learning (元学习) 这里的相关概念都是基于已有预训练模型,就是模型本身已经训练好,有一定泛化能力。需要“再加工”满足别的任务需求。 进入后…...
tcp_v4_connect函数的解析
源码: int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) {// 解析输入的地址结构struct sockaddr_in *usin (struct sockaddr_in *)uaddr;// 获取 TCP 协议栈的全局 death_row 对象struct inet_timewait_death_row *tcp_death_row;// …...
go-channel
设计原理 Go 提及的设计模式就是:不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。 共享内存方式:多个协程共享同一块内存,但是多个协程中读写变量是操作同一块内存,会产生多线程问题的并发问题&am…...
K8s操作命令
生命周期管理 1. 创建 1. 创建资源 kubectl run 创建并运行一个或多个容器镜像。*创建一个deployment或job来管理容器*。 语法:kubectl run NAME --imageimage [–env“keyvalue”] [–portport] [–replicasreplicas] [–dry-runbool] [–overridesinline-jso…...
【MySQL】 MySQL数据库基础
文章目录 🐱👓数据库的操作📌显示当前的数据库📌创建数据库🎈语法:🎈语法说明🎈示例: 🌴使用数据库🎋删除数据库🐱🏍语…...
vscode 下载安装
vscode 下载安装常用插件 vscode 官网: https://code.visualstudio.com/ 点击右上角 Download 进入下载选择页面 选择自己使用操作对应 CPU 架构 下载 本文使用 x86 架构 64位 windows 系统为例 跳转下载页面 自动 开始下载 下载不开始?试试这个直…...
springboot对接postgres
安装postgres 注意:下述链接方式会自动创建数据库steven_russell,若需要创建其他数据库,可以手动执行命令创建数据库 docker run --name postgres \ -p 5432:5432 \ -e POSTGRES_USERsteven_russell \ -e POSTGRES_PASSWORD123456 \ -itd --privilegedtrue postgre…...
[python 刷题] 242 Valid Anagram
[python 刷题] 242 Valid Anagram 题目: Given two strings s and t, return true if t is an anagram of s, and false otherwise. An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the o…...
算法通过村第七关-树(递归/二叉树遍历)青铜笔记|手撕递归
文章目录 前言1. 递归的特征2. 如何写出好的递归3. 怎么看懂递归的代码总结 前言 提示:我们生活在24小时不眠不休的社会里但是没有24小时不眠不休的身体有些东西必须舍弃 -- 马特海格 这一关,我看要谈论的是递归问题,说到它就牵扯到很多问题了…...
#循循渐进学51单片机#点亮你的LED#not.2
1、深刻理解电容的意义,并且在今后的电路学习过程中要多多注意参考别人电路中去耦电路的处理方法,积累经验。 1)电容缓冲电压,抗电磁干扰; 2)低频率电容,一般用的最多的是钽电容,电…...
基于Java+SpringBoot+Vue+uniapp点餐小程序(亮点:协同过滤算法、会员系统,购物车结算、在线聊天)
校园点餐小程序 一、前言二、我的优势2.1 自己的网站2.2 自己的小程序(小蔡coding)2.3 有保障的售后2.4 福利 三、开发环境与技术3.1 MySQL数据库3.2 Vue前端技术3.3 Spring Boot框架3.4 微信小程序 四、功能设计4.1 系统功能结构设计4.2 主要功能描述 五…...
深度学习-全连接神经网络-详解梯度下降从BGD到ADAM - [北邮鲁鹏]
文章目录 参考文章及视频导言梯度下降的原理、过程一、什么是梯度下降?二、梯度下降的运行过程 批量梯度下降法(BGD)随机梯度下降法(SGD)小批量梯度下降法(MBGD)梯度算法的改进梯度下降算法存在的问题动量法(Momentum)目标改进思想为什么有效动量法还有什么效果&…...
数据结构--二叉排序树
目录 二叉排序树的定义 二叉排序树的查找 二叉排序树的插入 二叉排序树的构造 二叉排序树的删除 查找效率分析 回顾 二叉排序树的定义 二叉排序树的查找 查找成功的情况 查找失败的情况 二叉排序树的插入 注意 (1)二叉排序树不允许出现重复的值…...
Python | 根据子列表中的第二个元素对列表进行排序
在本文中,我们将学习如何根据主列表中存在的子列表的第二个元素对任何列表进行排序。 比如 Input : [[‘rishav’, 10], [‘akash’, 5], [‘ram’, 20], [‘gaurav’, 15]] Output : [[‘akash’, 5], [‘rishav’, 10], [‘gaurav’, 15], [‘ram’, 20]] Input …...
qsort函数详细讲解以及利用冒泡排序模拟实现qsort函数
个人主页:点我进入主页 专栏分类:C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞,评论,收藏。 一起努力,一起奔赴大厂。 目录 1.qsort函数 1.1qsort函数的参数 …...
C++QT day6
1> 将之前定义的栈类和队列类都实现成模板类 栈: #include <iostream> #define MAX 128 using namespace std; template<typename T> class Stack_s { private:T *pnew T[MAX];//栈的数组int top;//记录栈顶的变量 public://构造函数Stack_s(int t…...
热门的网页设计工具有哪些/厦门百度快照优化排名
废话不多说,直接开始,整体规划如下: 实验通过虚拟机实现,基于Red Hat 5.8来完成 1.资源分析 在做实验之前,首先要知道高可用用于分配的资源有哪些,由于我们做的是Lvs DR模型Director的高可用,用…...
网上做衣服的网站有哪些/seo博客网站
要解决JSP乱码,首先就要了解JSP乱码的原因1.架设服务器安装MYSQL时的会让你选择一种编码,如果这种编码与你的网页不一致,可能就会造成JSP页面乱码2.在PHPMYADMIN或mysql-front等系统 创建数据库时会让你选择一种编码,如果这种编码与你的网页不一致,也有可能造成JSP页面乱码3.创…...
深圳网站开发建设培训/软件开发外包公司
PHP页面的编码方式是utf-8,用 echo "<script typetext/javascript>alert(已全部清除!);script>";输出时弹出乱码窗口, 原因:因为有alert()输出中文到浏览器,所以一定要在网页中指定编码方式为UTF-8…...
WordPress支持熊掌号/百度官方优化软件
一个脚本可以使得本来要用键盘进行的相互式操作自动化。一个 Shell 脚本主要 由原本需要在命令行输入的命令组成, 或在一个文本编辑器中, 用户可以使用脚 本来把一些常用的操作组合成一组串行。 主要用来书写这种脚本的语言叫做脚本 语言。 很多脚本语言…...
辽宁高速公路建设管理局网站/网络营销图片
我是AY,杨洋,做wpf开发的,最近得了一种病,程序员患得患失综合征。同事说,我年纪在变大,技术跟不上。业余之间,我原创了写了一些语录,给大家中午休息,累疲惫的时候&#x…...
seo批量建站/怎样创建自己的网站
回收宝给出的今年低配高价手机排名数据显示,国产手机四强的华为、OPPO、vivo的手机均上榜,仅有小米的手机未有入榜。回收宝给出的数据显示,今年低配高价手机前十名当中以三星Galaxy note20居于第一名,华为有四款手机入榜ÿ…...