Linux Makefile-概述、语句格式、编写规则、多文件编程、Makefile变量分类:自定义变量、预定义变量

目录

1.make

1.1 make 命令格式

2.Makefile 核心概念‌ ‌

2.1创建并运行 Makefile步骤

3. Makefile编写

3.1最基础Makefile

3.1.1使用默认make命令

 3.1.2使用make -f 命令

3.1.2.1 使用make -f 命令执行默认make操作

3.1.2.2使用 make [ ‐f file ] [ targets ]命令

3.1.2.3使用 make [ ‐f file ] [ targets ]命令,并执行可执行程序

3.1.3 gcc编译常用组合选项

3.1.4 make 和 make all区别

3.1.4.1 all 是默认目标

3.1.4.2 all 不是默认目标

3.1.4.3 没有定义 all 命令

3.1.4.3 强制设置 all 为默认目标

3.2多文件编程Makefile-基础

3.3makefile变量

3.3.1 makefile 变量概述

3.3.2 makefile 的变量分类:

3.3.3 自定义变量语法

3.3.3.1自定义变量makefile多文件编程

3.3.4系统变量

3.3.5预定义变量

3.3.5.1编译器与工具

3.3.5.2. 编译选项

3.3.5.3. 文件与目录

3.3.5.4. 隐式规则中的关键变量

3.3.5.5. 常用内置变量

3.3.5.6.程序验证

4.几种多文件编程Makefile对应关系


1.make

make是个命令,是个可执行程序,用来解析Makefile文件的命令。
终端输入:which make 查看make保存地址,在 /usr/bin/make

1.1 make 命令格式

make [ ‐f file ] [ targets ]
(1)[ -f file ]:
make默认在工作目录中寻找名为GNUmakefile、makefile、Makefile的文件作为
makefile输入文件, -f 可以指定以上名字以外的文件作为makefile输入文件
(2)[ targets ]:
若使用make命令时没有指定目标,则make工具默认会实现makefile文件内的第一个目 标 ,然后退出,指定了make工具要实现的目标,目标可以是一个或多个(多个目标间用空 格隔开)。

2.Makefile 核心概念‌ ‌

作用‌:

自动化编译和链接程序,管理项目依赖关系,避免重复编译未修改的代码。

‌基本结构:

target: dependenciescommand‌target‌: 生成的目标(如可执行文件、中间文件)
‌dependencies‌: 生成目标所需的文件或目标
‌command‌: 生成目标的命令(必须以 Tab 开头)

2.1创建并运行 Makefile步骤

基本步骤:

  • 创建文件:在项目根目录创建名为 Makefile 的文件(无后缀)。
  • 编写规则:定义目标(如可执行文件)、依赖(如 .c 和 .o 文件)和命令。
  • 运行命令:在终端执行 make 或 make <target>。

3. Makefile编写

 make 命令格式

make [ ‐f file ] [ targets ]
(1)[ -f file ]:
make默认在工作目录中寻找名为GNUmakefile、makefile、Makefile的文件作为
makefile输入文件, -f 可以指定以上名字以外的文件作为makefile输入文件
(2)[ targets ]:
若使用make命令时没有指定目标,则make工具默认会实现makefile文件内的第一个目 标 ,然后退出,指定了make工具要实现的目标,目标可以是一个或多个(多个目标间用空 格隔开)。

3.1最基础Makefile

3.1.1使用默认make命令

程序:

main.c

#include <stdio.h>
#include "main.h"int main(int argc, char const *argv[])
{printf("main函数开始\n");printf("ABC = %d abc = %d\n",ABC, abc);return 0;
}

main.h

#define ABC 123
#define abc 456

makefile

main:main.c main.h gcc main.c -o main clean:rm main 

makefile内容解释:

main:main.c main.h //可执行文件main依赖main.c main.h
    gcc main.c -o main //由mian.c 生成可执行文件main
    
clean:
    rm main //执行 make clean 命令,删除可执行文件main

运行结果:

 3.1.2使用make -f 命令

3.1.2.1 使用make -f 命令执行默认make操作

程序:与3.1.1使用默认make命令一样。

makefile:与3.1.1使用默认make命令一样。仅名称不同。

