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

C语言编译过程全面解析

今天是2025年1月26日,农历腊月二十七,一个距离新春佳节仅一步之遥的日子。城市的喧嚣中,年味已悄然弥漫——能在这个时候坚持上班的人,真可称为“牛人”了吧,哈哈。。。。

此刻,我在重新审视那些曾被遗忘的角落——C语言,这门陪伴了编程生涯初期的语言,如今再次拾起,竟有如老友重逢,倍感亲切,又回到了那个最初的起点。

C语言编译过程

四个步骤:

(1)预处理:展开头文件/宏替换/去掉注释/条件编译(test.i )。
(2)编译 :检查语法,生成汇编 ( test.s)。
(3)汇编:汇编代码转换机器码(test.o )。
(4)链接:链接到一起生成可执行程序 a.out/a.exe。

在这里插入图片描述

一、预处理

1、**展开所有的宏(macro):**预处理器会查找源代码中的宏定义(使用#define指令定义),并将所有宏调用替换为相应的宏定义。
例如,源代码#define PI 3.14,则预处理器会将所有出现的PI替换为3.14

2、**处理所有条件编译指令:**如#if#elif#else#endif等,这些指令允许程序员根据条件编译不同的代码段。

3、处理#include指令:预处理器会查找源代码中的#include指令,将被包含文件的内容插入到源文件中的指定位置。
这通常用于包含头文件,以便在多个源文件中共享定义和声明。

4、**删除所有注释:**注释是程序员为代码添加的解释性文字,对程序的运行没有实际作用,因此预处理器会将其删除。

5、 **添加行号和文件名信息:**以便在编译时编译器可以使用这些信息来显示警告或错误信息。

预处理结束后,会产生一个后缀为.i的临时文件,该文件是源代码的修改版,已经删除了注释、展开了宏、包含了头文件等。

示例:
a1.c

#include <stdio.h>
int main(void) {printf("hello world\n");system("pause");return 0;
}

执行命令:
-E 是让编译器在预处理之后就退出,不进行后续编译过程;
-o 指定输出文件名。

[admin@myhost testc]$ gcc  -E  a1.c  -o  a1.i

生成a1.i文件
在这里插入图片描述

.c 中的头文件展开、[宏展开]。生成的文件是 .i 文件,预处理之后的程序还是文本,可以用文本编辑器打开。
预处理后的文件变大

头文件

什么是头文件
头文件(Header Files)是C语言中用来声明函数、宏和数据类型的文件(只是声明,不占用内存空间),通常以**“.h”**作为后缀。使得多个源文件可以共享这些声明和定义,从而提高代码的重用性和可读性。
在这里插入图片描述
头文件的作用

声明函数和变量:头文件可以包含函数和变量的声明,使得不同的源文件可以共享这些声明。
定义宏:头文件可以定义宏,这样在多个源文件中都可以使用相同的宏。
包含其他头文件:头文件可以包含其他头文件,从而形成一个头文件的层次结构。

示例:自定义头文件

  1. 创建头文件:.h 扩展名的文件
    myheader.h的头文件。
#ifndef MYHEADER_H
#define MYHEADER_H// 函数声明
void myFunction();// 宏定义
#define MY_MACRO 100// 类型定义(可选)
typedef struct {int x;int y;
} Point;#endif // MYHEADER_H

预处理器指令#ifndef、#define和#endif来防止头文件被多次包含

  1. 创建源文件:.c文件,并实现头文件中声明的函数
    myfunctions.c的文件。
#include "myheader.h"
#include <stdio.h>void myFunction() {printf("Hello from myFunction!\n");
}
  1. 使用头文件
    main.c的文件
#include "myheader.h"int main() {myFunction();printf("MY_MACRO = %d\n", MY_MACRO);Point p;p.x = 10;p.y = 20;printf("Point p = (%d, %d)\n", p.x, p.y);return 0;
}

预处理命令

C语言的预处理命令是由预处理器在编译之前执行的指令。
这些指令以#字符开头,主要目的是在编译之前对源代码进行文本替换、条件编译、文件包含等操作。

C语言中常见的预处理命令:
在这里插入图片描述

