C语言学习之预处理指令
目录
预定义符号
#define的应用
#define定义常量
#define定义宏
带有副作用的宏参数
宏替换的规则
函数和宏定义的区别
#和##
#运算符
##运算符
命名约定
#undef
编辑
命令行定义
条件编译
头文件包含
头文件被包含的方式
1.本地头文件包含
2.库文件包含
3.嵌套文件包含
1.头文件中ifndef/define/endif分别是干什么用的?
2.#include 和#include"filename.h"有什么区别?
2. #include "filename.h"
错误用法
总结
其它预处理指令
#error
#pragma
#line
#pragma pack() (在结构体部分介绍)
总结
预定义符号
C语言设置了一些预处理符号,可以直接使用,预定义符号也是在预处理期间处理的
__FILE__ //进行编译的文件
__LINE__ //文件当前行号
__DATE__ //文件被编译的日期
__TIME__ //文件被编译的时间
__STDC__ //如果编译器遵循ANSI C,其值为1,否则为定义(VS不严格遵循ASNI C)
示例:

#define的应用
#define 是预处理指令
#include也是预处理指令
#define定义常量
基本语法:
#define name stuff
上图所示的name是常量的名字,stuff是常量的内容。
如图所示就是它的应用。

#define 定义的数据通常储存在寄存器中

以下是一些#define定义常量的应用

但是如果我们定义的stuff过多怎么办呢?我们可以分行,除了最后一行外每一行都用”\“结束

但是注意:#define 定义标识符的是后面不要加 “;”

显然,我们发现else语句报错了,这是为什么呢?
在如下所示的代码中if语句后面没有大括号,if语句只能有一个语句,出现一个空语句的时候就会报错
#define A 100;//这样写是不好的,错误示范
int main()
{int a = 10;if (a < 0)a = 100;;//等效于a=Aelsea = -100;;//等效于a=-Areturn 0;
}
#define定义宏
#define机制包括一个规定,允许把参数替换到文本中,通常称之为宏(macro)或者定义宏(define macro)
下面的是宏的声明方式
其中parament—list是逗号隔开的符号表,它们可能出现在stuff中。
#define name( parament——list) stuff
注意:()左侧必须紧挨着name,否则存在的任何空白会把(parament—list)中的内容认为是stuff中的一部分
举例:

但是如果表达式是这样的呢?

结果为:

预期结果为:121,但是实际结果为21
可能与你的预期结果不符,但是原理很简单:乘法运算优先级大于宏定义的加法运算
实际上r的值等于a+1*a+1,因此实际上r=10+10+1=21.
所以我们可以将宏改成这样
#define square(x) (x)*(x)
但是这样可能会产生新的问题:

预期结果200,实际结果如上
原理也很简单:printf打印的表达式结果本质上为:10*10+10
所以针对这个代码,我们要这么写
#define add(x) ((x)+(x))
因此我们可以知道:定义宏的时候涉及对数值表达式进行求值的宏定义都应该用这种方式加上括号,避免使用宏因为参数之间操作符或者临近操作符的相互作用导致不可预知的后果。
带有副作用的宏参数
当宏参数在宏定义中出现吵过一次后,如果参数带有副作用,使用宏就会出现危险,导致不可预知的后果。副作用就是表达式求指导时候出现的永久性效果。

举例说明:

在上图中,x和y分别为5和8,进入表达式后执行结果为x为6,y为9,执行b语句,返回给z的值为9,但是在这之后y还会++一次,因此y结果为10

宏替换的规则
在程序中扩展#define定义符号和宏的时候需要以下几个步骤
1.在调用宏的时候,首先对参数进行检查,看看是否包含任何由#define定义的符号。如果是,它们首先被替换。
2.替换文本中随后被插入到程序中原来文本中的位置。对于宏,参数名被它们的值所替换
3.最后,再次对结果文件进行扫描,看看它是否包含任何由#define定义的符号。如果是,就重复上述过程
注意:
1.宏参数和#define定义中可以出现其他#define定义的符号。但是对于宏,不能递归
2.当预处理器搜索#define定义的符号的时候,字符串常量的内容不进行搜索
因为预处理的时候会对宏进行预处理操作,预处理后代码和我们编写的代码会有所差异
函数和宏定义的区别
宏通常被应用于执行简单的运算。
如图所示