将可执行文件main删除,Makefile复制一份,重命名为Makefile1,执行 make -f Makefile1

也可以正常执行make命令。执行结果与默认make命令结果相同

3.1.2.2使用 make [ ‐f file ] [ targets ]命令

程序:与3.1.1使用默认make命令一样。

makefile:

test:main.c main.h gcc main.c -o main @echo "=== test ==="clean:rm main @echo "=== clean ==="test1:@echo "=== test1 ==="; # @符号注释见下面 #echo前使用 @‌:在 echo 前添加 @ 符号,可隐藏命令本身的输出,仅显示命令的执行结果‌
#终端结果: === test1 ===#未使用 @‌:命令本身和执行结果都会显示,
#终端结果: echo "=== test1 ==="
# 		=== test1 ===
# 在 Makefile 中直接写 @echo "注释内容" # 注释内容, 注释内容会输出在终端,
# 因为 # 必须出现在行首或通过 ; 分隔	
test2:@echo "=== test2 ==="; # @符号注释见上面 

(1)执行  make -f Makefile2 test1 test test2

test1 test test2 为Makefile2中的三个目标文件,执行上述命令,先运行test1里面的运行命令,在运行test运行命令,最后运行test2运行命令。

运行结果:

(2)执行 make -f Makefile2 test1 test2 clean 命令

test1 test2 clean 为Makefile2中的三个目标文件,执行上述命令,先运行test1里面的运行命令,在运行test2运行命令,最后运行clean运行命令。

运行结果:

注意:保证执行 clean命令,确保删除的文件要存在。

删除文件不存在运行结果:

3.1.2.3使用 make [ ‐f file ] [ targets ]命令,并执行可执行程序

程序:与3.1.1使用默认make命令一样。

makefile:

test:main.c main.h gcc main.c -o main @echo "=== test ==="clean:rm main @echo "=== clean ==="test1:@echo "=== test1 ==="; # @符号注释见下面 #echo前使用 @‌:在 echo 前添加 @ 符号,可隐藏命令本身的输出,仅显示命令的执行结果‌
#终端结果: === test1 ===#未使用 @‌:命令本身和执行结果都会显示,
#终端结果: echo "=== test1 ==="
# 		=== test1 ===
# 在 Makefile 中直接写 @echo "注释内容" # 注释内容, 注释内容会输出在终端,
# 因为 # 必须出现在行首或通过 ; 分隔	
test2:@echo "=== test2 ==="; # @符号注释见上面 

(1)执行 make -f Makefile2 test1 test2 test;./main 命令

执行Makefile命令后,并运行生成的可执行文件

 (2)执行 make -f Makefile2 test;./main 命令

执行Makefile命令后,并运行生成的可执行文件

3.1.3 gcc编译常用组合选项

选项作用示例
-o指定输出文件名gcc -c main.c -o main.o
-I指定头文件搜索路径gcc -c main.c -I../include
-Wall启用所有警告信息gcc -c main.c -Wall
-g生成调试信息(用于 GDB)gcc -c main.c -g
-O2启用优化(级别 2)gcc -c main.c -O2

3.1.4 make 和 make all区别

关键总结