1、宏定义 (#define)
宏可以是简单的常量、带参数的宏(类似于函数)或者更复杂的结构。
宏定义是预处理命令中最常见的一种。

(1). 定义常量宏
常量宏是最简单的宏类型,它们用于定义常量值。例如:

#define PI 3.14159
#define MAX_SIZE 100

在代码中,每当预处理器遇到PI或MAX_SIZE时,它们都会被替换为3.14159和100。

(2). 定义带参数的宏(宏函数)
宏也可以像函数一样接受参数,并在展开时替换这些参数。例如:

#define SQUARE(x) ((x) * (x))

这个宏接受一个参数x,并返回它的平方。注意,由于宏是文本替换,所以它们不执行类型检查,也不会导致函数调用的开销。

(3). 条件编译宏
宏还可以用于条件编译,根据宏的定义与否来决定是否包含某段代码。例如:

#define DEBUG#ifdef DEBUG// 这段代码在定义了DEBUG宏时会被编译printf("Debug mode is on.\n");
#else// 这段代码在没有定义DEBUG宏时会被编译// printf("Debug mode is off.\n");
#endif

如果定义了DEBUG宏,则编译器会包含printf(“Debug mode is on.\n”);这行代码;否则,它会忽略它。

2、文件包含 (#include)
用于在当前文件中包含(插入)另一个文件的内容。
例如:#include <stdio.h> 包含了标准输入输出库的头文件。
也可以包含用户自定义的头文件:#include “myheader.h”。
3、条件编译
根据宏的定义与否来决定是否编译某段代码。
#if、#ifdef(如果定义了某个宏)
#ifndef(如果没有定义某个宏)
#else、#elif(else if的缩写)
#endif指令。
例如:#ifdef DEBUG … #endif 用于在定义了DEBUG宏时编译包含的代码。
4、宏取消定义 (#undef)
用于取消之前定义的宏。
例如:#undef PI 会取消PI宏的定义。
5、行控制 (#line)
用于改变当前行号和文件名,通常用于由其他程序生成的源代码中。
例如:#line 100 “newfile.c” 会将接下来的代码行视为位于名为newfile.c的文件的第100行。
6、错误和警告 (#error 和 #warning)
用于生成编译时的错误和警告信息。
例如:#error “This is an error message” 会导致编译器显示错误消息并停止编译。
#warning “This is a warning message” 会导致编译器显示警告消息但继续编译。
7、预定义的宏
C预处理器定义了一些预定义的宏,如:
LINE(当前行号)
FILE(当前文件名)
DATE(编译日期)
TIME(编译时间)等。

二、编译

将前面预编译后的文件进行编写,命令:

gcc -S a1.i -o a1.s

编译阶段的主要任务是将预处理后的C代码转换为汇编代码。这一转换过程涉及多个步骤,包括词法分析、语法分析、语义分析和代码生成(生成汇编代码)。

1、词法分析
任务:将源代码分解成一个个基本的元素,如变量名、常量、关键字、运算符和分隔符等。
输出:这些基本元素通常被称为“词法单元”或“标记”。
2、语法分析
任务:检查源代码的结构或语法是否正确,并构建所谓的抽象语法树(AST)。
AST:是源代码逻辑结构的一个层级模型,它表示了源代码中各个元素之间的关系。
输出:如果源代码语法正确,则生成抽象语法树;如果语法错误,则编译器会报错并停止编译。
3、语义分析
任务:在语法分析的基础上,进一步检查源代码是否有语义错误,例如变量类型不匹配、使用了未声明的变量或函数等。
输出:如果源代码语义正确,则继续后续的编译过程;如果语义错误,则编译器会报错并停止编译。
4、代码生成(生成汇编代码)
任务:将经过词法分析、语法分析和语义分析后的源代码转换为汇编语言代码。
汇编代码:是一种低层次的编程语言,更接近于机器语言,但比机器语言更易于人类阅读和理解。
输出:生成的汇编代码文件通常具有.s扩展名。

举例:
example.c:

#include <stdio.h>int main() {int a = 5;int b = 10;int sum = a + b;printf("Sum: %d\n", sum);return 0;
}

预处理:
使用预处理器处理example.c,将头文件stdio.h的内容包含进来,并处理宏定义等。
输出预处理后的文件example.i
编译:
词法分析:编译器读取预处理后的代码,将其分解成词法单元,如关键字int、return,标识符a、b、sum、main,运算符+、=,以及分隔符等。
语法分析:编译器根据C语言的语法规则,检查这些词法单元是否构成了有效的语法结构,并构建抽象语法树(AST)。例如,它会识别出int a = 5;是一个变量声明和初始化的语句。
语义分析:编译器进一步检查这些语法结构是否有意义。例如,它会检查变量a、b、sum在使用前是否已被声明,以及它们的类型是否匹配。此外,它还会检查函数调用printf是否合法,即是否提供了正确类型和数量的参数。
代码生成:如果语义分析通过,编译器将抽象语法树转换为汇编代码。

.section .data
sum_fmt: .asciz "Sum: %d\n".section .text
.globl main
main:pushq   %rbpmovq    %rsp, %rbpsubq    $16, %rspmovl    $5, -4(%rbp)      ; int a = 5;movl    $10, -8(%rbp)     ; int b = 10;movl    -4(%rbp), %eax    ; eax = aaddl    -8(%rbp), %eax    ; eax = eax + bmovl    %eax, -12(%rbp)   ; int sum = eax (即 a + b 的结果)leaq    sum_fmt(%rip), %rdi ; 设置第一个参数为格式字符串movl    -12(%rbp), %eax    ; 设置第二个参数为 sum 的值movl    %eax, %esi         ; esi = eax (即 sum 的值)xorl    %eax, %eax         ; 清零 eax,作为 printf 的返回值占位符call    printf             ; 调用 printf 函数movl    $0, %eax          ; 设置返回值 0leave                     ; 清理栈帧ret                       ; 返回

三、汇编

将前面编译后的文件进行汇编,命令:

gcc -c a1.s -o a1.o

汇编阶段的主要任务是将汇编代码转换为机器代码(也称为目标代码或二进制代码)。这一转换过程是由汇编器(Assembler)完成的。

汇编指令解析
汇编器逐条读取汇编代码中的指令,并根据汇编指令和机器指令的对照表将其转换为对应的机器指令。
每条汇编指令通常都对应一条或多条机器指令。

地址和符号处理
在汇编过程中,汇编器需要处理汇编代码中的地址和符号。
例如,对于变量和函数的引用,汇编器会将其转换为相应的内存地址。
此外,汇编器还会处理标签(labels)和跳转指令(如goto、if等),确保它们能够正确地跳转到目标位置。

生成目标文件
经过汇编器处理后的代码被转换为机器代码,并存储在目标文件(通常具有.o或.obj扩展名)中。目标文件是二进制格式的,包含了机器可以直接执行的指令和数据。

在这里插入图片描述

四、链接

命令:gcc a1.o -o a1.exe

链接阶段是将多个目标文件(.o或.obj文件)和库文件合并成一个可执行文件的过程。

这个过程涉及多个步骤,包括符号解析、重定位以及处理静态库和动态库等。
1、符号解析
链接器会解析目标文件中的符号信息。
符号通常包括变量名、函数名等,它们代表了程序中的不同实体。
链接器会检查每个目标文件中的符号定义和引用,确保所有引用的符号都有相应的定义。
如果某个符号在多个目标文件中都有定义,链接器会根据链接规则(如C语言的“one definition rule”)来决定使用哪个定义。
2、重定位
在编译和汇编阶段,目标文件中的代码和数据被放置在相对地址中。
然而,在链接阶段,这些相对地址需要被转换为绝对地址,以便程序在运行时能够正确地访问内存中的代码和数据。
链接器会根据目标文件中的重定位信息,调整代码和数据的位置,确保它们能够被正确地加载和执行。

3、处理静态库和动态库
链接阶段还需要处理静态库和动态库。
静态库是一组预编译的目标文件的集合,它们在链接时被复制到最终的可执行文件中。
动态库则是在程序运行时动态加载的库文件,链接器会在可执行文件中记录动态库的依赖关系,并在程序运行时加载这些库。
使用动态库可以减小可执行文件的大小,并且当库文件更新时,无需重新编译整个程序。
静态库:
静态库是一组已经被编译和链接成二进制代码的程序模块,这些模块在编译时被合并到最终的可执行文件中。
特点:
在编译时将库的代码嵌入到可执行文件中,因此可执行文件独立于库的存在。
每次程序编译时,静态库的代码都被复制到生成的可执行文件中。
生成的可执行文件包含了库的所有必要代码,因此文件通常较大。
可执行文件不依赖于外部库文件,可以在没有库文件的机器上独立运行。
文件扩展名:通常以.a(Unix/Linux)或.lib(Windows)为文件扩展名。

使用场景:适用于对执行文件大小没有严格限制、需要在没有库文件的机器上运行或需要避免动态链接带来的依赖性的场景。

动态库:
动态库是一组已经被编译和链接成二进制代码的程序模块,但它们在运行时被加载到内存中,而不是在编译时被合并到可执行文件中。
特点:
可执行文件在运行时需要动态库的支持。
动态库可以被多个程序共享,从而减小可执行文件的大小。
需要确保目标系统上存在相应的动态库,否则程序将无法正常运行。
易于更新和维护,因为只需替换相应的动态库文件即可,无需重新编译整个程序。
文件扩展名:通常以.so(Unix/Linux)或.dll(Windows)为文件扩展名。
隐式调用:程序在编译时指定依赖的动态库,链接器会在程序运行时自动加载这些库。
显式调用:程序在运行时通过特定的API来加载和调用动态库中的函数,这种方式提高了程序的灵活性。
使用场景:适用于需要多个程序共享库代码、希望节省内存和磁盘空间或需要方便地进行库代码升级和维护的场景。

4、生成可执行文件
链接器会生成最终的可执行文件。这个文件包含了程序的所有代码和数据,并且已经被正确地组织和链接在一起,可以在操作系统上直接运行。

借用网络一张图,总结:
在这里插入图片描述

相关文章:

C语言编译过程全面解析

今天是2025年1月26日&#xff0c;农历腊月二十七&#xff0c;一个距离新春佳节仅一步之遥的日子。城市的喧嚣中&#xff0c;年味已悄然弥漫——能在这个时候坚持上班的人&#xff0c;真可称为“牛人”了吧&#xff0c;哈哈。。。。 此刻&#xff0c;我在重新审视那些曾被遗忘的…...

算法每日双题精讲 —— 前缀和(【模板】一维前缀和,【模板】二维前缀和)

在算法竞赛与日常编程中&#xff0c;前缀和是一种极为实用的预处理技巧&#xff0c;能显著提升处理区间和问题的效率。今天&#xff0c;我们就来深入剖析一维前缀和与二维前缀和这两个经典模板。 一、【模板】一维前缀和 题目描述 给定一个长度为 n n n 的整数数组 a a a&…...

Maui学习笔记- SQLite简单使用案例02添加详情页

我们继续上一个案例&#xff0c;实现一个可以修改当前用户信息功能。 当用户点击某个信息时&#xff0c;跳转到信息详情页&#xff0c;然后可以点击编辑按钮导航到编辑页面。 创建项目 我们首先在ViewModels目录下创建UserDetailViewModel。 实现从详情信息页面导航到编辑页面…...

VMware 中Ubuntu无网络连接/无网络标识解决方法【已解决】

参考文档 Ubuntu无网络连接/无网络标识解决方法_ubuntu没网-CSDN博客 再我们正常使用VMware时&#xff0c;就以Ubuntu举例可能有时候出现无网络连接&#xff0c;甚至出现无网络标识的情况&#xff0c;那么废话不多说直接上教程 环境&#xff1a;无网络 解决方案&#…...

完美世界前端面试题及参考答案

如何设置事件捕获和事件冒泡? 在 JavaScript 中,可以通过addEventListener方法来设置事件捕获和事件冒泡。该方法接收三个参数,第一个参数是事件类型,如click、mousedown等;第二个参数是事件处理函数;第三个参数是一个布尔值,用于指定是否使用事件捕获机制。当这个布尔值…...

新时代架构SpringBoot+Vue的理解(含axios/ajax)

文章目录 引言SpringBootThymeleafVueSpringBootSpringBootVue&#xff08;前端&#xff09;axios/ajaxVue作用响应式动态绑定单页面应用SPA前端路由 前端路由URL和后端API URL的区别前端路由的数据从哪里来的 Vue和只用三件套axios区别 引言 我是一个喜欢知其然又知其所以然的…...

代理模式 -- 学习笔记

代理模式学习笔记 什么是代理&#xff1f; 代理是一种设计模式&#xff0c;用户可以通过代理操作&#xff0c;而真正去进行处理的是我们的目标对象&#xff0c;代理可以在方法增强&#xff08;如&#xff1a;记录日志&#xff0c;添加事务&#xff0c;监控等&#xff09; 拿一…...

gif动画图像优化,相同的图在第2,4,6帧中重复出现,会增加图像体积吗?

对于 GIF 图像&#xff0c;情况与 Git 文件存储有所不同。GIF 是一种图像格式&#xff0c;其体积主要取决于图像的内容、颜色数量、优化设置等因素。如果在 GIF 动画中&#xff0c;相同的图像在第 2、4、6 帧中重复出现&#xff0c;是否会增加图像体积&#xff0c;取决于以下几…...

Harmony Next 跨平台开发入门

ArkUI-X 官方介绍 官方文档&#xff1a;https://gitee.com/arkui-x/docs/tree/master/zh-cn ArkUI跨平台框架(ArkUI-X)进一步将ArkUI开发框架扩展到了多个OS平台&#xff1a;目前支持OpenHarmony、Android、 iOS&#xff0c;后续会逐步增加更多平台支持。开发者基于一套主代码…...

阿里巴巴Qwen团队发布AI模型,可操控PC和手机

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

android 音视频系列引导

音视频这块的知识点自己工作中有用到&#xff0c;一直没有好好做一个总结&#xff0c;原因有客观和主观的。 客观是工作太忙&#xff0c;没有成段时间做总结。 主观自己懒。 趁着这次主动离职拿了n1的钱&#xff0c;休息一下&#xff0c;对自己的人生做一下总结&#xff0c;…...

STM32调试手段:重定向printf串口

引言 C语言中经常使用printf来输出调试信息&#xff0c;打印到屏幕。由于在单片机中没有屏幕&#xff0c;但是我们可以重定向printf&#xff0c;把数据打印到串口&#xff0c;从而在电脑端接收调试信息。这是除了debug外&#xff0c;另外一个非常有效的调试手段。 一、什么是pr…...

基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结

title: 基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结 tags: - jenkins - python categories: - jenkins在软件开发的持续集成与持续交付&#xff08;CI/CD&#xff09;流程里&#xff0c;及时、准确地获取并分析测试报告对保障软件质量至关重要。本文将详细…...

Vue.js组件开发-实现导出PDF文件可自定义添加水印及水印样式方向

使用 Vue 实现导出 PDF 文件并添加水印&#xff0c;同时支持设置水印样式、方向和自定义水印内容。 步骤 安装依赖&#xff1a;使用 html2canvas 将 HTML 内容转换为 canvas&#xff0c;使用 jspdf 生成 PDF 文件。创建 Vue 组件&#xff1a;在组件中实现水印生成、HTML 转 c…...

css中的animation

css的animation animation是一个综合属性,是animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode, animation-play-state, and animation-timeline这些属性的简写 不过在…...

四.3 Redis 五大数据类型/结构的详细说明/详细使用( hash 哈希表数据类型详解和使用)

四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09; 文章目录 四.3 Redis 五大数据类型/结构的详细说明/详细使用&#xff08; hash 哈希表数据类型详解和使用&#xff09;2.hash 哈希表常用指令(详细讲解说明)2.1 hset …...

基于Springboot + vue实现的洗衣店订单管理系统

“前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff1a;人工智能学习网站” &#x1f496;学习知识需费心&#xff0c; &#x1f4d5;整理归纳更费神。 &#x1f389;源码免费人人喜…...

用 Scoop 优雅管理 Windows 软件:安装、配置与使用全指南

本篇将主要讲讲如何用「Scoop」优雅管理 Windows 软件&#xff1a;安装、配置与使用全指南 一、Scoop 是什么&#xff1f; Scoop 是一款专为 Windows 设计的命令行软件包管理工具&#xff0c;它能让你像 Linux 系统一样通过命令快速安装、更新和卸载软件。其核心优势包括&…...

深度学习中常用的评价指标方法

深度学习中常用的评价指标方法因任务类型&#xff08;如分类、回归、分割等&#xff09;而异。以下是一些常见的评价指标&#xff1a; 1. 分类任务 准确率&#xff08;Accuracy&#xff09; 定义&#xff1a;正确预测的样本数占总样本数的比例。 公式&#xff1a;AccuracyTPT…...

多协议网关BL110钡铼6路RS485转MQTT协议云网关

多协议网关BL110钡铼6路RS485转MQTT协议云网关是一款集成了多种通信协议的工业级网关设备&#xff0c;专为物联网&#xff08;IoT&#xff09;应用设计。该网关能够将RS485总线设备的数据转化为MQTT协议&#xff0c;通过网络传输到云平台&#xff0c;实现远程监控和数据管理。以…...

Nginx 安装配置指南

Nginx 安装配置指南 引言 Nginx 是一款高性能的 HTTP 和反向代理服务器&#xff0c;同时也可以作为 IMAP/POP3/SMTP 代理服务器。由于其稳定性、丰富的功能集以及低资源消耗而被广泛应用于各种场景。本文将为您详细介绍 Nginx 的安装与配置过程。 系统要求 在安装 Nginx 之…...

二叉树介绍

一.树的概念 树的图&#xff1a; 1.结点的度&#xff1a;一个结点含有子树的个数称为该结点的度&#xff1b; 如上图&#xff1a;A的度为6 2.树的度&#xff1a;一棵树中&#xff0c;所有结点度的最大值称为树的度&#xff1b; 如上图&#xff1a;树的度为6 3.叶子结点或终…...

VLC-Qt: Qt + libVLC 的开源库

参考链接 https://blog.csdn.net/u012532263/article/details/102737874...

【四川乡镇界面】图层shp格式arcgis数据乡镇名称和编码2020年wgs84无偏移内容测评

本文将详细解析标题和描述中提到的IT知识点&#xff0c;主要涉及GIS&#xff08;Geographic Information System&#xff0c;地理信息系统&#xff09;技术&#xff0c;以及与之相关的文件格式和坐标系统。 我们要了解的是"shp"格式&#xff0c;这是一种广泛用于存储…...

Helm Chart 详解:从入门到精通

Helm 是 Kubernetes 的包管理工具,而 Helm Chart 是 Helm 的核心概念,用于定义、安装和升级 Kubernetes 应用。本文将详细介绍 Helm Chart 的结构、核心文件及其作用,帮助你从入门到精通 Helm Chart。 © ivwdcwso (ID: u012172506) 1. 什么是 Helm Chart? Helm Char…...

excel如何查找一个表的数据在另外一个表是否存在

比如“Sheet1”有“张三”、“李四”“王五”三个人的数据&#xff0c;“Sheet2”只有“张三”、“李四”的数据。我们通过修改“Sheet1”的“民族”或者其他空的列&#xff0c;修改为“Sheet2”的某一列。这样修改后筛选这个修改的列为空的或者为出错的&#xff0c;就能找到两…...

gesp(C++六级)(7)洛谷:P10376:[GESP202403 六级] 游戏

gesp(C六级)&#xff08;7&#xff09;洛谷&#xff1a;P10376&#xff1a;[GESP202403 六级] 游戏 题目描述 你有四个正整数 n , a , b , c n,a,b,c n,a,b,c&#xff0c;并准备用它们玩一个简单的小游戏。 在一轮游戏操作中&#xff0c;你可以选择将 n n n 减去 a a a&am…...

随机森林例子

完整代码&#xff1a; # 导入必要的库 from sklearn.datasets import load_iris from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score import numpy as np# 加载鸢尾花数…...

Qt中Widget及其子类的相对位置移动

Qt中Widget及其子类的相对位置移动 最后更新日期&#xff1a;2025.01.25 下面让我们开始今天的主题… 一、开启篇 提出问题&#xff1a;请看上图&#xff0c;我们想要实现的效果是控件黄色的Widge&#xff08;m_infobarWidget&#xff09;t随着可视化窗口&#xff08;m_glWidge…...

MyBatis 关联映射详解

目录 一、创建表结构 1. 学生表 (student) 2. 教师表 (teacher) 二、一对一 & 多对一 关系映射 1. 连表查询&#xff08;直接查询&#xff09; 2. 分步查询&#xff08;懒加载&#xff09; 三、一对多 关系映射 1. 直接查询 2. 分步查询 四、MyBatis 延迟加载&am…...