笔记五:C语言编译链接
Faye:孤独让我们与我们所爱的人相处的每个瞬间都无比珍贵,让我们的回忆价值千金。它还驱使你去寻找那些你在我身边找不到的东西。
---------《寻找天堂》
目录
一、编译和链接的介绍
1.1 程序的翻译环境和执行环境
1.1.1 翻译环境
1.1.2 运行环境
1.2 预处理
1.2.1 预定义符号
1.2.2 #define
#define的语法:
#define 替换规则:
#和##
带副作用的宏参数
编辑 宏和函数对比
#undef
1.3 编译
1.3.1 词法分析
1.3.2 语法分析
1.3.3 语义分析
1.4 汇编
1.5 链接
一、编译和链接的介绍
1.1 程序的翻译环境和执行环境
在ANSI C的任何一种实现中,存在两个不同的环境。
第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。
第2种是执行环境,它用于实际执行代码。
注:ANSI C是由美国国家标准协会(ANSI)及国际标准化组织(ISO)推出的关于C语言的标准。ANSI C 主要标准化了现存的实现, 同时增加了一些来自 C++ 的内容 (主要是函数原型) 并支持多国字符集 (包括备受争议的三字符序列)。 ANSI C 标准同时规定了 C 运行期库例程的标准。
1.1.1 翻译环境
- 组成一个程序的每个源文件通过编译过程分别转换成目标代码(object code)。
- 每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序。
- 链接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其需要的函数也链接到程序中
翻译的几个环节,通过下面的图进行初步的了解:
1.1.2 运行环境
- 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
- 程序的执行便开始。接着便调用main函数。
- 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程 一直保留他们的值。
- 终止程序。正常终止main函数;也有可能是意外终止。
1.2 预处理
在预处理阶段,源⽂件和头⽂件会被处理成为 .i 为后缀的⽂件。在 gcc 环境下想观察⼀下,对 test.c ⽂件预处理后的.i⽂件,命令(以下所有的命令在Linux下的指令)如下:
gcc -E test.c -o test.i
在Linux下执行这条指令后,生成.i文件,查看里面内容大多都是宏
预处理阶段主要处理那些源⽂件中#开始的预编译指令。
⽐如:#include,#define,处理的规则如下:
- 将所有的 #define 删除,并展开所有的宏定义。
- 处理所有的条件编译指令,如: #if、#ifdef、#elif、#else、#endif 。
- 处理#include 预编译指令,将包含的头⽂件的内容插⼊到该预编译指令的位置。这个过程是递归进行的,也就是说被包含的头⽂件也可能包含其他⽂件。
- 删除所有的注释
- 添加⾏号和⽂件名标识,⽅便后续编译器⽣成调试信息等。
- 或保留所有的#pragma的编译器指令,编译器后续会使⽤。
经过预处理后的 .i ⽂件中不再包含宏定义,因为宏已经被展开。并且包含的头⽂件都被插⼊到 .i⽂件中。所以当我们⽆法知道宏定义或者头⽂件是否包含正确的时候,可以查看预处理后的 .i ⽂件来确认。
1.2.1 预定义符号
__FILE__ //进行编译的源文件
__LINE__ //文件当前的行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义
这些预定义的符号都是语言内置的。下面使用部分宏:
#include<stdio.h>int main() {//__FILE__进行编译的源文件 __LINE__文件当前的行号printf(" file:%s \n line:%d\n", __FILE__, __LINE__); //__DATE__ 文件被编译的日期 __TIME__ 文件被编译的时间printf(" date:%s \n time:%lld\n", __DATE__, __TIME__);return 0;
}
运行结果如下:
1.2.2 #define
#define是一种定义标识符,用来定义宏,下面是#define的功能介绍
#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏( macro )或定义宏(define macro )。
举个梨子:
#define MAX 1000
#define reg register //为 register这个关键字,创建一个简短的名字
#define do_forever for(;;) //用更形象的符号来替换一种实现
#define CASE break;case //在写case语句的时候自动把 break写上。
// 如果定义的 stuff过长,可以分成几行写,除了最后一行外,每行的后面都加一个反斜杠(续行符)。
#define DEBUG_PRINT printf("file:%s\tline:%d\t \date:%s\ttime:%s\n" ,\__FILE__,__LINE__ , \__DATE__,__TIME__ )
在define定义标识符的时候,建议不要加上 ; 这样容易导致问题。比如下面的场景:
#include<stdio.h>
#define MAX 1000;
int main() {int condition = 0, max = 0;if (condition) max = MAX; elsemax = 0;return 0;
}
在vs下进行编译,这里会出现语法错误。
#define的语法:
语法: #define name stuff
下面是宏的申明方式:
把宏名全部大写函数名不要全部大写
- 参数列表的左括号必须与name紧邻。
- 如果两者之间有任何空白存在,参数列表就会被解释为stuff的一部分
举个小梨子,定义一个数的平方的宏:
#define MUL(x) x*x //参数列表的左括号必须与name紧邻
这个宏接收一个参数 x ,如果在上述声明之后,MUL(5)。置于程序中,预处理器就会用下面这个表达式替换上面的表达式:5*5
#include<stdio.h>#define MUL(x) x*x //参数列表的左括号必须与name紧邻。int main() {printf("%d\n", MUL(5)); // ==> printf("%d\n", 5*5)return 0;
}
那么如果输入的参数是一个表达式呢?MUL宏输出的结果是否还是符合预期呢?此时将MUL(5)替换为 MUL(2+3),它的预期结果应该也是25,运行一下看看
结果是11,为什么呢?这时候把(2+3)参数带入MUL宏中看看 ===> 2+3* 2+3 ====> 2+6+3,所以输出的结果变为了11。这样就比较清晰了,由替换产生的表达式并没有按照预想的次序进行求值。这里涉及到了运算符优先级的问题。在宏定义上加上两个括号,这个问题便轻松的解决了:
#define MUL(x) (x)*(x)
举另外一个小梨子,定义一个数跟自己加和的宏:
#include<stdio.h>#define SADD(x) (x)+(x) //参数列表的左括号必须与name紧邻。int main() {printf("%d\n", 10*SADD(2)+ SADD(2)); //预期结果 10*4+4=44return 0;
}
欸,这又是怎么回事?参数我也加上了小括号,不应该呀。依旧是上面的分析方法,将宏在表达式中进行展开,10*SADD(2)+ SADD(2) =====> 10 * (2) + (2)+ (2) + (2)====> 20+6=26。乘法运算先于宏定义的加法,所以出现了26。这个问题的解决办法是在宏定义表达式两边加上一对括号就可以了:
#define SADD(x) ((x)+(x))
这样运行结果便符合预期啦
通过上面两个小梨子,得出以下的经验:
用于对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免在使用宏时由于参数中 的操作符或邻近操作符之间不可预料的相互作用。
#define 替换规则:
- 1. 在调用宏时,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先 被替换。
- 2. 替换文本随后被插入到程序中原来文本的位置。对于宏,参数名被他们的值所替换。
- 3. 最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述处理过程。
- 1. 宏参数和#define 定义中可以出现其他#define定义的符号。但是对于宏,不能出现递归。
- 2. 当预处理器搜索#define定义的符号的时候,字符串常量的内容并不被搜索。
#和##
字符串是有自动连接的特点的,将两个或者多个字符串紧挨着它们会自动连接,形成一个组合后的字符串,通过下面的小梨子看看:
#include<stdio.h>
int main() {char* p = "hello ""world""!!!\n";printf("hello ""world""!!!\n");printf("%s", p);return 0;
}
如果把这些写到宏里是不是实现同样的效果呢?
使用 # ,把一个宏参数变成对应的字符串。还可以添加部分参数,进行打印:
#include<stdio.h>//使用 # ,把一个宏参数变成对应的字符串
//FORMAT 数据输出格式,VALUE 数据
#define PRINT(FORMAT,VALUE) printf("the value of " #VALUE " is "FORMAT"\n", VALUE);int main() {int i = 10;PRINT("% d" , i + 5)return 0;
}
代码中的 #VALUE 会预处理器处理为: "VALUE"
## 的作用
## 可以把位于它两边的符号合成一个符号。 它允许宏定义从分离的文本片段创建标识符。
通过一个小梨子看看:
#include<stdio.h>
#define ADD_TO_SUM(num, value) s##num += value;int main() {int s1 = 0, s2 = 0, s3 = 0;ADD_TO_SUM(1, 10) // 作用是:给s1增加10.ADD_TO_SUM(2, 20) //给s2增加20.ADD_TO_SUM(3, 30) //给s3增加30.printf("s1: %d s2: %d s3: %d", s1, s2, s3);return 0;
}
带副作用的宏参数
x + 1 ; // 不带副作用 不会改变参数的数值x ++ ; // 带有副作用 参数的数值被永久修改
借用上面MUL的宏,运行下列代码:
#define MUL(x) (x)* (x)int main() {int i = 2;printf("MUL: %d i: %d\n", MUL(i++),i);return 0;
}
发现宏替换后MUL(i++) ====> (i++)* (i++) 。此后i被加加两次,产生了副作用
宏和函数对比
- 1. 用于调用函数和从函数返回的代码可能比实际执行这个小型计算工作所需要的时间更多。所以宏比函数在程序的规模和速度方面更胜一筹。
- 2. 更为重要的是函数的参数必须声明为特定的类型。 所以函数只能在类型合适的表达式上使用。反之这个宏怎可以适用于整形、长整型、浮点型等可以 用于>来比较的类型。
- 1. 每次使用宏的时候,一份宏定义的代码将插入到程序中。除非宏比较短,否则可能大幅度增加程序的长度。
- 2. 宏是没法调试的。
- 3. 宏由于类型无关,也就不够严谨。
- 4. 宏可能会带来运算符优先级的问题,导致程容易出现错。
- 宏有时候可以做函数做不到的事情。比如:宏的参数可以出现类型,但是函数做不到。
下面表格是将宏与函数进行对比:
属性 | #define 定义宏 | 函数 |
代码长度 | 每次使用时,宏代码都会被插入到程序中。除了非常 小的宏之外,程序的长度会大幅度增长 | 函数代码只出现于一个地方;每次使用这个函数时,都调用那个地方的同一份代码 |
执行速度 | 更快 | 存在函数的调用和返回的额外开销,所以相对慢一些 |
操作符优 先级 | 宏参数的求值是在所有周围表达式的上下文环境里, 除非加上括号,否则邻近操作符的优先级可能会产生 不可预料的后果,所以建议宏在书写的时候多些括号。 | 函数参数只在函数调用的时候求 值一次,它的结果值传递给函 数。表达式的求值结果更容易预 测 |
带有 副作 用的 参数 | 参数可能被替换到宏体中的多个位置,所以带有副作用的参数求值可能会产生不可预料的结果。 | 函数参数只在传参的时候求值一 次,结果更容易控制。 |
参数 类型 | 宏的参数与类型无关,只要对参数的操作是合法的, 它就可以使用于任何参数类型 | 函数的参数是与类型有关的,如 果参数的类型不同,就需要不同 的函数,即使他们执行的任务是 相同的。 |
调试 | 宏是不方便调试的 | 函数是可以逐语句调试的 |
递 归 | 宏是不能递归的 | 函数是可以递归的 |
#undef
这条指令用于移除一个宏定义。
#undef NAME// 如果现存的一个名字需要被重新定义,那么它的旧名字首先要被移除。
1.3 编译
编译过程就是将预处理后的文件进行⼀系列的:词法分析、语法分析、语义分析及优化,⽣成相应的汇编代码文件。编译过程的命令如下:
gcc -S test.i -o test.s
在Linux下执行这条指令后,生成.s文件,查看.s文件里面内容是相应的汇编代码
对下面的代码进行编译的时候,流程会是怎么样的呢?
num=(z+6)*(9/3)
1.3.1 词法分析
将源代码程序被输⼊扫描器,扫描器的任务就是简单的进⾏词法分析,把代码中的字符分割成⼀系列的记号(关键字、标识符、字⾯量、特殊字符等)。
上⾯程序进行词法分析后得到了13个记号
记号 | 类型 |
num | 标识符 |
= | 赋值 |
( | 左圆括号 |
z | 标识符 |
+ | 加号 |
6 | 数字 |
) | 右圆括号 |
* | 乘号 |
( | 左圆括号 |
9 | 数字 |
+ | 加号 |
3 | 数字 |
) | 右圆括号 |
1.3.2 语法分析
接下来语法分析器,将对扫描产⽣的记号进行语法分析,从⽽产⽣语法树。这些语法树是以表达式为节点的树
1.3.3 语义分析
由语义分析器来完成语义分析,即对表达式的语法层⾯分析。编译器所能做的分析是语义的静态分析。静态语义分析通常包括声明和类型的匹配,类型的转换等。这个阶段会报告错误的语法信息。
1.4 汇编
汇编器是将汇编代码转转变成机器可执行的指令,每⼀个汇编语句几乎都对应⼀条机器指令。就是根据汇编指令和机器指令的对照表⼀⼀的进行翻译,也不做指令优化。汇编的命令如下:
gcc -c test.s -o test.o
在Linux下执行这条指令后,生成.o文件,查看里面内容为机器语言
1.5 链接
链接是一个复杂的过程,链接的时候需要把一堆文件链接在⼀起才生成可执行程序。链接过程的命令如下:
gcc test.o -o test
链接过程主要包括:地址和空间分配,符号决议和重定位等这些步骤。链接解决的是一个项目中多文件、多模块之间互相调用的问题。比如: 在一个C的项目中有2个.c文件( test.c 和 add.c ),代码如下:
#include <stdio.h>
//test.c
//声明外部函数
extern int Add(int x, int y);
//声明外部的全局变量
extern int g_val;
int main()
{int a = 10;int b = 20;int sum = Add(a, b);printf("%d\n", sum);return 0;
}
int g_val = 2022;
int Add(int x, int y)
{return x+y;
}
我们已经知道,每个源⽂件都是单独经过编译器处理⽣成对应的⽬标⽂件。
- test.c 经过编译器处理⽣成 test.o
- add.c 经过编译器处理⽣成 add.o
我们在 test.c 的⽂件中使⽤了 add.c ⽂件中的 Add 函数和 g_val 变量。
我们在 test.c ⽂件中每⼀次使⽤ Add 函数和 g_val 的时候必须确切的知道 Add 和 g_val 的地址,但是由于每个⽂件是单独编译的,在编译器编译 test.c 的时候并不知道 Add 函数和 g_val 变量的地址,所以暂时把调⽤ Add 的指令的⽬标地址和 g_val 的地址搁置。等待最后链接的时候由链接器根据引⽤的符号 Add 在其他模块中查找 Add 函数的地址,然后将 test.c 中所有引⽤到Add 的指令重新修正,让他们的⽬标地址为真正的 Add 函数的地址,对于全局变量 g_val 也是类似的⽅法来修正地址。这个地址修正的过程也被叫做:重定位
相关文章:
笔记五:C语言编译链接
Faye:孤独让我们与我们所爱的人相处的每个瞬间都无比珍贵,让我们的回忆价值千金。它还驱使你去寻找那些你在我身边找不到的东西。 ---------《寻找天堂》 目录 一、编译和链接的介绍 1.1 程序的翻译环境和执行环境 1.1.1 翻译环境 1.1.2 运行环境 …...
SpringUI:打造高质量Web交互设计的首选元件库
SpringUI作为一个专为Web设计与开发领域打造的高质量交互元件库,确实为设计师和开发者提供了极大的便利。以下是对SpringUI及其提供的各类元件的详细解读和一些建议: SpringUI概述 SpringUI集合了一系列预制的、高质量的交互组件,旨在帮助设…...
LeetCode - 神经网络的 反向传播(Sigmoid + MSE) 教程
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/146085177 使用 Python + Numpy,设计带有 Sigmoid 激活函数 的神经网络,实现反向传播以更新神经元的权重和偏置。函数输入:特征向量(Input)、真实标签(Label)、初始…...
Elastic如何获取当前系统时间
文章目录 1. 使用 _ingest.timestamp 在 Ingest Pipeline 中获取当前时间2. 使用 Painless Script 获取当前时间3. 使用 now 关键字在查询中获取当前时间4. 使用 date 类型字段的默认值5. 使用 Kibana 的 Dev Tools 查看当前时间6. 使用 date 聚合获取当前时间7. 使用 Elastics…...
腾讯云对象存储服务(COS)
腾讯云对象存储服务(COS) 安全、可扩展、低成本的云存储解决方案 腾讯云 对象存储服务(COS,Cloud Object Storage) 是一种高可靠、高性能、可扩展的云存储服务,专为海量非结构化数据(如图片、…...
力扣35.搜索插入位置-二分查找
class Solution:def searchInsert(self, nums: List[int], target: int) -> int:# 初始化左右指针left, right 0, len(nums) - 1# 当左指针小于等于右指针时,继续循环while left < right:# 计算中间位置mid (left right) // 2# 如果中间元素等于目标值&…...
SSLScan实战指南:全面检测SSL/TLS安全配置
SSLScan是一款开源的SSL/TLS安全扫描工具,用于检测服务器的加密协议、支持的加密套件、证书信息以及潜在的安全漏洞。本指南将详细介绍如何安装、使用SSLScan,并结合实战案例帮助您全面评估服务器的安全性。 一、SSLScan简介 功能特性: 检测支持的SSL/TLS协议版本(如TLS 1.…...
Linux 进程管理
一.进程 1.基本介绍 在Linux中每一个执行的程序都称之为进程,每一个进程都会分配一个进程号(PID)。进程以前台和后台两种方式存在,前台进程就是我们可以在屏幕上操作的,后台进程我们无法在屏幕上看到。 程序是静态的…...
mfc140u.dll是什么?当程序遭遇mfc140u.dll问题:快速恢复正常的秘诀
在使用Windows操作系统运行某些软件时,不少用户会遇到令人头疼的mfc140u.dll文件丢失错误。mfc140u.dll这个错误一旦出现,往往导致相关程序无法正常启动或运行,给用户带来诸多不便。这天的这篇文章将给大家分析mfc140u.dll是什么?…...
日新F1、瑞研F600P 干线光纤熔接(熔接损耗最大0.03DB)
Ⅰ. 设备特性对比与实测验证 1. 日新F1(两马达)极限参数 切割角度:必须≤0.3(双边累计误差<0.6) ▶ 实测案例:切割0.35时,损耗波动达0.05-0.08dB(超干线标准)…...
【我的待办(MyTodolists)-免费无内购的 IOS 应用】
我的待办(MyTodolists) 我的待办:智能任务管理助手应用说明主要功能为什么选择"我的待办"?隐私保障使用截图 我的待办:智能任务管理助手 应用说明 "我的待办"是一款智能化的任务管理应用&#x…...
微信小程序+SpringBoot的单词学习小程序平台(程序+论文+讲解+安装+修改+售后)
感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,我会一一回复,希望帮助更多的人。 系统背景 (一)社会需求背景 在全球化的大背景下,英语作为国际…...
测试直播web自动化所学
web框架封装 web自动化开始:用电脑替代人工测试。 日常人工测试 —— 先点击XX 输入XXX 。。。页面是否符合预期 自动化测试的编码: web自动化,Selenium[常用测试库] Selenium,每个页面,是由元素组成的。html构成。 …...
Vue+Ant Design搭建AI聊天对话
今天在这里介绍一下 Ant Design X,这是蚂蚁设计团队推出的一款专注于人工智能(AI)领域的组件库,主要面向 React 生态系统(目前支持Openai,通义千问)。官方也推出了ant-design-x-vue 面向 Vue。当然我们今天的主题也是使…...
应用案例 | 精准控制,高效运行—宏集智能控制系统助力SCARA机器人极致性能
概述 随着工业4.0的深入推进,制造业对自动化和智能化的需求日益增长。传统生产线面临空间不足、效率低下、灵活性差等问题,尤其在现有工厂改造项目中,如何在有限空间内实现高效自动化成为一大挑战。 此次项目的客户需要在现有工厂基础上进行…...
JavaScript基础-运算符的分类
在JavaScript编程中,运算符是构建表达式和执行操作的基础工具。了解不同类型的运算符以及它们的工作原理对于编写高效且无误的代码至关重要。本文将介绍JavaScript中的主要运算符类型,并通过实例展示它们的用法。 一、算术运算符 算术运算符用于执行基…...
URIError: URI malformed
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…...
达梦适配记录-检查服务器
service DmServicedmdb status 查看是否开启,没有配置systemctl,查看《DM8_Linux 服务脚本使用手册》2.1.2.2 1 .拷贝服务模板文件( DmService )到目录( /opt/dmdbms/bin ),并将新文…...
【leetcode hot 100 160】相交链表
解法一:(哈希集合)利用HashSet保存一个链表的值,循环另一个列表,在HashSet中寻找该值。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x…...
选择排序算法的SIMD优化
一、优化原理 将查找数组最小值索引的SIMD优化的函数嵌入选择排序主循环,优化最耗时的最小值查找环节,同时保留选择排序的交换逻辑。 二、关键改造步骤 1)最小值查找模块化 复用SIMD优化的 find_min_index_simd函数。 2)动态子数组处理 每次循环处理 arr[i..n-1] 子数…...
Visual Studio Code打开远程服务器项目,打开服务器Android上百G源码,SSH免密连接方式
Visual Studio Code打开远程服务器项目 1,Visual Studio Code拓展中,安装远程插件 Remote Development 2,SSH免密连接,A电脑免密连接B,配置B电脑.ssh/authorized_keys A电脑的.ssh/id_rsa.pub中的公钥内容,…...
vscode mac版本 配置git
首先使用 type -a git查看git的安装目录 然后在vscode中找到settings配置文件,修改git.path...
BUUCTF——[GYCTF2020]FlaskApp1 SSTI模板注入/PIN学习
目录 一、网页功能探索 二、SSTI注入 三、方法一 四、方法二 使用PIN码 (1)服务器运行flask登录所需的用户名 (2)modename (3)flask库下app.py的绝对路径 (4)当前网络的mac地…...
【QT常用技术讲解】window系统以CMD命令行方式执行第三方程序及注册表文件命令
前言 在window下(本篇为window10),调用第三方应用,可以调用后台CMD执行的命令行。如果是浏览器调用第三方应用,可以通过自定义域名调用指定的处理脚本,处理脚本再调用第三方软件。本篇只讲解QT程序调用后台…...
manus是什么?能干啥?
Manus哪儿来的? Manus是一款由中国团队Monica.im于2025年3月5日发布的通用型AI代理(AI Agent)产品,旨在通过自主思考、系统规划和灵活工具调用,帮助用户完成各种复杂任务,从而解放用户的时间与创…...
物联网系统搭建
实验项目名称 构建物联网系统 实验目的 掌握物联网系统的一般构建方法。 实验要求: 1.构建物联网系统,实现前后端的交互。 实验内容: CS模式MQTT(不带数据分析处理功能) 实现智能设备与应用客户端的交…...
恭喜!《哪吒2》明天将荣登世界影坛第六!目前仅差1.81亿元
全球总票房为为20.27亿美元!3月8日将荣登世界影坛第六宝座! 中国票房 内地票房 中国电影票房、灯塔、猫眼三大数据源加权平均得出《哪吒2》中国内地总票房为144.26亿元人民币。 港澳票房 目前港澳地区没有新的数据显示,按3月6日1905电影网…...
2025 ubuntu24.04系统安装docker
1.查看ubuntu版本(Ubuntu 24.04 LTS) rootmaster:~# cat /etc/os-release PRETTY_NAME"Ubuntu 24.04 LTS" NAME"Ubuntu" VERSION_ID"24.04" VERSION"24.04 LTS (Noble Numbat)" VERSION_CODENAMEnoble IDubun…...
浅说图论基础
引入 在学最短路算法之前,我们要先搞清楚另外一个事情,什么是图,我们又可以基于图做那些事情。 图不同于树,它是一种更加复杂的数据结构,相比较于树或者数组(线性表)而言,图的关联…...
DeepSeek【部署 03】客户端应用ChatBox、AnythingLLM及OpenWebUI部署使用详细步骤
DeepSeek客户端应用 1.ChatBox2.AnythingLLM3.OpenWebUI4.总结 客户端软件提供可视化的模型及参数配置,人性化的对话窗口及文件上传功能,大大降低了大模型的使用门槛。 1.ChatBox Chatbox AI 是一款 AI 客户端应用和智能助手,支持众多先进的…...
工作学习笔记:HarmonyOS 核心术语速查表(v14 实战版)
作为在 HarmonyOS 开发一线摸爬滚打的工程师,笔者在 v14 版本迭代中整理了这份带血的实战术语表。 一、架构基础术语速查 A 系列术语 术语官方定义笔者解读(v14 实战版)开发陷阱 & 解决方案abc 文件ArkCompiler 生成的字节码文件打包时…...
mapbox进阶,模仿百度,简单实现室内楼层切换
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️fill-extrusion三维填充图层样式1.4 ☘…...
发行基础:热销商品榜单
转载自官方文件 ------------------ 热销商品榜单 Steam 在整个商店范围内有各种热销商品榜单,最醒目的莫过于 Steam 主页上的榜单了。 您也可以在浏览单个标签、主题、类型时找到针对某个游戏类别的热销商品榜单。 主页热销商品榜单 该榜单出现在 Steam 主页上…...
Android Studio 一直 Loading devices
https://stackoverflow.com/questions/71013971/android-studio-stuck-on-loading-devices...
【时间序列】因果推断:从时序数据中探寻“因”与“果”
在日常生活中,我们经常听到这样的问题:“为什么股票价格会突然下跌?”、“天气变化是否会影响销售额?”这些问题背后,其实都在试图寻找一种因果关系。然而,在时间序列数据中,探寻因果关系并不像…...
联核科技AGV无人叉车的应用场景有哪些?
联核科技AGV无人自动叉车在多个应用场景中均展现出卓越的性能和广泛的应用价值。下面是针对每个应用场景的简要概括、适用车型及其功能的详细介绍联核科技官网-AGV叉车十大品牌-无人叉车厂家-自动化叉车-智能搬运码垛机器人-智能叉车系统解决方案专家 上存下拣 上层四向车立体…...
多模态知识图谱融合
1.Knowledge Graphs Meet Multi-Modal Learning: A Comprehensive Survey 1.1多模态实体对齐 1.2多模态实体链接 研究进展&#...
c++实现最大公因数和最小公倍数
最大公因数和最小公倍数的介绍 读这篇文章,请你先对最大公因数以及最小公倍数进行了解: 最大公因数(英文名:gcd) 定义:最大公因数,也称最大公约数,指两个或多个整数共有约数&…...
利用optisystem软件仿真半导体激光器的P-I特性曲线
利用optisystem软件仿真半导体激光器的P-I特性曲线。得到的图形遵循在超过阈值电流之后,输出光功率与电流成线性关系规律。 资源文件列表 FiberP-I.m , 1881 PCMcode.m , 830 PRseries.m , 140 photo_detect.m , 638...
华为:Wireshark的OSPF抓包分析过程
一、OSPF 的5包7状态 5个数据包 1.Hello:发现、建立邻居(邻接)关系、维持、周期保活;存在全网唯一的RID,使用IP地址表示 2.DBD:本地的数据库的目录(摘要),LSDB的目录&…...
RangeError: Invalid array length
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…...
django各种mixin用法
在 Django 中,Mixin 是一种用于扩展类功能的设计模式。通过 Mixin,可以在不修改原有类的情况下,为其添加新的方法或属性。Django 中的 Mixin 广泛应用于视图(View)、表单(Form)、模型(Model)等组件中。以下是 Django 中常见 Mixin 的用法和示例: 一、视图(View)中的…...
【leetcode hot 100 206】反转链表
解法一:(头插法)在遍历链表时,将当前节点的 next 指针改为指向前一个节点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}* ListNode(int val)…...
OpenCV视频解码实战指南
硬核解析OpenCV视频处理底层原理,从零实现高效视频解码流水线!附赠FFmpeg调优参数和异常帧处理方案,建议收藏备用。 📺 视频解码核心原理 视频容器 vs 编码格式 类型常见格式特点容器格式MP4/MKV/AVI/MOV存储封装格式࿰…...
USB流量分析总结(实战[NISACTF 2022] 破损的flag)
一、USB流量分析 USB协议的数据部分在 Leftover Capture Data 域之中,可以用tshark命令将leftover capture data 数据单独提取出来,利用命令如下: tshark -r 1.pcapng -T fields -e usb.capdata > usbdata.txt tshark -r 1.pcapng -T fields -e usb…...
CentOS7离线部署安装docker和docker-compose
CentOS7离线部署安装docker和docker-compose 安装包准备 docker下载地址、docker-compose下载地址 docker和docker-compose版本对应关系 注:本次安装部署选择的版本是 docker:docker-28.0.1.tgzdocker-compose:docker-compose-linux-x86_6…...
【第21节】C++设计模式(行为模式)-Chain of Responsibility(责任链)模式
一、问题背景 在 VC/MFC 开发中,消息处理机制是核心部分之一。VC 是基于消息和事件驱动的框架,消息的处理流程通常是通过链式传递的方式进行的。例如,一个 WM_COMMAND 消息的处理流程可能如下: (1)MDI 主窗…...
vue3页面html导出word文档
一、第三方包下载 使用npm下载以下插件: npm install jszip-utils docxtemplater pizzip file-saver docxtemplater-image-module-free 二、总页面组件代码 <template> <summaryDetails :securityId"securityId" :symbol"symbol" …...
防火墙带宽管理实验
一、实验拓扑图 二、实验要求 需求一: 企业组织架构中存在部门A ,部门 A 中存在销售组 1 和研发组 2 销售部门---> 业务 Email 、 ERP 服务 可以对部门A 中的销售组进行带宽资源细分,保证销售员工的业务服务流量正常转…...
高颜值多端适用软件:兼具屏保功能,PC 端登录可用
软件介绍 FliTik是一款翻页式时钟软件,外观颜值颇高,支持Windows和TV端。 这款软件最大的亮点之一,就是它采用了极为吸睛的翻页式设计。当你第一眼看到它的界面时,相信一定会和我一样,被它超高的颜值所惊艳到。简洁大方的布局&a…...