场景make 行为make all 行为
all 是默认目标执行 all执行 all
all 不是默认目标执行第一个目标(如 build执行 all(需存在定义)
未定义 all执行第一个目标报错
强制 .DEFAULT_GOAL=all执行 all执行 all
3.1.4.1 all 是默认目标

当 all 是默认目标时,make 和 make all 运行顺序,结果相同。

程序:

main.c

#include <stdio.h>int main(int argc, const char *argv[])
{int x = 60;int y = 20;printf("main x= %d y= %d \n", x, y);return 0;
}

makefile

# all 是第一个目标(默认目标)
all:target echo " all开始"target:main.c gcc main.c -o mainecho " main开始"clean:rm main  *.o  -rf	

运行结果:当 all 是默认目标时,make 和 make all 运行顺序,结果相同。

(1)make all

(2)make

3.1.4.2 all 不是默认目标

all 不是默认目标,执行make all命令,会先执行 all依赖的命令。

程序:

 main.c

#include <stdio.h>int main(int argc, const char *argv[])
{int x = 60;int y = 20;printf("main x= %d y= %d \n", x, y);return 0;
}

makefile

# 若makefile命名不是 GNUmakefile、makefile、Makefile 中的一个
# 要使用 make -f Makefile名称,执行make命令# all 不是第一个目标
target:main.c gcc main.c -o mainecho " main开始"all:clean  targetecho " all开始"clean:rm main  *.o  -rf

运行结果:

(1) 首次make 编译, 执行默认目标 target,编译 gcc main.c -o main

(2)执行make all命令,会先执行 clean命令  rm main *.o -rf,在编译gcc main.c -o main

3.1.4.3 没有定义 all 命令

 main.c

#include <stdio.h>int main(int argc, const char *argv[])
{int x = 60;int y = 20;printf("main x= %d y= %d \n", x, y);return 0;
}

makefile

# 若makefile命名不是 GNUmakefile、makefile、Makefile 中的一个
# 要使用 make -f Makefile名称,执行make命令target:main.c gcc main.c -o mainecho " main开始"clean:rm main  *.o  -rf

运行结果:make all运行报错,make正常运行。

3.1.4.3 强制设置 all 为默认目标

 main.c

#include <stdio.h>int main(int argc, const char *argv[])
{int x = 60;int y = 20;printf("main x= %d y= %d \n", x, y);return 0;
}

makefile

# 若makefile命名不是 GNUmakefile、makefile、Makefile 中的一个
# 要使用 make -f Makefile名称,执行make命令# 显式设置 .DEFAULT_GOAL 为 all
.DEFAULT_GOAL = alltarget:main.c gcc main.c -o mainecho " main开始"all:clean  targetecho " all开始"clean:rm main  *.o  -rf

运行结果:强制设置 all 为默认目标,执行make命令,先执行all依赖的语句。

3.2多文件编程Makefile-基础

main.c

#include "head.h"int main(int argc, const char *argv[])
{int x = 60;int y = 20;printf("%d + %d = %d\n", x, y, sum(x, y));printf("%d - %d = %d\n", x, y, sub(x, y));return 0;
}

sub.c

#include "head.h"int sub(int a, int b)
{return a - b;
}

sum.c

#include "head.h"int sum(int a, int b)
{return a + b;
}

head.h

#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>int sum(int a, int b);
int sub(int a, int b); #endif

Makefile

main:main.o sub.o sum.ogcc main.o sub.o sum.o -o mainmain.o:main.cgcc -c main.c -o main.osub.o:sub.cgcc -c sub.c -o sub.osum.o:sum.cgcc -c sum.c -o sum.oclean:rm *.o main a.out -rf

Makefile语句解释:
main:main.o sub.o sum.o //可执行文件main依赖于main.o sub.o sum.o
    gcc main.o sub.o sum.o -o main //gcc 编译 main.o sub.o sum.o 生成可执行文件main

main.o:main.c //可执行文件main.o依赖于main.c
    gcc -c main.c -o main.o //gcc 编译 main.c 生成可执行文件main.o

sub.o:sub.c //可执行文件sub.o依赖于sub.c
    gcc -c sub.c -o sub.o //gcc 编译 sub.c 生成可执行文件sub.o

sum.o:sum.c //可执行文件sum.o依赖于sum.c

        gcc -c sum.c -o sum.o //gcc 编译 sum.c 生成可执行文件sum.o

clean:
    rm *.o main a.out -rf //执行 make clean删除可执行文件,所有.o文件 main a.out

执行顺序:

可执行文件main依赖于main.o,main.o又依赖于main.c,先执行gcc -c main.c -o main.o,在执行gcc main.o sub.o sum.o -o main

运行结果:

3.3makefile变量

3.3.1 makefile 变量概述

makefile 变量类似于 C 语言中的宏,当 makefile make 工具解析时,其中的变量会被展开。
变量的作用:
保存文件名列表
保存文件目录列表
保存编译器名
保存编译参数
保存编译的输出
...

3.3.2 makefile 的变量分类:

1 、自定义变量
makefile 文件中定义的变量。
make 工具传给 makefile 的变量。
2 、系统环境变量
make 工具解析 makefile 前,读取系统环境变量并设置为 makefile 的变量。
3 、预定义变量(自动变量)

3.3.3 自定义变量语法

定义变量:
变量名 = 变量值
引用变量:
$( 变量名 ) ${ 变量名 }
makefile 的变量名 :
makefile 变量名可以以数字开头
注意:
1 、变量是大小写敏感的
2 、变量一般都在 makefile 的头部定义
3 、变量几乎可在 makefile 的任何地方使用

常用变量:

定义变量:VAR = value
使用变量:$(VAR)
常用内置变量:
CC:C 编译器(默认 cc,通常指向 gcc)。
CFLAGS:C 编译选项(如 -Wall -O2)。
LDFLAGS:链接选项(如 -L 指定库路径)。
LDLIBS:链接库(如 -lm 表示数学库)。
3.3.3.1自定义变量makefile多文件编程

程序:

 main.c

#include "head.h"int main(int argc, const char *argv[])
{int x = 60;int y = 20;printf("%d + %d = %d\n", x, y, sum(x, y));printf("%d - %d = %d\n", x, y, sub(x, y));return 0;
}

sub.c

#include "head.h"int sub(int a, int b)
{return a - b;
}

sum.c

#include "head.h"int sum(int a, int b)
{return a + b;
}

head.h

#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>int sum(int a, int b);
int sub(int a, int b); #endif

Makefile

CC=gcc
obj=main
obj1=sub
obj2=sum
OBJS=main.o sub.o sum.o$(obj):$(OBJS)$(CC) $(OBJS) -o $(obj)$(obj).o:$(obj).c$(CC) -c $(obj).c -o $(obj).o$(obj1).o:$(obj1).c$(CC) -c $(obj1).c -o $(obj1).o$(obj2).o:$(obj2).c$(CC) -c $(obj2).c -o $(obj2).oclean:rm *.o $(obj) a.out -rf

Makefile语句解释:与3.2多文件编程Makefile-基础,一样,只是替换为自定义的变量
main:main.o sub.o sum.o //可执行文件main依赖于main.o sub.o sum.o
    gcc main.o sub.o sum.o -o main //gcc 编译 main.o sub.o sum.o 生成可执行文件main

main.o:main.c //可执行文件main.o依赖于main.c
    gcc -c main.c -o main.o //gcc 编译 main.c 生成可执行文件main.o

sub.o:sub.c //可执行文件sub.o依赖于sub.c
    gcc -c sub.c -o sub.o //gcc 编译 sub.c 生成可执行文件sub.o

sum.o:sum.c //可执行文件sum.o依赖于sum.c

        gcc -c sum.c -o sum.o //gcc 编译 sum.c 生成可执行文件sum.o

clean:
    rm *.o main a.out -rf //执行 make clean删除可执行文件,所有.o文件 main a.out

执行顺序:

可执行文件main依赖于main.o,main.o又依赖于main.c,先执行gcc -c main.c -o main.o,在执行gcc main.o sub.o sum.o -o main

运行结果:

3.3.4系统变量

make 工具会拷贝系统的环境变量并将其设置为 makefile 的变量,在 makefile 中可直接读取或修改拷贝后的变量。
程序:
main.c
#include <stdio.h>int main(int argc, const char *argv[])
{int x = 60;int y = 20;printf("x = %d  y = %d \n", x, y);return 0;
}

Makefile

main:main.cgcc main.c -o main clean:rm main -rfecho $(PWD)echo $(HOME)echo $(HOSTNAME)echo $(MY_SHELL_NUM)
运行结果:
(1)先在终端执行shell脚本,设置一个预设环境变量,echo 输出一下。
MY_SHELL_NUM=123
export MY_SHELL_NUM
echo $MY_SHELL_NUM
(2)执行 make 命令,在执行 make clean 命令,shell语句的结果输出在终端。
分别输出 PWD ,HOME,HOSTNAME,MY_SHELL_NUM这四个变量的结果

3.3.5预定义变量

$@ 目标名
$< 依赖文件列表中的第一个文件
$^ 依赖文件列表中除去重复文件的部分
AR 归档维护程序的程序名,默认值为 ar
ARFLAGS 归档维护程序的选项
AS 汇编程序的名称,默认值为 as
ASFLAGS 汇编程序的选项
CC C 编译器的名称,默认值为 cc
CFLAGS C 编译器的选项
CPP C 预编译器的名称,默认值为$(CC) -E
CPPFLAGS C 预编译的选项
CXX C++编译器的名称,默认值为 g++
CXXFLAGS C++编译器的选项
3.3.5.1编译器与工具
变量名默认值描述示例用法
CCccC 编译器CC = gcc
CXXg++C++ 编译器CXX = clang++
ARar静态库打包工具AR = ar rcs
ASas汇编器AS = nasm
LDld链接器LD = lld
3.3.5.2. 编译选项
变量名描述默认值示例用法
CFLAGSC 编译选项CFLAGS = -O2 -Wall
CXXFLAGSC++ 编译选项CXXFLAGS = -std=c++17
CPPFLAGS预处理选项(C/C++通用)CPPFLAGS = -Iinclude
LDFLAGS链接器选项(如库路径)LDFLAGS = -Llib
LDLIBS链接的库(如 -lmLDLIBS = -lpthread
3.3.5.3. 文件与目录
变量名描述默认值示例用法
MAKEFILE_LIST当前 Makefile 文件名列表自动生成用于条件判断
VPATH搜索源文件的目录列表VPATH = src:lib
SRC自定义源文件变量SRC = main.c utils.c
OBJ自定义目标文件变量OBJ = $(SRC:.c=.o)
3.3.5.4. 隐式规则中的关键变量

Make 根据文件后缀自动推导编译规则,以下变量控制隐式规则行为:

变量名描述默认命令示例覆盖
COMPILE.cC 文件编译命令$(CC) $(CFLAGS) $(CPPFLAGS) -cCOMPILE.c = $(CC) -O3
LINK.cC 程序链接命令$(CC) $(CFLAGS) $(LDFLAGS)LINK.c = $(CC) -flto
3.3.5.5. 常用内置变量
变量名描述示例值
MAKE当前 Make 命令路径/usr/bin/make
MAKECMDGOALS用户指定的目标列表all clean
CURDIR当前工作目录/home/user/project

3.3.5.6.程序验证

 程序:

 main.c

#include "head.h"int main(int argc, const char *argv[])
{int x = 60;int y = 20;printf("%d + %d = %d\n", x, y, sum(x, y));printf("%d - %d = %d\n", x, y, sub(x, y));return 0;
}

sub.c

#include "head.h"int sub(int a, int b)
{return a - b;
}

sum.c

#include "head.h"int sum(int a, int b)
{return a + b;
}

head.h

#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>int sum(int a, int b);
int sub(int a, int b); #endif

Makefile

CC=gcc
obj=main
obj1=sub
obj2=sum
OBJ=main.o sub.o sum.o
CFLAGS=-Wall -O2   
# -Wall警告相关, -O2:优化选项,兼顾编译速度和性能$(obj):$(OBJ)$(CC) $^ -o $@$(obj).o:$(obj).c$(CC) $(CFLAGS) -c $< -o $@$(obj1).o:$(obj1).c$(CC) $(CFLAGS) -c $< -o $@$(obj2).o:$(obj2).c$(CC) $(CFLAGS) -c $< -o $@clean:rm *.o $(obj) a.out -rf

Makefile语句解释:

与3.3.3 自定义变量语法,一样,只是替换为预定义的变量。表达式的区别见4.几种多文件编程Makefile对应关系。

运行结果:

注:Makefile更精简表达式

Makefile1

CC=gcc
obj=main
OBJ=main.o sub.o sum.o
CFLAGS=-Wall -g$(obj):$(OBJ)$(CC) $^ -o $@%*.o:%*.c  #使用通配符匹配,所有.c文件都去执行下面的命令$(CC) $(CFLAGS) -c $< -o $@clean:rm *.o $(obj) a.out -rf

运行结果:与上述Makefile运行结果相同

(1)先在终端执行 make clean (2)终端执行 make -f Makefile1 

4.几种多文件编程Makefile对应关系

多文件编程Makefile最基础、自定义变量、预定义变量对应关系。

每一行为几种方法相同结果不同格式的变量表达式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/78902.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

城市应急安防系统EasyCVR视频融合平台:如何实现多源视频资源高效汇聚与应急指挥协同

一、方案背景 1&#xff09;项目背景 在当今数字化时代&#xff0c;随着信息技术的飞速发展&#xff0c;视频监控和应急指挥系统在公共安全、城市应急等领域的重要性日益凸显。尤其是在关键场所&#xff0c;高效的视频资源整合与传输能力对于应对突发公共事件、实现快速精准的…

双Token实现用户登录身份认证-Java版

双Token实现用户登录身份认证-Java版 1. 设计方案 方案概述: Access Token: 短期有效的JWT,包含用户ID、设备ID、token版本号。Refresh Token: 长期有效的令牌,存储于Redis,关联用户信息、设备ID及token版本号,用于刷新Access Token。设备绑定: Token与设备ID绑定,防止跨…

Proteus vs Multisim:电路设计与仿真软件对比

Proteus和Multisim作为两款主流的电路设计与仿真软件&#xff0c;在功能定位和应用场景上既有重叠也有显著差异。以下从多个维度综合阐述两者的异同点&#xff1a; 一、相同点 基础功能 ✅ 电路原理图设计&#xff1a;支持电路设计和仿真分析。 ⚙️ 虚拟仪器&#xff1a;提供…

ssh 三级跳

ssh 三级跳 在网络安全和数据传输领域&#xff0c;SSH&#xff08;Secure Shell&#xff09;是一种常用的协议&#xff0c;用于加密两台计算机之间的通信。在某些情况下&#xff0c;你可能需要通过一个中间服务器来间接连接到目标服务器&#xff0c;这通常被称为“三级跳”或“…

Java 性能优化:从原理到实践的全面指南

性能优化是 Java 开发中不可或缺的一环&#xff0c;尤其在高并发、大数据和分布式系统场景下&#xff0c;优化直接影响系统响应速度、资源利用率和用户体验。Java 作为一门成熟的语言&#xff0c;提供了丰富的工具和机制支持性能调优&#xff0c;但优化需要深入理解 JVM、并发模…

【土堆 PyTorch 教程总结】PyTorch入门

目录 一、python学习中两大法宝函数 1、dir() 2、help() 二、PyTorch读取数据集 1、Dataset类 &#xff08;1&#xff09;作用和基本原理 &#xff08;2&#xff09;常见用法 &#xff08;3&#xff09;自定义 Dataset 示例 2、Dataloader类 &#xff08;1&#xff0…

5.DJI-PSDK:Psdk开发负载与Msdk的应用app进行交互:

DJI-PSDK:Psdk开发负载与Msdk的应用app进行交互: 负载设备和无人机使用数据传输模块,在控制命令传输通道上以透传的方式在PSDK和MSDK间传输控制指令。在高速数据传输通道上以透传的方式在PSDK和MSDK间传输数据信息以及用户自定义的数据。使用数据传输功能,不仅可以设置不同…

2025 蓝桥杯省赛c++B组个人题解

声明 本题解为退役蒻苟所写&#xff0c;不保证正确性&#xff0c;仅供参考。 花了大概2个半小时写完&#xff0c;感觉比去年省赛简单&#xff0c;难度大概等价于 codeforces dv4.5 吧 菜鸡不熟悉树上背包&#xff0c;调了一个多小时 题目旁边的是 cf 预测分 所有代码均以通…

Dubbo(53)如何在Spring Boot中集成Dubbo?

在Spring Boot中集成Dubbo可以通过Spring Boot Starter来简化配置&#xff0c;以下是详细的步骤和相关代码示例。 1. 引入依赖 首先&#xff0c;在Spring Boot项目的 pom.xml 中添加Dubbo相关的依赖&#xff1a; <dependencies><!-- Spring Boot Starter --><…

开发一个环保回收小程序需要哪些功能?环保回收小程序

废品分类展示与识别 详细分类列表&#xff1a;清晰展示常见废品类型&#xff0c;如废纸&#xff08;报纸、书本纸、包装纸等&#xff09;、塑料&#xff08;塑料瓶、塑料容器、塑料薄膜等&#xff09;、金属&#xff08;易拉罐、铁制品、铜制品等&#xff09;、玻璃&#xff0…

抗干扰CAN总线通信技术在分布式电力系统中的应用

摘要&#xff1a;随着分布式电力系统的广泛应用&#xff0c;其通信系统的可靠性与稳定性受到了前所未有的挑战。CAN总线通信技术以其卓越的抗干扰性能和可靠性&#xff0c;在众多通信技术中脱颖而出&#xff0c;成为解决分布式电力系统通信问题的关键。本文深入剖析了CAN总线通…

MySQL与Oracle深度对比

MySQL与Oracle深度对比&#xff1a;数据类型与SQL差异 一、数据类型差异 1. 数值类型对比 数据类型MySQLOracle整数TINYINT, SMALLINT, MEDIUMINT, INT, BIGINTNUMBER(精度) 或直接INT(内部仍为NUMBER)小数DECIMAL(p,s), FLOAT, DOUBLENUMBER(p,s), FLOAT, BINARY_FLOAT, BI…

探索 Rust 语言:高效、安全与并发的完美融合

在当今的编程语言领域&#xff0c;Rust 正以其独特的魅力吸引着越来越多开发者的目光。它诞生于 Mozilla 实验室&#xff0c;旨在解决系统编程中长久以来存在的难题&#xff0c;如今已成为构建可靠、高效软件的有力工具。 1 内存安全 Rust 通过所有权&#xff08;ownership&a…

springboot框架集成websocket依赖实现物联网设备、前端网页实时通信!

需求&#xff1a; 最近在对接一个物联网里设备&#xff0c;他的通信方式是 websocket 。所以我需要在 springboot框架中集成websocket 依赖&#xff0c;从而实现与设备实时通信&#xff01; 框架&#xff1a;springboot2.7 java版本&#xff1a;java8 好了&#xff0c;还是直接…

第八天 开始Unity Shader的学习之Blinn-Phong光照模型

Unity Shader的学习笔记 第八天 开始Unity Shader的学习之Blinn-Phong光照模型 文章目录 Unity Shader的学习笔记前言一、Blinn-Phong光照模型①计算高光反射部分效果展示 二、召唤神龙:使用Unity内置的函数总结 前言 今天我们编写另一种高光反射的实现方法 – Blinn光照模型…

React八案例上

代码下载 技术栈&#xff1a; React 核心库&#xff1a;react、react-dom、react-router-dom脚手架&#xff1a;create-react-app数据请求&#xff1a;axiosUI组件库&#xff1a; antd-mobile其他组件库&#xff1a; react-virtualized、formikyup、react-spring 等百度地图A…

线代[13]|线性代数题37道以及数学分析题3道(多图预警)

博主首次发布于CSDN&#xff0c;禁止转载&#xff01;&#xff08;CSDN&#xff1a;汉密士2025&#xff09; 文章目录 一、缘起&#xff5c;《俗说矩阵》课程目录照片存档&#xff5c;线性代数学习脉络&#xff5c;线代习题集封面存档&#xff5c;未来——我与线性代数的纠缠 二…

OpenCV 图形API(24)图像滤波-----双边滤波函数bilateralFilter()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 应用双边滤波到图像。 该函数对输入图像应用双边滤波&#xff0c;如 http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Fil…

AI与5G的融合:如何实现更快速、更智能的物联网应用?

引言 AI和5G的结合&#xff0c;正在加速物联网&#xff08;IoT&#xff09;应用的发展&#xff0c;让万物互联变得更加智能、高效。5G提供超高速率、低时延和海量连接的网络能力&#xff0c;而AI则赋予物联网设备更强的数据分析、预测和自动决策能力。当AI与5G融合&#xff0c;…

在ArcGIS Pro中将栅格NoData值修改为特定值

目录 问题如下&#xff1a;栅格文件中NoData值为65535&#xff0c;要将该NoData值修改为-9999 步骤一&#xff1a;使用栅格计算器&#xff08;Raster Calculator&#xff09;输出具有新NoData值的栅格文件 步骤二&#xff1a;输出修改值后的栅格文件&#xff08;Export Rast…