重生之我在异世界学编程之C语言:深入预处理篇(上)
大家好,这里是小编的博客频道
小编的博客:就爱学编程
很高兴在
CSDN
这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!!
本文目录
- 引言
- 正文
- 一、预处理的作用与流程
- (1)预处理阶段(Preprocessing)
- (2)编译阶段(Compilation)
- (3)汇编阶段(Assembly)
- (4)链接阶段(Linking)
- 二、预处理指令详解
- (1)宏定义和宏替换
- 《1》宏定义的基本概念
- 1.1 无参数的宏定义
- 1.2 带参数的宏定义
- 《2》宏定义的特性与注意事项
- 2.1 宏的文本替换特性
- 2.2 宏的作用域与生命周期
- 2.3 宏与函数的区别
- 《3》高级宏技巧与应用案例
- 3.1 宏串联与字符串化
- (2)文件包含
- 一、文件包含的基本概念
- 二、`#include`指令的使用方式
- 三、文件包含的优势与注意事项
- (1)优势
- (2)注意事项
- 四、示例说明
- 由于本文已经介绍很多了,所以小编在下一篇完结本节知识的介绍期待一下吧!!!!快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!
引言
C语言预处理是C语言编译过程的一个重要阶段,它在源代码被正式编译之前对代码进行一系列的处理操作。这些处理包括宏替换、文件包含、条件编译等,旨在提高代码的移植性、可读性和可维护性。以下是关于C语言预处理有关的详细介绍。一起来看看吧!!!
那接下来就让我们开始遨游在知识的海洋!
正文
一、预处理的作用与流程
- 预处理阶段主要处理源文件中以
#
开头的指令。这些指令告诉预处理器在编译之前需要对源代码进行哪些修改或调整。经过预处理后,生成一个中间文件(通常以.i
为后缀),然后再进入正式的编译阶段。
- 在C语言中,从源代码到可执行文件的转换过程通常分为四个阶段:
预处理、编译、汇编和链接
。下面是对这四个阶段的详细介绍:
(1)预处理阶段(Preprocessing)
预处理是编译过程的第一个阶段,主要任务是对源代码中的预处理指令进行处理。这些指令通常以“#”开头,如
#include
、#define
等。
-
1. 宏替换:预处理器会将代码中的宏(使用
#define
定义的内容)替换为实际的值或表达式。例如,将PI
定义为3.14159后,预处理器会在代码中所有出现PI
的地方将其替换为3.14159
。 -
2. 文件包含:预处理器会处理
#include
指令,将指定头文件的内容插入到源文件中。这有助于代码的模块化,使得多个源文件可以共享相同的声明和定义。 -
3. 条件编译:根据
#ifdef
、#ifndef
等条件编译指令,预处理器会决定是否编译某部分代码。这允许开发者根据不同的编译条件选择性地包含或排除特定的代码块。 -
4. 删除注释:预处理阶段还会删除源代码中的所有注释,因为注释对编译器是不可见的,不参与编译。
经过预处理后的代码,通常是一个没有注释、完成了宏替换和头文件包含的文件,但扩展名仍然是
.c
。
(2)编译阶段(Compilation)
在编译阶段,编译器会把预处理后的C语言代码转换为汇编代码。这一阶段的主要任务是进行语法分析和语义分析。
- 1. 词法分析:编译器首先会将源代码分解为一系列的单词(token),如关键字、标识符、运算符等。这些单词将作为后续语法分析的输入。
- 2. 语法分析:编译器会根据C语言的语法规则,将单词组合成语法结构,如表达式、语句、函数等。这一阶段的目标是验证源代码是否符合C语言的语法规则。
- 3. 语义分析:在语法分析的基础上,编译器会进一步检查变量类型、函数调用等是否符合C语言的语义规则。同时,编译器还会生成中间表示(Intermediate Representation, IR),这是一种介于高级语言和机器语言之间的代码形式,便于后续的优化和代码生成。
编译阶段的输出结果是生成目标文件(object file),通常以
.o
或.obj
为后缀。这是一个二进制文件,包含了程序的机器码,但还不能直接运行。
(3)汇编阶段(Assembly)
- 在汇编阶段,汇编器会将编译生成的中间代码转换成目标代码,即汇编指令。这些汇编指令与具体的硬件平台相关,因此汇编器的输出会因目标平台的不同而有所差异。
汇编阶段的主要任务是:
- 将中间代码翻译成汇编指令;
- 为源代码中的变量、函数等生成符号表,以便在链接阶段使用;
- 生成目标文件,这是一个可以直接被链接器处理的二进制文件。
(4)链接阶段(Linking)
链接阶段是编译过程的最后一步,它的任务是将多个目标文件以及所需的库文件组合成一个可执行文件。
-
1. 符号解析:链接器会查找并解析各个目标文件和库文件中的符号,如函数和变量的定义与调用。这是确保程序正确性的关键步骤之一。
-
2. 地址分配:链接器会为每个符号分配内存地址,以确保程序中的函数调用和变量引用可以正确执行。
-
3. 库链接:如果程序使用了外部的库(如标准C库或第三方库),链接器会将这些库的代码与目标文件链接在一起。
-
4. 生成可执行文件:最终,链接器将所有目标文件和库文件整合成一个可以直接在操作系统上运行的可执行文件。这个文件的扩展名通常是
.exe
(在Windows系统上)或没有扩展名(在Linux/Unix系统上)。
通过以上四个阶段的处理,C语言的源代码最终被转换成了一个可以在计算机上运行的
可执行文件
。
二、预处理指令详解
- C语言的预处理阶段在编译之前对源代码进行一系列的处理操作,这些处理包括
宏替换、文件包含、条件编译
等。小编先介绍宏定义的相关知识,并通过丰富的代码示例来详细阐述其用法和注意事项。
(1)宏定义和宏替换
《1》宏定义的基本概念
- 宏定义是C语言中一种常用的预处理指令,它允许程序员为一段代码或数据定义一个别名(即宏)。在编译过程中,预处理器会将这些宏替换为它们所代表的实际内容。宏定义通常使用
#define
指令来实现。
1.1 无参数的宏定义
- 无参数的宏定义是最简单的宏类型,它直接将一个标识符替换为一个指定的字符串或数值。这种宏常用于定义常量或简化复杂的表达式。
例:
#include <stdio.h>// 定义一个表示圆周率的宏
#define PI 3.14159265358979323846int main() {double radius = 5.0;double area = PI * radius * radius; // 使用PI宏计算圆的面积printf("The area of the circle is: %f
", area);return 0;
}
- 在这个例子中,
PI
被定义为一个表示圆周率的常量。在main
函数中,我们使用这个宏来计算圆的面积。
1.2 带参数的宏定义
带参数的宏定义允许我们创建更灵活的宏,这些宏可以接受参数并在替换时将它们插入到相应的位置。这种宏类似于函数,但它们在预处理阶段就被展开,而不是在运行时调用。
#include <stdio.h>// 定义一个计算两个数最大值的宏
#define MAX(a, b) ((a) > (b) ? (a) : (b))int main() {int x = 10, y = 20;int max_value = MAX(x, y); // 使用MAX宏计算最大值printf("The maximum value between %d and %d is: %d
", x, y, max_value);return 0;
}
在这个例子中,MAX
宏接受两个参数a
和b
,并返回它们之间的较大值。在main
函数中,我们使用这个宏来计算x
和y
之间的最大值。
《2》宏定义的特性与注意事项
虽然宏定义提供了强大的功能,但在使用时也需要注意一些
特性和潜在的问题
。
2.1 宏的文本替换特性
- 宏替换是在预处理阶段进行的文本替换操作,这意味着预处理器
不会检查
替换后的代码是否有效或合法。因此,如果宏定义不当或使用不当,可能会导致意外的结果或错误。
例:
#include <stdio.h>// 一个有问题的宏定义
#define SQUARE(x) x * xint main() {int a = 5;int result = SQUARE(a + 1); // 期望结果是(a+1)*(a+1),但实际结果是a+1*a+1printf("The square of (a + 1) is: %d
", result); // 输出结果是11,而不是36return 0;
}
- 在这个例子中,由于宏
SQUARE
没有正确地用括号将参数包围起来,导致替换后的表达式变成了a + 1 * a + 1
,而不是(a + 1) * (a + 1)
。因此,输出结果不是期望的36
,而是错误的11
。
为了避免这种问题,我们应该在定义宏时使用括号来保护参数和整个表达式:
#include <stdio.h>// 修改后的正确宏定义
#define SQUARE(x) ((x) * (x))int main() {int a = 5;int result = SQUARE(a + 1); // 现在结果是(a+1)*(a+1)printf("The square of (a + 1) is: %d
", result); // 输出结果是36return 0;
}
2.2 宏的作用域与生命周期
- 宏定义在它们被声明的文件中是全局可见的,除非使用了特定的编译器选项或预处理指令来限制它们的可见性。此外,宏的生命周期贯穿整个编译过程,直到目标代码生成为止。一旦目标代码生成,宏就不再存在;它们只是编译过程中的一种辅助工具。
需要注意的是:
- 由于宏是在预处理阶段进行替换的,因此它们
不具有
变量那样的作用域和生命周期概念。换句话说,宏在整个源文件中都是有效的,并且每次出现时都会被替换为其定义的内容。
2.3 宏与函数的区别
尽管宏在某些方面类似于函数(例如它们都可以接收参数并返回结果),但它们之间存在显著的差异:
- 作用时机:宏在预处理阶段进行替换,而函数在运行时被调用。
- 类型检查:函数在编译时会进行类型检查以确保参数的类型匹配,而宏则不进行任何类型检查。
- 调试难度:由于宏是在预处理阶段展开的,因此在调试时可能难以跟踪和理解它们的实际行为。相比之下,函数具有明确的入口点和出口点,更容易进行调试和分析。
- 性能考虑:虽然宏可以避免函数调用的开销(如栈操作和参数传递),但在某些情况下,过度使用宏可能会导致代码膨胀和性能下降。因此,在选择使用宏还是函数时需要根据具体情况进行权衡。
《3》高级宏技巧与应用案例
除了基本的宏定义之外,C语言还支持一些高级的宏技巧和应用场景。这些技巧和场景可以帮助我们编写更高效、更可维护的代码。
3.1 宏串联与字符串化
C语言提供了两个特殊的操作符来支持宏的字符串化和串联操作:#
和##
。
#
操作符用于将宏参数转换为字符串字面量,这在需要动态构建字符串时非常有用。
#include <stdio.h>#define STRINGIFY(x) #x
int main() {printf("%s", STRINGIFY(Hello, World!)); // 输出"Hello, World!"return 0;
}
##
操作符用于连接两个标记(token)以形成一个新的标记。这在需要动态构建标识符名称时非常有用。
#include <stdio.h>#define CONCAT(a, b) int ## a ## _ ## b = a + b;CONCAT(x, y); // 展开为int
(2)文件包含
预处理的主要任务之一便是文件包含(File Inclusion),这一功能通过
#include
指令实现,使得一个源文件能够将另一个源文件的全部内容包含进来。
一、文件包含的基本概念
- 文件包含允许开发者将一个或多个源文件的内容插入到当前正在编译的源文件中。这种机制极大地促进了代码的模块化和重用性。通过将常用的
代码段、宏定义、函数声明
等放在一个单独的头文件
中,然后在需要的地方通过#include
指令引入这些头文件,可以显著减少代码的重复,提高开发效率。
二、#include
指令的使用方式
#include
指令有两种基本的使用格式:
- 尖括号形式:
#include <文件名>
这种形式通常用于包含标准库头文件或系统提供的头文件。预处理器会在系统的标准目录中寻找指定的文件。
- 双引号形式:
#include "文件名"
这种形式则用于包含用户自定义的头文件。预处理器首先会在当前源文件所在的目录中查找指定的文件,如果找不到,再按照系统标准目录的路径进行查找。
三、文件包含的优势与注意事项
(1)优势
- 模块化设计:通过文件包含,可以将程序划分为多个独立的模块,每个模块负责不同的功能,便于管理和维护。
- 代码重用:将常用的代码段放在头文件中,可以在多个源文件中重复使用,避免代码冗余。
- 易于调试和维护:当需要对某个功能进行修改时,只需修改相应的头文件即可,无需逐个修改包含该功能的源文件。
(2)注意事项
- 防止重复包含:为了避免同一个头文件被多次包含导致的编译错误,通常会在头文件中使用条件编译指令(如
#ifndef
,#define
,#endif
)来确保头文件只被包含一次。
- 路径问题:在使用双引号形式的
#include
指令时,需要注意指定正确的文件路径,否则会导致编译失败。
- 依赖关系:如果文件A包含了文件B,而文件B又依赖于文件C,那么在文件A中需要先包含文件C,再包含文件B,以确保依赖关系的正确性。
四、示例说明
假设有一个名为math_utils.h
的头文件,其中定义了几个数学运算的宏:
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))#endif // MATH_UTILS_H
然后,在一个源文件main.c
中,可以通过以下方式包含这个头文件并使用其中的宏:
// main.c
#include <stdio.h>
#include "math_utils.h"int main() {int x = 5, y = 10;printf("Max: %d
", MAX(x, y));printf("Min: %d
", MIN(x, y));return 0;
}
- 在这个例子中,
main.c
源文件通过#include "math_utils.h"
指令包含了math_utils.h
头文件,从而可以使用其中定义的MAX
和MIN
宏来进行数学运算。
综上所述:
- 文件包含是C语言预处理阶段的一个重要功能,它通过
#include
指令实现了代码的模块化和重用性,为开发者提供了极大的便利。
由于本文已经介绍很多了,所以小编在下一篇完结本节知识的介绍期待一下吧!!!!快乐的时光总是短暂,咱们下篇博文再见啦!!!不要忘了,给小编点点赞和收藏支持一下,在此非常感谢!!!
相关文章:
重生之我在异世界学编程之C语言:深入预处理篇(上)
大家好,这里是小编的博客频道 小编的博客:就爱学编程 很高兴在CSDN这个大家庭与大家相识,希望能在这里与大家共同进步,共同收获更好的自己!!! 本文目录 引言正文一、预处理的作用与流程…...
Java并发编程5--Java内存模型的基础
1.并发编程模型的两个关键问题 在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步(这里的线程是指并发执行的活动实体)。 通信是指线程之间以何种机制来交换信息。 在命令式编程中,线程之间的通…...
国密算法SM1、SM2、SM3和SM4 具体的使用和区别
国密算法是中国自主研发的密码算法,包括SM1、SM2、SM3和SM4,分别用于不同场景。以下是它们的具体使用和区别: SM1 对称加密算法 类型: 对称加密 密钥长度: 128位 使用场景: 用于数据加密和解密,适用于金融、政务等领域。 特点: …...
package.json的全面详解
在 Node.js 的世界里,package.json 文件占据着举足轻重的地位。它就像项目的“大脑”,掌控着项目的各种信息和依赖管理。下面,我们就深入剖析 package.json 文件,让你全面了解它的奥秘。 一、创建 package.json 在正式开始使用 …...
Linux、Docker与Redis核心知识点与常用命令速查手册
Linux、Docker与Redis核心知识点与常用命令速查手册 一、Linux基础核心 1. 核心概念 文件系统:采用树形结构,根目录为/权限机制:rwx(读/写/执行)权限,用户分为owner/group/others软件包管理: …...
通过TDE工业通讯网关解决设备通讯问题
设备通讯现状 在现代工业环境中,设备的通讯已成为提高生产效率和实现智能化管理的关键。随着工业4.0时代的到来,越来越多的智能设备被投入到生产运营中,这些设备通过集成特定的通信模块,形成了各自独立的自组网子系统。然而&…...
CI/CD(二)docker-compose安装Jenkins
1、docker-compose.yml version: 3.8services:jenkins:image: jenkins/jenkins:lts # 使用官方的 Jenkins LTS 镜像container_name: jenkinsuser: root # 如果需要以 root 用户运行ports:- "8080:8080" # Jenkins Web 界面端口- "50000:50000" # 用于 Jen…...
Linux操作系统3-文件与IO操作5(动态库与静态库的建立与加载)
上篇文章:Linux操作系统3-文件与IO操作4(软硬链接的建立与使用, 文件的三种时间)-CSDN博客 本篇代码Gitee仓库:myLerningCode/l21 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 本篇重点:动态库与静态库 目录 一. 静…...
同步异步日志系统-日志器的实现
该模块是针对于前几个模块的整合,也是直接面向客户所使用的,对于该模块的实现,我们基于:继承建造者设计模式来实现; 因此我们需要抽象出一个日志器抽象基类; 该基类提供的接口如下: 1、 debug();//站在用户的角度来说就是我只需要…...
webpack 项目优化(一)
一、构建速度优化 缩小文件处理范围 module: {rules: [{test: /\.js$/,exclude: /node_modules/, // 排除第三方库include: path.resolve(__dirname, src), // 限定处理范围use: babel-loader}] }利用缓存 Webpack 5 内置持久化缓存(直接配置)࿱…...
【撰写技巧】基金项目撰写跟踪交流会
基金申请书撰写完成后,提交前的审查是一个非常关键的步骤,这决定了你提交的材料是否符合要求,是否具备足够的说服力,以及是否能够通过专家评审。审查主要可以分为自我审查和团队审查两个层面。以下是基金申请书审查的主要内容和注…...
vue学习笔记
结合目录,点击阅读 文章目录 案例1:第一行vue代码App.vue引入Person.vue案例:改变变量的值案例:改变对象属性值案例:toRefs进行解包案例:给名字首字母大写案例:监视变量值的变化案例࿱…...
前端构建工具——Webpack和Vite的主要区别
目录 1. 设计理念2. 性能表现3. 使用场景4. 配置复杂度5. 生态系统6. 性能对比总结7. 选择建议 1. 设计理念 Webpack 设计理念:Webpack是一个通用的模块打包工具,它将项目中的各种资源(如JavaScript、CSS、图片等)视为模块&…...
Letsencrypt+certbot为域名免费配置ssl
1、基础概念 Let’s Encrypt 是一个提供免费 SSL/TLS 证书的认证机构,它的目标是让互联网上的通信更加安全,特别是普及 HTTPS。通过 Let’s Encrypt 提供的证书,网站可以使用加密连接,保护用户的数据传输。 Certbot 是一个由电子…...
达梦数据库针对慢SQL,收集统计信息清除执行计划缓存
前言:若遇到以下场景,大概率是SQL走错了执行计划: 1、一条SQL在页面上查询特别慢,但拿到数据库终端执行特别快 2、一条SQL在某种检索条件下查询特别慢,但拿到数据库终端执行特别快 此时,可以尝试按照下述步…...
IDEA通过Contince接入Deepseek
Deepseek 的出色表现,上期【Deepseek得两种访问方式与本地部署】 安装Continue插件 第一步、下载插件 在编辑栏【File】->设置【Settiings】或快捷键【CtrlAltS】,弹窗的左侧导航树,选择【plugins】,在marketplace 搜索【Continue】,点…...
Windows 10 ARM工控主板CAN总线实时性能测试
在常规的Windows系统中支持CAN总线应用,需要外接CAN总线适配器,通常为USB转CAN模块或PCI接口CAN卡。实时性本身是CAN总线的显著特性之一,但由于Windows并非实时操作系统,应用程序容易受到系统CPU负载影响,导致调度周期…...
深入理解无锁队列与C++原子操作
文章目录 深入理解无锁队列与C原子操作引言原子操作基础什么是原子操作?内存顺序(Memory Order) 无锁队列实现环形缓冲区队列(单生产者/单消费者)链表式无锁队列(多生产者/多消费者) 关键问题与…...
OpenGL: QOpenGLShaderProgram
一、QOpenGLShaderProgram 编译过程的封装 1、bool addShaderFromSourceCode(QGLShader::ShaderType type, const char * source); 2、bool addShaderFromSourceFile(QGLShader::ShaderType type, const QString & fileName); 3、virtual bool link(); 4、bool bind(); 5、…...
【网络编程】之数据链路层
【网络编程】之数据链路层 数据链路层基本介绍基本功能常见协议 以太网什么是以太网以太网协议帧格式数据链路层的以太网帧报文如何封装/解封装以及分用以太网通信原理传统的以太网与集线器现代以太网与交换机碰撞域的概念 Mac地址基本概念为什么要使用Mac地址而不是使用IP地址…...
HTTP 和 TCP/IP-傻傻分不清
HTTP 和 TCP/IP 是计算机网络中不同层次的协议,它们的核心区别在于功能和所属的网络层次。以下是详细对比: 1. 所属网络层次 TCP/IP 定位:TCP/IP 是一个协议族(包含多个协议),涵盖网络通信的传输层和网络层…...
【SQL】SQL约束
🎄约束 📢作用:是用于限制存储再表中的数据。可以再创建表/修改表时添加约束。 📢目的:保证数据库中数据的正确、有效性和完整性。 📢对于一个字段可以同时添加多个约束。 🎄常用约束: 约束分类 约束 描述关键字非…...
【ISO 14229-1:2023 UDS诊断(ECU复位0x11服务)测试用例CAPL代码全解析⑧】
ISO 14229-1:2023 UDS诊断【ECU复位0x11服务】_TestCase08 作者:车端域控测试工程师 更新日期:2025年02月17日 关键词:UDS诊断协议、ECU复位服务、0x11服务、ISO 14229-1:2023 TC11-008测试用例 用例ID测试场景验证要点参考条款预期结果TC…...
解决vue-awesome-swiper 4.x + swiper 5.x 分页pagination配置不生效问题
这次给的需求需要实现几个轮播图,我打算用swiper来做。刚开始我参照同事之前实现的swiper,复制到我的新页面中,是可用的。但是这次的需求需要有底下的分页pagination,而且因为版本比较老,比较难找到配置项。这里说一下…...
Spring Boot 开发入门
文章来源:开发您的第一个 Spring Boot 应用程序 (Developing Your First Spring Boot Application) _ Spring Boot3.4.0中文文档(官方文档中文翻译)|Spring 教程 —— CADN开发者文档中心 本节介绍如何开发一个小型的 “Hello World!” Web 应用程序&…...
MATLAB算法实战应用案例精讲-【数模应用】空间插值(附MATLAB、R语言和python代码实现)
目录 前言 算法原理 什么是插值? 为什么要插值? 常见插值方法 插值方法选择 GIS中常用的空间分析方法 一、空间插值 二、缓冲区分析 三、空间统计 四、领域分析 五、网络分析 六、多标准决策 插值分析 插值应用示例 空间插值的类型 不同工具箱中的空间插值工…...
碰一碰发视频@技术原理与实现开发步骤
碰一碰发视频系统:技术原理与实现方案解析 引言 近年来,随着移动支付和近场通信技术(NFC)的普及,“碰一碰”功能逐渐成为商家与用户交互的新入口。通过“碰一碰加盟”模式,企业可以快速赋能线下商户&…...
14.学成在线开发小结
1.统计两张表的数据,表1和表2是一对多的关系,如果既要统计表1又要统计表2的数据,要分开进行统计,否则表1一条数据在表2中可能有多条数据对应,导致表1的数据被多次统计。 2.nacos配置文件的数据读取不到可能原因有&…...
图像处理之CSC
CSC 是 Color Space Conversion(色彩空间转换)的缩写,它涉及图像处理中的亮度、饱和度、对比度和色度等参数的调整。这些参数是图像处理中的核心概念,通常用于描述和操作图像的颜色信息。 以下是亮度、饱和度、对比度和色度与 CS…...
数据结构:顺序表(Sequence List)及其实现
什么是顺序表? 顺序表是一种最简单的数据结构,它就像一排连续的小房子,每个房子里都住着一个数据元素。这些房子是按顺序排列的,每个房子都有一个门牌号(下标),我们可以通过门牌号快速找到对应…...
微信云开发小程序音频播放踩坑记录 - 从熄屏播放到iOS静音
在开发小程序冥想功能时,我们遇到了几个棘手的问题:用户反馈手机熄屏后音频停止、iOS设备播放没声音、冥想音频没有访问计数和CDN缓存优化等。本文将分享这些问题的解决过程和实践经验。 微信小程序简称:Moodo 微信小程序全程:AIMoodo心情日记系统 简…...
Python基础
https://www.w3schools.com/https://docs.python.org/3/ Python 介绍 Python是跨平台的,它可以运行在Windows、Mac和各种Linux/Unix系统上。在Windows上写Python程序,放到Linux上也是能够运行的。 要开始学习Python编程,首先就得把Python安装…...
基于Go语言 XTA AI聊天界面实现
项目开源地址: XTA-AI-SDK 人工智能技术的迅速发展,AI聊天应用变得越来越流行。本文将介绍如何使用Go语言和LCL库( Lazarus Component Library)创建一个功能丰富的AI聊天界面。项目主要包含以下模块: 项目背景 本项目旨在为开发…...
线上项目报错OOM常见原因、排查方式、解决方案
概述 OutOfMemoryError(OOM)是 Java 应用程序中常见的问题,通常是由于应用程序占用的内存超过了 JVM 分配的最大内存限制。在 Spring Boot 项目中,OOM 问题可能由多种原因引起。 1. OOM 的常见原因 OOM 通常由以下几种情况引起&…...
AI大模型零基础学习(6):多模态大模型实战——让AI看懂世界
从“文字交互”到“全感官认知”的维度突破 一、多模态大模型:AI的“五感觉醒” 1.1 基础概念重塑 单模态局限:传统大模型仅处理文本(如ChatGPT) 多模态进化: 输入:支持文本、图像、音频、视频、3D模型 …...
基于Spring Boot+Vue的宠物服务管理系统(源码+文档)
项目简介 宠物服务管理系统实现了以下功能: 基于Spring BootVue的宠物服务管理系统的主要使用者分为用户管理模块,由于系统运行在互联网络中,一些游客或者病毒恶意进行注册,产生大量的垃圾用户信息,管理员可以对这些…...
简要分析LeetCode树经典题目(Java)
目录 开场白 实战环节 准备工作 遍历问题 LeetCode144. 二叉树的前序遍历 方法一 方法二 LeetCode94. 二叉树的中序遍历 LeetCode145. 二叉树的后序遍历 方法一 方法二 LeetCode102. 二叉树的层序遍历 LeetCode103. 二叉树的锯齿形层序遍历 LeetCode107. 二叉树的…...
vue3开发打年兽功能
1.效果 WeChat_20250217192041 2.代码 2.1 index.vue <template><div class"pages"><TopNavigationYleftTitle"打年兽"ruleIconColor"#fff"backgroundImage""svgIpcn"backIcon4"gradientBackgroundColor&q…...
动手学Agent——Day2
文章目录 一、用 Llama-index 创建 Agent1. 测试模型2. 自定义一个接口类3. 使用 ReActAgent & FunctionTool 构建 Agent 二、数据库对话 Agent1. SQLite 数据库1.1 创建数据库 & 连接1.2 创建、插入、查询、更新、删除数据1.3 关闭连接建立数据库 2. ollama3. 配置对话…...
如何在 GitHub 中创建一个空目录 ?
GitHub 是开发人员必不可少的工具,它提供了存储、共享和协作代码的平台。一个常见的问题是如何在 GitHub 存储库中创建一个空目录或文件夹。GitHub 不支持直接创建空目录。但是,有一种解决方法是使用一个虚拟文件,通常是一个 .gitkeep 文件。…...
3. 导入官方dashboard
官方dashboard:https://grafana.com/grafana/dashboards 1. 点击仪表板 - 新建 - 导入 注:有网络的情况想可以使用ID,无网络情况下使用仪表板josn文件 2. 在官方dashboard网页上选择符合你现在数据源的dashboard - 点击进入 3. 下拉网页选…...
前端知识速记--HTML篇:HTML5的新特性
前端知识速记–HTML篇:HTML5的新特性 一、语义化标签 HTML5引入了许多新的语义化标签,如 <header>、<footer>、<article>、<section> 等。这些标签不仅提高了网页的可读性和结构性,还有助于SEO(搜索引擎…...
【数据分享】1929-2024年全球站点的逐年降雪深度数据(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 有关气象指标的监测站点数据,之前我们分享过1929-2024年全球气象站…...
鸿蒙面试题
1.0penHarmony的系统架构是怎样的? 2.电话服务的框架? 3.OpenHarmony与HarmonyOS有啥区别?...
pdf-extract-kit paddle paddleocr pdf2markdown.py(效果不佳)
GitHub - opendatalab/PDF-Extract-Kit: A Comprehensive Toolkit for High-Quality PDF Content Extraction https://github.com/opendatalab/PDF-Extract-Kit pdf2markdown.py 运行遇到的问题: 错误: -------------------------------------- C Tra…...
基于STM32、HAL库、RX8025T(I2C接口)驱动程序设计
一、简介: RX8025T 是一款低功耗、高精度的实时时钟芯片,具有以下特性: I2C 接口通信 内置 32.768 kHz 晶振 提供秒、分、时、日、月、年等时间信息 支持温度补偿,提高时间精度 低功耗设计,适合电池供电的应用 二、I2C初始化: #include "stm32l4xx_hal.h&…...
基于Ubuntu+vLLM+NVIDIA T4高效部署DeepSeek大模型实战指南
一、 前言:拥抱vLLM与T4显卡的强强联合 在探索人工智能的道路上,如何高效地部署和运行大型语言模型(LLMs)一直是一个核心挑战。尤其是当我们面对资源有限的环境时,这个问题变得更加突出。原始的DeepSeek-R1-32B模型虽…...
【Go语言快速上手】第二部分:Go语言进阶之并发编程
文章目录 一、并发编程1. goroutine:创建和调度 goroutine2. channel:无缓冲 channel、有缓冲 channel、select 语句2.1 无缓冲 channel2.2 有缓冲 channel2.3 select 语句 3. sync 包:Mutex、RWMutex、WaitGroup 等同步原语3.1 Mutex&#x…...
《机器学习数学基础》补充资料:四元数、点积和叉积
《机器学习数学基础》第1章1.4节介绍了内积、点积的有关概念,特别辨析了内积空间、欧几里得空间;第4章4.1.1节介绍了叉积的有关概念;4.1.2节介绍了张量积(也称外积)的概念。 以上这些内容,在不同资料中&…...
蓝桥杯篇---IAP15F2K61S2矩阵键盘
文章目录 前言简介矩阵键盘的工作原理1.行扫描2.检测列状态3.按键识别 硬件连接1.行线2.列线 矩阵键盘使用步骤1.初始化IO口2.扫描键盘3.消抖处理4.按键识别 示例代码:4x4矩阵键盘扫描示例代码:优化后的矩阵键盘扫描注意事项1.消抖处理2.扫描频率3.IO口配…...