023-C语言预处理详解
C语言预处理详解
文章目录
- C语言预处理详解
- 1. 预定义符号
- 2. #define定义常量
- 3. #define定义宏
- 4. 带有副作用的宏参数
- 5. 宏替换的规则
- 6. 宏函数的对比
- 7. #和##
- 7.1 #运算符
- 7.2 ##运算符
- 8. 命名约定
- 9. #undef
- 10. 命令行定义
- 11. 条件编译
- 12. 头文件包含
- 12.1 头文件被包含方式
- 12.1.1 本地文件被包含方式
- 12.1.2 库文件包含
- 12.2 嵌套文件包含
- 13. 其他预处理指令
- 13.1 #error
- 13.2 #line
- 13. 其他预处理指令
- 13.1 #error
- 13.2 #line
1. 预定义符号
C语言设置了一些预定义符号,可以直接使用,预定义符号也是在预处理期间处理的。
__FILE__ // 进行编译的源文件
__LINE__ // 文件当前的行号
__DATE__ // 文件被编译的日期
__TIME__ // 文件被编译的时间
__STDC__ // 如果编译器遵循ANSI C,其值为1,否则未定义。
2. #define定义常量
基本语法:
#define name stuff
如果使用#define,在预处理阶段时,代码中所有的name将会被替换为stuff。
注意,这一句的最后不需要加;
,如果加上;
,;
也会被替换进代码。
举例:
#define MAX 1000
#define reg register
#define do_forever for(;;)
#define CASE break;case// 如果定义的stuff过长,可以分成几行写,除了最后一行外,每行的最后丢加上一个续行符(反斜杠\)
#define DEBUG_DRINT printf("file:%s\tline:%d\t\date:%s\ttime:%s\n,\__FILE__,__LINE__\__DATE__,__TIME__")
3. #define定义宏
#define机制包括了一个规定,运行把参数替换到文本中,这种实现通常称为宏(macro)或定义宏(define macro)。
下面是宏的声明方式:
#define name( parament-list ) stuff
其中的parament-list
是一个有逗号隔开的符号表,它们可能出现在stuff中。
注意:参数列表发左括号必须于name紧邻,如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分。
举例:
#define SQUARE(x) x * x
这个宏接收一个参数x
,在上述声明后,如果将SQUARE(5);
置于程序中,预处理器就会用下面这个表达式替换上面的表达式:5 * 5
;
使用宏时,最好多使用括号,否则会出现一些问题:
int a = 5;
printf("%d\n", SQUARE(a + 1));
这里我们想要的结果应该是36,但实际上它将打印为11。
在使用宏时,替换过程中,它并不会将传入的表达式先进行运算再替换,而是直接替换,所以实际上上面的代码被替换成了:
printf("%d\n", a + 1 * a + 1);
想要解决这个问题,我们只需要在宏定义时多加上一些括号就行了。
#define SQUARE(x) ((x) * (x))
4. 带有副作用的宏参数
上面说过,当宏函数在进行替换时是直接替换,那么如果传入的参数为x,而宏函数中出现了x++,将会导致传入的参数x在执行完宏函数后发生变化。
同样的,如果传入的参数出现类似x++的表达式,并且宏函数中不止一次使用该参数,且我们不知道该宏内部情况,那么将导致不可预测的后果。这就是带有副作用的宏参数。
所以我们在定义和使用宏函数时,应该尽量避免使用类似上述的表达。
5. 宏替换的规则
在程序中扩展#define定义符号和宏时,需要涉及几个步骤。
- 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。
- 替换文本随后被插入到程序中原来的文本的位置。对于宏,参数名被他们的值所替换。
- 最后再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。
注意:
- 宏参数和#define定义中可以出现其他#define定义的符号。但是对应宏,不能出现递归。
- 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
6. 宏函数的对比
宏通常被应用于执行简单的运算。
比如在两个数中找出较大的一个时,写成下面的宏,更有优势一些。
#define MAX(a, b) ((a) > (b) ? (a) : (b))
那么为什么不使用函数完成这个任务:
- 由于调用函数和从函数返回的代码可能比实际执行这个小型计算工作需要的时间更多。所以宏函数在程序的规模和速度方面更胜一筹。
- 更为重要的是函数的参数必须声明为特定的类型。所以函数只能在类型合适的表达式上使用。反之这个宏可以让整型、长整型、浮点型等直接使用
>
等来直接比较,宏是类型无关的。
和函数相比宏的劣势:
1. 每次使用宏时,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅增加程序的长度。
1. 宏没法进行调试。
1. 宏类型无关,不够严谨。
1. 宏可能会带来运算符优先级的问题,导致程序容易出错。
宏有时候可以做函数做不到的事。比如:宏的参数可以出现类型,但函数做不到。
#define MALLOC(num, type) (type*)malloc((num) * sizeof(type))
宏和函数的对比:
属性 | #define定义宏 | 函数 |
---|---|---|
代码长度 | 每次使用都会将宏代码插入到程序中。除了使用很小的宏之外,程序的长度会大幅增长。 | 函数代码只出现在一个地方,每次调用函数时,都调用同一份代码。 |
执行速度 | 更快。 | 存在函数调用和返回的额外开销,会慢一些。 |
操作符优先级 | 宏参数的求值是在所有周围表达式的上下文环境里,除非加上括号,否则邻近操作符的优先级可能会产生不可预料的后果。 | 函数参数在函数调用时求值,将结果值传递给函数。 |
带有副作用的参数 | 参数可能被替换到宏体中的多个内置,如果宏的参数被多次计算,带有副作用的参数求值可能会产生不可预料的后果。 | 函数参数只在传参的时候求值一次,易控制。 |
参数类型 | 宏的蚕食与类型无关,只要对参数的操作是合法的, | 函数的参数是与类型有关的,如参数类型不同,就需要使用不同的函数。 |
调试 | 宏是不方便调试的 | 函数是可以逐语句调试的 |
递归 | 宏是不能递归的 | 函数是可以递归的 |
7. #和##
7.1 #运算符
#运算符将宏的⼀个参数转换为字符串字面量。它仅允许出现在带参数的宏的替换列表中。
#运算符所执行的操作可以理解为“字符串化”。
当我们有一个变量 int a = 10;
的时候,我们想打印出: the value of a is 10
。
#define PRINT(n) printf("the value of "#n" is %d", n);
7.2 ##运算符
##
可以把它两边的符号变成一个符号,##
被称为记号粘合剂。
这样的连接必须产生合法的标识符,否则其结果就是未定义的。
当我们想要写一个函数求两个数的最大值时,不同的数据类型就要写不同的函数。
int int_max(int x, int y)
{return x > y ? x : y;
}float float_max(float x, float y)
{return x > y ? x : y ;
}
但如果使用##
,就只需要写一份。
#define GENERIC_MAX(type) \
type type##_max(type x, type y)\
{ \
return (x>y?x:y); \
}
使用宏定义不同函数。
GENERIC_MAX(int) //替换到宏体内后int##_max ⽣成了新的符号 int_max做函数名
GENERIC_MAX(float) //替换到宏体内后float##_max ⽣成了新的符号 float_max做函数名int main()
{//调⽤函数int m = int_max(2, 3);printf("%d\n", m);float fm = float_max(3.5f, 4.5f);printf("%f\n", fm);return 0;
}
8. 命名约定
- 宏名全部大写
- 函数名不要全部大写
9. #undef
用于移除一个宏定义。
#undef NAME
//如果现存的⼀个名字需要被重新定义,那么它的旧名字⾸先要被移除。
10. 命令行定义
许多编译器提供了一种能力,允许在命令行中定义符号。如果我们想要一个程序在不同情况下定义不同大小的数组:
#include <stdio.h>int main()
{int array [ARRAY_SIZE];int i = 0;for(i = 0; i< ARRAY_SIZE; i ++){array[i] = i;}for(i = 0; i< ARRAY_SIZE; i ++){printf("%d " ,array[i]);}printf("\n" );return 0;
}
编译指令:
//linux 环境演⽰
gcc -D ARRAY_SIZE=10 programe.c
11. 条件编译
在编译一个程序的过程中,我们可能需要制作不同的版本,有些版本可能要舍弃一些功能,这是我们就可以使用条件编译指令。
比如调试性的代码,删除了,以后万一要调整代码的功能可能还得重新写,保留了又影响程序的运行效率,这时我们就可以选择性的编译。
1. 一个分支语句的条件编译
语法结构:
#if 常量表达式
...(需要条件编译的代码)
#endif
在#if后写常量表达式,如果苍凉表达式为真,则编译#if和#endif之间的内容,否则不编译该内容。使用如下:
#include <stdio.h>#define __DEBUG__ 1int main()
{
#if __DEBUG__ == 1printf("1");
#endifprintf("2");return 0;
}
在上面我们定义了一个__BEDUG__宏,我们可以修改这个宏的内容来实现条件编译:
- 当把__BEDUG__定义为1时,条件满足,将会编译
printf("1");
- 当__BEDUG__为其他值时,条件不满足,将不会编译
printf("1");
printf("2");
在#if和#endif之外,它的编译将不会受条件编译的影响。
2. 多个分支语句的条件编译
条件编译类似于if…else…语句,也可以又多个分支的条件编译,语法格式如下:
#if 常量表达式...
#elif 常量表达式...
#elif 常量表达式...
#else...
#endif
其中,#elif可以有任意多个,#else可以没有,具体使用如下:
#include <stdio.h>#define __DEBUG__ 6int main()
{
#if __DEBUG__ == 1printf("1");
#elif __DEBUG__ == 2printf("2");
#elif __DEBUG__ == 3printf("3");
#elseprintf("4");
#endifprintf("5");return 0;
}
- 当__BEDUG__为1时
printf("1");
将会被编译被定义为对应内容时,相应的语句才会被编译,如__BEDUG__为1时printf("1");
将会被编译,__BEDUG__为2时printf("2");
将会被编译。- 当__BEDUG__的值不满足任何#if或#elif的条件时,将会编译#else后的内容。
3. 判断某个宏是否被定义
我们也可以通过判断某个宏是否被定义来决定是否进行条件编译。
语法结构:
#if defined(宏名)...
#endif#ifdef 宏名...
#endif-----------------------------------------------#if !defined(宏名)...
#endif#ifndef 宏名...
#endif
上面的结构中,上两种结构在宏被定义时,将会编译相应的代码,下两种结构在宏没被定义时,将会编译相应的代码。
#include <stdio.h>#define __DEBUG__int main()
{
#if defined(__DEBUG__)printf("1");
#endif#ifdef __DEBUG__printf("2");
#endif#if !defined(__DEBUG__)printf("3");
#endif#ifndef __DEBUG__printf("4");
#endifprintf("5");return 0;
}
4. 嵌套编译
条件编译也支持嵌套使用。
#include <stdio.h>#define TEST1
#define TEST2 1int main()
{
#if defined(TEST1)#if TEST2 == 1printf("1");#endifprintf("2");
#endifreturn 0;
}
12. 头文件包含
12.1 头文件被包含方式
12.1.1 本地文件被包含方式
#include "filename"
本地文件我们使用双引号引起来,此时,编译时先会在源文件的目录下进行查找,如果没有找到,就到标准库的头文件目录里面去查找,如果还找不到就会编译错误。
Linux环境下标准头文件的路径:
/usr/include
VS2022环境下标准头文件路径
D:\Software\VS2022\MicrosoftVisualStudio\2022\Community\VC\Tools\MSVC\14.41.34120\include
// 按照自己安装的路径去找
12.1.2 库文件包含
#include <filename>
库文件使用尖括号括起来即可,被尖括号括起来的文件,编译时会直接在标准库的头文件目录中查找。
根据上面的查找规则,库文件也可以使用双引号,但是查找的效率会低些。
12.2 嵌套文件包含
当我们包含头文件时,可能会包含多个重复的头文件,并不一定是在同一个文件中一起包含的,有可能是我们在文件1中包含了stdio.h,在文件2中也包含了stdio.h,同时文件1又包含了文件2,此时就会造成文件的重复包含,重复包含文件会导致一些错误。
这时我们可以使用条件编译来解决:
#ifndef __TEST_H__
#define __TEST_H__
// 包含头文件
#endif
我们只需要在包含每个头文件前都加上这个内容就可以解决。
但是这用起来太繁琐了,我们还有更简单的办法可以解决这个问题:
#pragma once
我们只需要在包含头文件前加上这一条指令,就可以避免头文件的重复引入。
13. 其他预处理指令
13.1 #error
作用:强制中断编译并输出错误信息
#error "错误信息"
13.2 #line
作用:从该行开始,修改编译器报告的行号和文件名。
#line 100 "newfile.c"
件,并不一定是在同一个文件中一起包含的,有可能是我们在文件1中包含了stdio.h,在文件2中也包含了stdio.h,同时文件1又包含了文件2,此时就会造成文件的重复包含,重复包含文件会导致一些错误。
这时我们可以使用条件编译来解决:
#ifndef __TEST_H__
#define __TEST_H__
// 包含头文件
#endif
我们只需要在包含每个头文件前都加上这个内容就可以解决。
但是这用起来太繁琐了,我们还有更简单的办法可以解决这个问题:
#pragma once
我们只需要在包含头文件前加上这一条指令,就可以避免头文件的重复引入。
13. 其他预处理指令
13.1 #error
作用:强制中断编译并输出错误信息
#error "错误信息"
13.2 #line
作用:从该行开始,修改编译器报告的行号和文件名。
#line 100 "newfile.c"
相关文章:
023-C语言预处理详解
C语言预处理详解 文章目录 C语言预处理详解1. 预定义符号2. #define定义常量3. #define定义宏4. 带有副作用的宏参数5. 宏替换的规则6. 宏函数的对比7. #和##7.1 #运算符7.2 ##运算符 8. 命名约定9. #undef10. 命令行定义11. 条件编译12. 头文件包含12.1 头文件被包含方式12.1.…...
C#自定义控件-实现了一个支持平移、缩放、双击重置的图像显示控件
1. 控件概述 这是一个继承自 Control 的自定义控件,主要用于图像的显示和交互操作,具有以下核心功能: 图像显示与缩放(支持鼠标滚轮缩放)图像平移(支持鼠标拖拽)视图重置(双击重置…...
MarkitDown:AI时代的文档转换利器
在当今AI快速发展的时代,如何高效地将各种格式的文档转换为机器可读的格式,成为了一个迫切需要解决的问题。今天,我们来介绍一款由微软开发的强大工具——MarkitDown,它正是为解决这一问题而生的。 什么是MarkitDown? MarkitDown是一个用Python编写的轻量级工具,专门用…...
《数字分身进化论:React Native与Flutter如何打造沉浸式虚拟形象编辑》
React Native,依托JavaScript语言,借助其成熟的React生态系统,开发者能够快速上手,将前端开发的经验巧妙运用到移动应用开发中。它通过JavaScript桥接机制调用原生组件,实现与iOS和Android系统的深度交互,这…...
DeerFlow:字节新一代 DeepSearch 框架
项目地址:https://github.com/bytedance/deer-flow/ 【全新的 Multi-Agent 架构设计】独家设计的 Research Team 机制,支持多轮对话、多轮决策和多轮任务执行。与 LangChain 原版 Supervisor 相比,显著减少 Tokens 消耗和 API 调用次数&#…...
数字孪生工厂实战指南:基于Unreal Engine/Omniverse的虚实同步系统开发
引言:工业元宇宙的基石技术 在智能制造2025与工业元宇宙的交汇点,数字孪生技术正重塑传统制造业。本文将手把手指导您构建基于Unreal Engine 5.4与NVIDIA Omniverse的实时数字孪生工厂系统,集成Kafka实现毫秒级虚实同步,最终交付…...
牛客网NC22015:最大值和最小值
牛客网NC22015:最大值和最小值 题目描述 题目要求 输入:一行,包含三个整数 a, b, c (1≤a,b,c≤1000000) 输出:两行,第一行输出最大数,第二行输出最小数。 样例输入: …...
Uniapp中小程序调用腾讯地图(获取定位地址)
1、先配置权限: 这是上图的代码: "permission": { "scope.userLocation": { "desc": "你的位置信息将用于小程序位置接口的效果展示" } } 第二步:写代码: //下面是uniapp的模版代码 主…...
2025 后端自学UNIAPP【项目实战:旅游项目】5、个人中心页面:微信登录,同意授权,获取用户信息
一、框架以及准备工作 1、前端项目文件结构展示 2、后端项目文件结构展示 3、登录微信公众平台,注册一个个人的程序,获取大appid(前端后端都需要)和密钥(后端需要) 微信公众平台微信公众平台&…...
隆重推荐(Android 和 iOS)UI 自动化工具—Maestro
文章目录 前言一、为什么选择 Maestro?二、使用步骤1.安装(Windows)2.运行示例 三、Maestro Studio (重点)轻松编辑测试 四、价格总结 前言 当前移动 UI 自动化工具的实际效能与预期存在显著差距,团队推行…...
C#发送文件到蓝牙设备
测试环境: visual studio 2022 win11笔记本电脑,具有蓝牙功能 .net6控制台 测试步骤如下: 1 新增名为BluetoothDemo控制台项目 2 通过nuget安装InTheHand.Net.Bluetooth,版本选择4.2.1和安装InTheHand.Net.Obex,版…...
采用sherpa-onnx 实现 ios语音唤起的调研
背景 项目中需要实现一个语音唤起的功能,选择sherpa-onnx进行调研,要求各端都要验证没有问题。个人负责ios这部分的调研。查询官方发现没有直接针对ios语音唤起的稳定,主要技术平台也没有相关的可以借鉴。经过调研之后补充了一个。 一、下载…...
磁盘I/O瓶颈排查:面试通关“三部曲”心法
想象一下,你就是线上系统的“交通调度总指挥”,服务器的磁盘是所有数据进出的“核心枢纽港口”。当这个“港口”突然拥堵不堪,卡车(数据请求)排起长龙,进不去也出不来,整个系统的“物流”&#…...
磁盘性能测试与分析:结合fio和iostat的完整方案
磁盘性能测试与分析:结合fio和iostat的完整方案 磁盘性能是影响现代计算机系统整体运行效率的关键因素之一,特别是对于高I/O负载的应用如数据库、虚拟化环境等。本文将详细介绍如何利用fio和iostat工具全面评估磁盘性能,包括IOPS、带宽、延迟…...
随机森林(Random Forest)
随机森林(Random Forest)是一种基于决策树的集成学习算法,它通过构建多个决策树并将它们的预测结果进行综合,从而提高模型的准确性和稳定性。 1.基本原理 随机森林属于集成学习中的“Bagging”方法。其核心思想是通过构建多个决…...
C#数据类型
🧩 一、布尔值(bool) 表示逻辑值:true 或 false bool isTrue true; bool isFalse false;📌 二、整数(Integer Types) C# 支持多种有符号和无符号整数类型: 类型大小范围sbyte8…...
FastAPI 实现 Express 框架的 p-limit(1) 防并发操作
背景 以下是将 Electron 主进程中的 CURD 逻辑(Express 实现)迁移到 FastAPI 的完整方案,包含技术选型、实现步骤和注意事项,确保主进程与子进程解耦且稳定运行: 关键点 注意用 conda 安装 python 版本时,…...
STC8H系列单片机STC8H_H头文件功能注释
#ifndef __STC8H_H__ // 条件编译:如果未定义__STC8H_H__宏 #define __STC8H_H__ // 则定义该宏,防止头文件被重复包含 / //包含本头文件后,不用另外再包含"REG51.H" // 提示:本头文件已包含基本寄存器定义 sfr P0 = …...
C#中BackgroundWorker的概念与用法详解
一、BackgroundWorker 概念 BackgroundWorker 是 C# 中用于在后台线程中运行操作的组件,它允许你在不影响用户界面(UI)响应能力的情况下执行耗时操作。 它位于 System.ComponentModel 命名空间内,主要用于 Windows 窗体应用程序中…...
RM算法的地下宫殿
证: X n 1 X n β n ( ξ n − X n ) ( 1 − β n ) X n β n ξ n X_{n1}X_n\beta_n(\xi_n-X_n)(1-\beta_n)X_n\beta_n\xi_n Xn1Xnβn(ξn−Xn)(1−βn)Xnβnξn。由数学归纳法可得 X n 1 ∑ j 1 n ξ j β j ∏ i j n − 1 ( 1 − β…...
WEB安全--Java安全--LazyMap_CC1利用链
一、前言 该篇是基于WEB安全--Java安全--CC1利用链-CSDN博客的补充,上篇文章利用的是TransformedMap类,而CC链的原作者是利用的LazyMap类作为介质进行的触发。 所以本文将分析国外原作者在ysoserial commonscollections1中给出的CC1利用链。 二、回顾梳…...
【Matlab】最新版2025a发布,深色模式、Copilot编程助手上线!
文章目录 一、软件安装1.1 系统配置要求1.2 安装 二、新版功能探索2.1 界面图标和深色主题2.2 MATLAB Copilot AI助手2.3 绘图区升级2.4 simulink2.5 更多 延迟一个月,终于发布了🤭。 一、软件安装 1.1 系统配置要求 现在的电脑都没问题,老…...
[网络升级指南] 服务器网卡/带宽如何选?1GbE vs 10GbE vs 25GbE+ 性能与成本深度解析 (2025)
更多服务器知识,尽在hostol.com 嘿,各位服务器“舰长”们!当你为你的“星际飞船”(服务器)配备了顶级的 CPU“引擎”、超大的内存“能源核心”、以及光速 SSD“曲速引擎”之后,是不是觉得它就能在数字宇宙…...
Nginx与Tomcat负载均衡集群配置指南
目录 一、资源清单 二、基础环境 三、安装配置Tomcat 四、安装配置Nginx 一、资源清单 主机 操作系统 IP地址 tomcat1 OpenEuler24.03 192.168.16.142 tomcat2 OpenEuler24.03 192.168.16.143 Nginx OpenEuler24.03 192.168.16.144 二、基础环境 hostnamectl …...
已解决(亲测有效!):安装部署Docker Deskpot之后启动出现Docker Engine Stopped!
文章目录 已解决:安装部署Docker Deskpot之后启动出现Docker Engine Stopped!个人环境介绍自己的解决问题思路(详细过程附截图)1.打开控制面板2.点击程序和功能3.点击启动或关闭windows功能4.Hyper-V5.右键菜单栏的windows图标点击…...
C++多态实现的必要条件剖析
在C中,多态的一个必要条件确实是通过基类的指针或引用调用虚函数。这一要求背后的原因与C如何实现动态绑定(运行时多态)密切相关。下面详细解释了为什么需要使用基类的指针或引用来实现多态。 动态绑定与静态绑定 静态绑定(编译期…...
25.5.15
没有比水题更令人开心的事情了 典型的并查集题目,并查集分为并和查,并就是把有关系的父亲根结点设为同一个,查就是在成功构造后对其进行查询 查通过递归实现 if (x f[x])return x; return f[x] find(f[x]); 由于并查集的特点࿰…...
WebSocket:实时通信(如聊天应用)从零到一的深度解析
简介 在现代互联网应用中,实时通信已成为不可或缺的核心功能。从在线聊天到金融数据监控,从协同办公到在线游戏,实时性需求推动了WebSocket技术的广泛应用。本文将从底层协议原理出发,结合企业级开发场景,系统讲解WebSocket的实现机制、实战技巧与优化策略。通过完整的代…...
二程运输的干散货船路径优化
在二程运输中,干散货船需要将货物从一个港口运输到多个不同的目的地港口。路径优化的目标是在满足货物运输需求、船舶航行限制等条件下,确定船舶的最佳航行路线,以最小化运输成本、运输时间或其他相关的优化目标。 影响因素 港口布局与距离:各个港口之间的地理位置和距离…...
【Java ee初阶】http(1)
HTTP 全称为“超文本传输协议”,由名字可知,这是一个基于文本格式的协议,而TCP,UDP,以太网,IP...都是基于二进制格式的协议。 如何区别该协议是基于哪种格式的协议? 形如这种协议格式…...
《Deepseek从入门到精通》清华大学中文pdf完整版
资源介绍: 《DeepSeek:从入门到精通》是由清华大学新闻与传播学院新媒体研究中心元宇宙文化实验室的精心撰写的一份专业文档。该文档以通俗易懂的方 式,全面介绍了DeepSeek的使用方法,为用户提供了极具价值的指导。 这份文档内容丰…...
【图片识别工具】批量单据识别批量重命名,批量OCR识别图片文字并重命名,批量改名工具的使用步骤和注意事项
一、适用场景 财务与发票管理:企业需处理大量电子发票或扫描件,通过OCR识别发票代码、金额等关键信息,自动重命名为发票号_金额.pdf格式,便于归档与税务审计。 物流单据处理:物流公司需从运单中提取单…...
重磅发布!OpenAI 推出最新模型 GPT-4.1 系列!
今日凌晨,OpenAI宣布开放全新模型GPT-4.1,并于即日起在ChatGPT中投入使用。 超长上下文与卓越编码能力 GPT-4.1作为OpenAI的最新模型,支持长达100万tokens的上下文,是OpenAI首次发布的长窗口模型。相较于前代,GPT-4.1…...
游戏引擎学习第281天:在房间之间为摄像机添加动画效果
回顾并为今天的内容定下基调 这次我们要继续深入处理实体系统。在前一阶段对实体系统做了一些很酷的改动,但现在到了要认真面对和完善它的时候。 今天的主要目标是修复并优化摄像机在房间之间移动时的逻辑。在上一次的实现中,我们重新启用了基于房间的…...
机器学习 --- 模型选择与调优
机器学习 — 模型选择与调优 文章目录 机器学习 --- 模型选择与调优一,交叉验证1.1 保留交叉验证HoldOut1.2 K-折交叉验证(K-fold)1.3 分层k-折交叉验证Stratified k-fold 二,超参数搜索三,鸢尾花数据集示例四,现实世界数据集示例…...
PostgreSQL pgrowlocks 扩展详解
一、简介 pgrowlocks 是 PostgreSQL 官方提供的扩展模块,用于查看指定表中每一行当前的行级锁(Row Lock)信息。它非常适用于: 并发冲突排查行级锁等待分析死锁前兆探测热点数据行分析 二、安装与启用 1. 安装前提(…...
Makefile 详解
Makefile 是一个用于自动化构建过程的脚本文件,主要用于管理源代码的编译和链接过程。它定义了项目中的依赖关系以及如何从源文件生成目标文件。 基本概念 Make:一个构建自动化工具,读取 Makefile 中的指令目标(Target):要生成的…...
IntelliJ IDEA 集成AI编程助手全解析:从Copilot到GPT-4o Mini的实践
目录 AI编程助手的演进与核心价值GitHub Copilot深度集成指南国产新星DeepSeek配置实战GPT-4o Mini低成本接入方案三大助手对比与场景适配企业级安全与本地化部署未来发展趋势与开发者启示1. AI编程助手的演进与核心价值 1.1 技术演进图谱 #mermaid-svg-LwYPrW2Y2Pqvqgf0 {fon…...
wps excel将表格输出pdf时所有列在一张纸上
记录:wps excel将表格输出pdf时所有列在一张纸上 1,调整缩放比例 2,将表格的所有铺满到这套虚线...
【开源Agent框架】OWL:面向现实任务自动化的多智能体协作框架深度解析
一、基本介绍 1.1 项目概述 OWL(Optimized Workforce Learning)是基于CAMEL-AI框架构建的创新型多智能体协作系统,旨在通过动态智能体交互实现复杂任务的自动化处理。项目在GAIA基准测试中以69.09的平均分位列开源框架榜首,展现了强大的任务处理能力。 技术特性矩阵: 多…...
120页WORD方案 | 2025企业数字化转型AI大模型数字底座项目设计方案
这份文档是一份关于企业数字化转型AI大模型数字底座项目的设计方案,涵盖了从项目概述、业务需求分析到技术架构设计等多个方面。它详细阐述了企业为何需要构建AI大模型底座,以及如何通过这一底座实现智能化决策支持、业务流程优化和客户体验提升。方案中…...
Vue3 本地环境 Vite 与生产环境 Nginx 反向代理配置方法汇总【反向代理篇】
文章目录 一、前言二、问题场景三、开发环境配置(Vite)四、生产环境配置(Nginx)4.1 初始错误配置4.2 正确配置方案4.3 配置解析4.4高级配置选项 五、常见问题排查六、开发环境 vs 生产环境对比七、总结 一、前言 在前后端分离架构…...
机器视觉对位手机中框点胶的应用
在手机制造的精密世界里,每一个环节都关乎着产品的最终品质,而手机中框点胶工艺更是其中关键一环。点胶不仅起到固定内部组件、增强结构强度的作用,还影响着手机的防水、防尘性能。然而,随着手机设计日益轻薄化、复杂化࿰…...
Elasticsearch性能调优全攻略:从日志分析到集群优化
#作者:猎人 文章目录 前言搜索慢查询日志索引慢写入日志性能调优之基本优化建议性能调优之索引写入性能优化提升es集群写入性能方法:性能调优之集群读性能优化性能调优之搜索性能优化性能调优之GC优化性能调优之路由优化性能调优之分片优化 前言 es里面…...
Electron 主进程中使用Worker来创建不同间隔的定时器实现过程
背景 目前主进程使用 timer.setInterval 来做间隔任务执行,但是总有用户反馈养号卡主不执行了,或者某个操作不执行了,为了排除主进程的运行造成 setInterval 阻塞可能,将 setInterval 单独处理,可以排除主进程对定时器…...
用户安全架构设计
一、主动踢出,被动踢出 二、密码设计策略:密码复杂度,密码安全检查,密码失效设计,账号锁定设计,密码存储和传输加密 三、密码找回策略:密保问题,下行短信验证码,上行短信…...
2025年黑客扫段攻击激增:如何构建智能防御体系保障业务安全?
引言 2025年,随着全球物联网设备突破500亿台,黑客利用自动化工具发起的扫段攻击(IP段扫描漏洞利用)已成为企业业务安全的最大威胁之一。单次攻击可覆盖数万个IP,精准定位未修复漏洞,导致数据泄露、服务瘫痪…...
基于大模型预测胃穿孔预测与围手术期管理系统技术方案
目录 1. 系统架构模块2. 关键算法实现2.1 术前预测模型(Transformer多模态融合)2.2 术中实时分析(在线学习LSTM)3. 模块流程图(Mermaid)3.1 数据预处理系统3.2 术前预测系统3.3 术中实时分析系统4. 技术验证模块4.1 模型可解释性验证4.2 边缘计算部署架构1. 系统架构模块…...
Java转Go日记(三十六):简单的分布式
1.1.1. 简单的分布式server 目前分布式系统已经很流行了,一些开源框架也被广泛应用,如dubbo、Motan等。对于一个分布式服务,最基本的一项功能就是服务的注册和发现,而利用zk的EPHEMERAL节点则可以很方便的实现该功能。EPHEMERAL节…...
操作系统-进程与线程
操作系统 操作系统用来保护系统资源和提高稳定性的重要机制 文章目录 用户态和内核态为什么要区分状态? 进程管理进程,线程进程/线程切换进程的5种状态进程通信线程通讯进程调度算法 用户态和内核态 用户态 应用程序运行时所在的模式,权限受限…...