为什么会导致这两种截然不同的结果呢?
因为函数是先将参数的表达式计算好后带入函数的形参部分,宏定义是直接替换。
而在上述代码中,相较于函数,为什么宏更有优势呢?
原因有二:
1.用于调用函数和从函数返回的代码可能比实际执行这个计算的工作需要的时间小很多。所以宏比函数在程序的规模和速度方面更胜一筹
2.函数的参数必须要声明特定的类型。因此函数只适合在类型合适的表达式上使用。繁殖这个宏可以适用于整型、浮点型、长整型等可以用>进行比较的类型。宏的参数无关乎类型
和函数相比宏的劣势
1.每次使用宏一份宏定义插入程序中。当功能比较复杂的适合,宏定义内容很长,会大幅度增加程序的长度
2.宏没办法调试
3.宏与类型无关,不够严谨
4.宏可能会带来运算优先级的问题,可能导致程序出错。
以下是一个汇总的对比表格

#和##
#运算符
#运算符将红的一个参数转换为字符串字面量。仅允许出现在带宏参数的宏的替换列表中。
#运算符所执行的操作可以理解为“字符串化”
比如我们对于
int a=10;
的时候,我们想打印出:a的数值为10。我们就可以这样写
#define PRINTF(n) printf("“#n”的数值为%d",n)
我们按这种方式调用的时候
PRINTF(a);//我们将a替换到宏内,就出现了#a,而#a就是转换为“a”时的一个字符串。
//所以代码就会被处理:
printf(""a"的数值为%d",a);
运行代码就是
a的数值为10
##运算符
##可以把位于它两边的符号合成为一个符号,允许宏定义从分离的文本片段创建标识符。##被称之为记号粘合

但是请注意:这样的粘合必须产生一个合法的标识符。否则结果就是未定义
举例说明:
我们要写一段代码进行两个数字比较大小的时候,不同类型就要写不同的函数

实在是过于繁琐,我们可以将其改进一下:

当我们调用的时候

但是实际应用的时候##应用的并不算多。
命名约定
一般而言函数和宏的写法很相似,我们靠语言很难去区分它们。因此我们有个约定:
宏名全部大写
函数名不要全部大写
特例:
offsetof——宏
#undef
这条指令用去移除一个宏
#undef NAME
//当我们需要定义一个新的宏变量的时候,旧名需要去除
举例说明:
命令行定义
许多C的编辑器提供了一种能力,允许在命令行中定义符号。用于启动编译过程。
当我们根据同一个源文件编译出一个程序的不同版本的时候,这个特性有些用处(假定一个程序中声明了一个某一长度的数组,如果机器内存有限,我们要一个很小的数组,如果另一个机器内存很大我们需要一个大数组)
#include<stdio.h>
int main()
{int arr[arr_size];int i=o;int j=0;for(i=0;i<arr_size;i++){arr[i]=i;}for(i=0;i<arr_size;i++){printf("%d",arr[i]);}printf("\n");return 0;
}
(该代码需要在Linux系统环境下运行,VS无法进行验证。因为作者本人并没有相应的环境,因此作者只能借用别人的结果验证)
编译代码:
//Linux环境演示
gcc-test.c -D arr_size=10 -o test//这里D与arr_size之间是否留有空格均可。
结果为:

条件编译
因为我们有条件编译指令,在编译一个程序的时候我们如果要将一条语句(一组语句)编译或者方式是很方便的。
#include<stdio.h>
#define __DEBUG__
//当我们不用的时候将这段代码注释
int main()
{//code}
常见的条件编译指令:
1.
#if 常量表达式
//...
#endif
//常量表达式由预处理器求值2.多分枝条件编译#if
//... 常量表达式
#elif
//... 常量表达式
#else
//...
#endif
3.判断是否被定义
#if defined(symbol)
#ifdef symbol
#if !defined(symbol)
#ifndef symbol
4.嵌套指令
#if defined(OS_UNIX)#ifdef option1unix_version_option1();#endif#elif option2unix-version_option2();#endif
#elif defined(OS_MSDOS) #ifdef option2msdos_version_option2();#endif
#endif
标准库应用较多
头文件包含
头文件被包含的方式
1.本地头文件包含
#include"file.name"
查找策略:
先在源文件找,如果该头文件没找到,编译器就像查找库函数头文件一样在标准位置查找头文件/
如果找不到就提示编译错误。
2.库文件包含
#include<stdio.h>
直接去标准路径查找,如果找不到就提示编译错误
其实也可以用“”包含,但是这样查找效率更低,也不容易区分库文件和本地文件
3.嵌套文件包含
实际应用中,我们也可以这样
test.h
#include<stdio.h>
void test()
{
//code
}
struct person
{int id;char name[30];
}
test.c
#include"test.h"
#include"test.h"
#include"test.h"
#include"test.h"
#include"test.h"
如果这样写,test.c文件将test.h包含5次,即test.h的内容会被拷贝5份在test.c中
如果test.h文件比较大,这样预处理后代码量暴增。如果工程大头公共头文件,被大家使用又不做任何处理后果影响很严重。
如果解决这个问题呢?答案:条件编译
每个头文件开头写:
1.#ifndef __TEST_H__
2.#define __TEST_H__
3.头文件内容
4#endif//__TEST_H
或者也可以这样
1.#pragma once
这样就可以避免头文件重复引用。
注:
推荐《高质量C/C++编程指南》中的考试试卷(很重要)
1.头文件中ifndef/define/endif分别是干什么用的?
在C语言中,#ifndef、#define 和 #endif 是预处理指令,用于防止头文件被重复包含,避免因多次声明同一内容导致的编译错误(如重复定义函数、结构体等)。以下是它们的详细作用和使用方法:
1. 作用说明
-
#ifndef(if not defined)
检查是否未定义某个宏。如果未定义,则继续处理后续代码;如果已定义,则跳过直到#endif之间的所有代码。 -
#define
定义一个宏,标记该头文件已被包含。通常以头文件名的大写形式命名(如MY_HEADER_H),确保唯一性。 -
#endif
结束#ifndef的条件编译块。
2. 使用场景
当多个源文件(.c)包含同一个头文件(.h),或头文件之间互相嵌套包含时,可能导致同一段代码被重复包含。例如:
// 文件 "myheader.h"
struct Data {int value;
};
如果 myheader.h 被多次包含,编译器会报错:
error: redefinition of 'struct Data'。
3. 解决方法:添加头文件保护
// 文件 "myheader.h"
#ifndef MY_HEADER_H // 如果未定义 MY_HEADER_H
#define MY_HEADER_H // 定义 MY_HEADER_Hstruct Data {int value;
};#endif // 结束条件编译
效果:
-
第一次包含
myheader.h时,MY_HEADER_H未定义,代码被处理,同时定义宏MY_HEADER_H。 -
后续再次包含
myheader.h时,#ifndef检测到宏已存在,直接跳过整个内容,避免重复声明。
4. 注意事项
-
宏名称必须唯一
建议以头文件名的大写形式命名(如MY_HEADER_H),避免与其他头文件冲突。 -
与
#pragma once的区别-
#ifndef是C/C++标准方式,兼容所有编译器。 -
#pragma once是编译器扩展(如GCC、MSVC支持),更简洁高效,但非标准。
-
-
作用范围
头文件保护仅对当前文件有效,不同头文件仍需独立保护。
5. 示例对比
未使用头文件保护(报错):
#include "myheader.h"
#include "myheader.h" // 重复包含int main() {return 0;
}
// 编译报错:struct Data 重复定义
使用头文件保护(正常):
// myheader.h 添加了 #ifndef/#define/#endif
#include "myheader.h"
#include "myheader.h" // 第二次包含被跳过int main() {return 0;
}
// 编译通过!
总结
| 指令 | 作用 | 必要性 |
|---|---|---|
#ifndef | 检查宏是否未定义 | 必须 |
#define | 定义宏标记头文件已包含 | 必须 |
#endif | 结束条件编译块 | 必须 |
使用头文件保护是编写C语言头文件的最佳实践,能有效避免重复包含问题,确保代码可移植性和健壮性。
2.#include<filename.h>和#include"filename.h"有什么区别?
在C语言中,#include <filename.h> 和 #include "filename.h" 用于包含头文件,但它们的搜索路径和适用场景有本质区别:
核心区别
| 指令形式 | 搜索路径顺序 | 典型用途 |
|---|---|---|
#include <filename.h> | 1. 系统/编译器标准头文件目录 (如 /usr/include、编译器内置路径等) | 包含标准库头文件或系统级头文件 |
#include "filename.h" | 1. 当前源文件所在目录 2. 若未找到,再按 <filename.h> 的路径搜索 | 包含自定义头文件或项目本地头文件 |
详细说明
1. #include <filename.h>
-
适用场景:
用于包含标准库头文件(如stdio.h、math.h)或第三方库头文件(如通过系统包管理器安装的库)。 -
搜索机制:
编译器直接在预定义的系统头文件路径中查找文件,不会检查当前目录。 -
示例:
-
#include <stdio.h> // 标准输入输出库
#include <stdlib.h> // 标准库函数(如malloc)
2. #include "filename.h"
-
适用场景:
用于包含项目本地头文件(如自定义的myheader.h)。 -
搜索机制:
-
先在当前源文件所在目录查找文件;
-
若未找到,再按
<filename.h>的路径搜索(即系统目录)。
-
-
示例:
-
#include "utils.h" // 项目内的工具函数头文件
#include "config.h" // 本地配置文件
实际应用中的注意事项
-
区分使用场景
-
标准库必须用
< >,例如#include <string.h>。 -
自定义头文件应优先用
" ",例如#include "my_lib.h"。
-
-
路径配置
-
如果自定义头文件不在当前目录,可通过编译器的
-I选项指定搜索路径:
-
gcc -I/path/to/headers main.c -o main
-
-
此时,
#include "myheader.h"会先在/path/to/headers中查找。
-
-
兼容性与可读性
-
虽然
#include "stdio.h"可能也能编译(因为最终会回退到系统路径),但为了代码规范性和可读性,建议严格区分< >和" "。
-
-
重复包含问题
-
无论使用哪种方式,头文件中都应添加
#ifndef/#define/#endif或#pragma once防止重复包含(详见头文件保护机制)。
-
示例对比
场景:项目中包含自定义头文件
// 项目结构
project/
├── src/
│ └── main.c
└── include/
└── mylib.h
// main.c 中正确包含头文件
#include "../include/mylib.h" // 可行,但路径硬编码
// 或通过编译选项 -Iinclude/,直接写:
#include "mylib.h"
错误用法
#include <mylib.h> // 错误!编译器不会在项目目录中搜索此文件
总结
| 形式 | 目的 | 搜索路径 | 最佳实践 |
|---|---|---|---|
<filename.h> | 系统/标准库头文件 | 系统目录 → 编译器内置路径 | 标准库、第三方库 |
"filename.h" | 项目本地头文件 | 当前目录 → 系统目录(可扩展) | 自定义头文件、项目内文件 |
正确使用两种包含方式,可以避免路径错误、提升代码可维护性,并明确头文件来源。
其它预处理指令
#error
作用
强制触发编译错误,并显示自定义错误信息。通常用于条件编译中检测非法配置或代码依赖。
使用场景
-
检查编译器是否支持特定功能。
-
防止代码在不兼容的环境中编译。
示例
#ifndef REQUIRED_VERSION
#error "REQUIRED_VERSION must be defined!" // 触发错误并终止编译
#endif
编译输出:
error: #error "REQUIRED_VERSION must be defined!"
#pragma
作用
向编译器发送特定指令,用于启用或禁用编译器功能(如优化、警告控制等)。
注意:#pragma 的行为是编译器相关的,不同编译器可能支持不同的指令。
常见用法
-
禁用警告(如 GCC/Clang/MSVC):
-
#pragma warning(disable : 4996) // 在 MSVC 中禁用特定警告
-
优化控制:
-
#pragma GCC optimize("O0") // 在 GCC 中关闭优化
-
标记代码段:
-
#pragma region DebugCode // 在 IDE 中折叠代码块(如 MSVC)
// 调试代码...
#pragma endregion -
跨平台兼容性
不同编译器的
#pragma指令可能不兼容,需结合条件编译使用: -
#ifdef _MSC_VER
#pragma comment(lib, "mylib.lib") // 仅在 MSVC 中链接库
#endif
#line
作用
修改编译器报告的行号和文件名,主要用于代码生成工具(如 Lex/Yacc、预处理器生成的代码)中,使错误信息指向原始文件而非生成后的中间文件。
语法
#line <行号> ["文件名"]
示例
#line 100 "my_source.c" // 后续代码的行号从 100 开始,文件名标记为 my_source.c
int a = 10; // 若此代码出错,编译器会报告 my_source.c 的第 100 行
实际应用
在预处理后的代码中调整行号,方便调试:
#include <stdio.h>
#line 1 "original.c" // 强制将下一行视为 original.c 的第 1 行
int main() {
printf("Hello"); // 若此行出错,编译器显示 original.c:2
}
#pragma pack() (在结构体部分介绍)
作用
控制结构体(struct)或联合体(union)的内存对齐方式,通过指定对齐字节数优化内存布局或兼容特定硬件/协议要求。
语法
#pragma pack(n) // 设置对齐字节数为 n(1/2/4/8...)
#pragma pack() // 恢复默认对齐方式
#pragma pack(push, n) // 保存当前对齐方式并设置新对齐
#pragma pack(pop) // 恢复上一次保存的对齐方式
示例
#pragma pack(1) // 按 1 字节对齐(无填充)
struct Data {
char a; // 1 字节
int b; // 4 字节
}; // 结构体总大小 = 5 字节(默认对齐下可能为 8 字节)
#pragma pack() // 恢复默认对齐
使用场景
-
网络协议包解析(确保结构体与协议定义的字节对齐一致)。
-
硬件寄存器映射(精确控制内存布局)。
-
减少内存占用(但可能降低访问速度)。
注意事项
-
过度使用
#pragma pack(1)可能导致性能下降(未对齐内存访问在某些平台上较慢)。 -
跨平台代码需谨慎处理对齐问题(不同编译器/平台的默认对齐可能不同)。
-
总结
指令 用途 关键点 #error强制触发编译错误并显示信息 用于条件编译中的错误检查 #pragma向编译器发送特定指令(编译器相关) 控制优化、警告、链接等 #line修改编译器报告的行号和文件名 代码生成工具中调试友好 #pragma pack()控制结构体的内存对齐方式 优化内存布局或兼容硬件/协议要求 使用建议:
-
#error和#pragma常用于平台适配或代码健壮性检查。 -
#line主要在自动生成的代码中使用。 -
#pragma pack()需谨慎使用,避免破坏内存对齐的默认优化。
感谢看到这里的读者大大,作者在这里求一个赞,谢谢各位
相关文章:
C语言学习之预处理指令
目录 预定义符号 #define的应用 #define定义常量 #define定义宏 带有副作用的宏参数 宏替换的规则 函数和宏定义的区别 #和## #运算符 ##运算符 命名约定 #undef 编辑 命令行定义 条件编译 头文件包含 头文件被包含的方式 1.本地头文件包含 2.库文件包含 …...
【STM32单片机】#10 USART串口通信
主要参考学习资料: B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接:https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装:STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 实验&…...
fastlio用mid360录制的bag包离线建图,提示消息类型错误
我用mid360录制的bag包,激光雷达的数据类型是sensor_msgs::PointCloud2,但是运行fast_lio中的mid360 launch文件,会报错(没截图),显示无法从livox_ros_driver2::CustomMsg转换到sensor_msgs::PointCloud2。…...
二级评论列表-Java实现
二级评论列表是很常见的功能,文章记录了新手用Java实现的具体逻辑。 整体实现逻辑是先用2个sql,分别查出两层数据。然后用java在service中实现数据组装,返给前端。这种实现思路好处是SQL简洁,逻辑分明,便于维护。 一…...
IP检测工具“ipjiance”
目录 IP质量检测 应用场景 对网络安全的贡献 对网络管理的帮助 对用户决策的辅助作用 IP质量检测 检测IP的网络提供商:通过ASN(自治系统编号)识别IP地址所属的网络运营商,例如电信、移动、联通等。 识别网络类型࿱…...
mysql的函数(第二期)
九、窗口函数(MySQL 8.0) 适用于对结果集的子集(窗口)进行计算,常用于数据分析场景。 ROW_NUMBER() 作用:为每一行生成唯一的序号。示例:按分数降序排名 SELECT n…...
Replicate Python client
本文翻译整理自:https://github.com/replicate/replicate-python 文章目录 一、关于 Replicate Python 客户端相关链接资源关键功能特性 二、1.0.0 版本的重大变更三、安装与配置1、系统要求2、安装3、认证配置 四、核心功能1、运行模型2、异步IO支持3、流式输出模型…...
halcon模板匹配(八)alignment_for_ocr_in_semiconductor
目录 一、alignment_for_ocr_in_semiconductor例程目的二、创建训练和查找用于图像对齐三、图像对齐四、在指定区域内查找文本一、alignment_for_ocr_in_semiconductor例程目的 在一个图像中定义两个区域,一个用于图像对齐,在另一个区域内使用文本模板进行匹配。 二、创建训…...
Java读取JSON文件并将其中元素转为JSON对象输出
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Java读取JSON文件并将其中元素转为JSON对象输…...
华为openEuler操作系统全解析:起源、特性与生态对比
华为openEuler操作系统全解析:起源、特性与生态对比 一、起源与发展历程 openEuler(欧拉操作系统)是华为于2019年开源的Linux发行版,其前身为华为内部研发的服务器操作系统EulerOS。EulerOS自2010年起逐步发展,支持华…...
Elasticsearch使用及常见的问题
Elasticsearch作为一款分布式搜索与分析引擎,其核心优势在于高性能搜索能力,依托倒排索引和分布式架构,可快速处理海量数据及复杂查询,支持实时索引与动态扩容,兼具高可用性和扩展性。其丰富的RESTful API与查询语言降…...
Python基础总结(七)之条件语句
文章目录 条件语句if一、Python中的真假二、条件语句格式2.1 if语句格式2.2 if-else语句2.3 if-elif-else语句 三、if语句嵌套 条件语句if 条件语句其实就是if语句,在讲解if语句之前需要知道Python中对于真假的判断。 一、Python中的真假 在Python中非0的都为真&…...
命令update-alternatives
❯ which pip /home/ying/anaconda3/bin/pipying192 ~ [2]> which pip /usr/bin/pip使用update-alternatives对他们进行管理和切换 快捷方式 和 实际路径不可以相同 所以我这边选择了/usr/local/bin目录作为介质存储快捷方式,另外该快捷方式会自己创建我们只需选…...
deekseak 本地windows 10 部署步骤
有些场景需要本地部署,例如金融、医疗(HIPAA)、政府(GDPR)、军工等,需完全控制数据存储和访问权限,避免云端合规风险或者偏远地区、船舶、矿井等无法依赖云服务,关键设施(…...
MySQL中常用函数的分类及示例
概述 以下是 MySQL 中常用函数的分类及示例,涵盖字符串处理、数值计算、日期操作、条件判断等常见场景: 一、字符串函数 1. CONCAT(str1, str2, ...) 拼接字符串。 SELECT CONCAT(Hello, , World); -- 输出: Hello World2. SUBSTRING(str, start,…...
<sql>、<resultMap>、<where>、<foreach>、<trim>、<set>等标签的作用和用法
目录 一. sql 代码片段标签 二. resultMap 映射结果集标签 三. where 条件标签 四. set 修改标签 五. trim 标签 六. foreach 循环标签 一. sql 代码片段标签 sql 标签是 mybatis 框架中一个非常常用的标签页,特别是当一张表很有多个字段多,或者要…...
企业级HAProxy高可用离线部署实战(附Kubernetes APIServer负载均衡配置)
企业级HAProxy高可用离线部署实战(附Kubernetes APIServer负载均衡配置) 摘要:本文深入讲解在离线环境下部署HAProxy 3.1.1的全流程,涵盖源码编译、系统服务封装、K8S APIServer四层负载配置等核心环节,并提供生产级高…...
实现Azure Databricks安全地请求企业内部API返回数据
需要编写一个Databricks在Azure云上运行,它需要访问企业内部的API获取JSON格式的数据,企业有网关和防火墙,API有公司的okta身份认证,通过公司的域账号来授权访问,现在需要创建一个专用的域账号,让Databrick…...
kafka认证部署
首先启动 zookeeper /home/kafka/bin/zookeeper-server-start.sh /home/kafka/config/zookeeper.properties 创建SCRAM证书 /home/kafka/bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config SCRAM-SHA-256[iterations8192,passwordliebe],SCRAM-SHA-512[p…...
【项目】CherrySudio配置MCP服务器
CherrySudio配置MCP服务器 (一)Cherry Studio介绍(二)MCP服务环境搭建(1)环境准备(2)依赖组件安装<1> Bun和UV安装 (3)MCP服务器使用<1> 搜索MCP…...
【LeetCode 热题 100】双指针 系列
📁283. 移动零 对于该题目,需要注意的是两个地方,一是保持非零元素的相对顺序,以及O(1)的空间复杂度。 采用双指针的思路,将数组划分成3个区间,。 [0 , left]:该区间内元素全是非零元素。 [left1 , right…...
【技术派后端篇】 Redis 实现用户活跃度排行榜
在各类互联网应用中,排行榜是一个常见的功能需求,它能够直观地展示用户的表现或贡献情况,提升用户的参与感和竞争意识。在技术派项目中,也引入了用户活跃度排行榜,该排行榜主要基于 Redis 的 ZSET 数据结构来实现。接下…...
模拟算法(一)作业分析及答案
目录 作业1:角谷猜想 解题思路 : 代码实现: 作业2:校门外的树 解题思路 注意事项 代码实现 作业3:乒乓球 编辑 问题重述 解题思路: 作业1:角谷猜想 【描述】 所谓角谷猜想…...
西红柿番茄检测数据集VOC+YOLO格式2320张1类别可用于计数
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2320 标注数量(xml文件个数):2320 标注数量(txt文件个数):2320 …...
企业级实战:将Java服务打包为Docker镜像的两种高效方法
企业级实战:将Java服务打包为Docker镜像的两种高效方法 摘要:本文针对Java服务容器化部署场景,提供 基于容器Commit 和 Dockerfile构建 两种镜像制作方案。重点解决动态库依赖、信号量配置、环境变量注入等企业级痛点问题,并提供…...
专题十六:虚拟路由冗余协议——VRRP
一、VRRP简介 VRRP(Virtual Router Redundancy Protocol)虚拟路由冗余协议通过把几台设备联合组成一台虚拟的设备,使用一定的机制保证当主机的下一跳设备出现故障时,及时将业务切换到备份设备,从而保持通讯的连续性和…...
Java中常见的锁synchronized、ReentrantLock、ReentrantReadWriteLock、StampedLock
在Java中,锁是实现多线程同步的核心机制。不同的锁适用于不同的场景,理解其实现原理和使用方法对优化性能和避免并发问题至关重要。 一、隐式锁:synchronized 关键字 实现原理 基于对象监视器(Monitor):每…...
DDPM(diffusion)原理
DDPM(diffusion)原理 1、DDPM(原理)2、DDPM和 Conditional DDPM(原理解释)2.1. Diffusion Models 原理详解核心思想前向扩散过程(Forward Diffusion)反向去噪过程(Revers…...
《软件设计师》复习笔记(2.2)——效验码、体系结构、指令、流水线
目录 一、校验码 码距 奇偶校验码 循环冗余校验码(CRC) 海明码 真题示例: 二、体系结构 Flynn分类法 三、指令系统 指令组成 指令执行过程 指令的寻址方式 操作数的寻址方式 CISC vs RISC 真题示例: 四、流水线技…...
BT1120 BT656驱动相关代码示例
前些年做视频输出项目的时候用过bt1120 tx与rx模块,现将部分代码进行记录整理。代码功能正常,可正常应用。 1. rx部分: /****************************************************************************** Copyright (C) 2021,All rights …...

