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.库文件包含 …...
腾讯wxg企业微信 后端开发一面
UDP安全吗,怎么修改让其安全? packet header QUIC FrameHeader TCP的三个窗口 滑动 发送 拥塞, 怎么用UDP使用类似的功能 怎么确认消息是否收到? TCP的拥塞控制是怎么样的 HTTPS的握手流程 MySQL为什么用B树 红黑树等结构也能在叶子节点实现…...
【Hot100】 73. 矩阵置零
目录 引言矩阵置零我的解题优化优化思路分步解决思路为什么必须按照这个顺序处理?完整示例演示总结 🙋♂️ 作者:海码007📜 专栏:算法专栏💥 标题:【Hot100】 73. 矩阵置零❣️ 寄语ÿ…...
c++_csp-j算法 (2)
目录 BFS搜索(广度优先搜索) 讲解 BFS搜索算法原理 BFS搜索算法实现 BFS搜索算法的应用 例题(1) P1032 [NOIP 2002 提高组] 字串变换 例题(2) P1443 马的遍历 BFS搜索(广度优先搜索) 讲解 BFS搜索算法原理 广度优先搜索(BFS)算法是一种图的搜索算法,用于遍历…...
学习笔记: Mach-O 文件
“结构决定性质,性质决定用途”。如果不了解结构,是很难真正理解的。 通过一个示例的可执行文件了解Mach-O文件的结构 Mach-O基本结构 Header: :文件类型、目标架构类型等Load Commands:描述文件在虚拟内存中的逻辑结构、布局Data: 在Load commands中…...
基于GRPO将QWEN训练为和deepseek一样的推理模型!
GRPO 群体相对策略优化(GRPO)算法最初由deepseek团队提出,是近端策略优化(PPO)的一个变体。 GRPO 是一种在线学习算法,它通过使用训练过程中已训练模型自身生成的数据进行迭代改进。GRPO 目标背后的逻辑是在确保模型与参考策略保…...
STM32 外部中断EXTI
目录 外部中断基础知识 STM32外部中断框架 STM32外部中断机制框架 复用功能 重映射 中断嵌套控制器NVIC 外部中断按键控制LED灯 外部中断基础知识 STM32外部中断框架 中断的概念:在主程序运行过程中,出现了特点的中断触发条件,使得…...
Codex CLI - 自然语言命令行界面
本文翻译整理自:https://github.com/microsoft/Codex-CLI 文章目录 一、关于 Codex CLI相关链接资源 二、安装系统要求安装步骤 三、基本使用1、基础操作2、多轮模式 四、命令参考五、提示工程与上下文文件自定义上下文 六、故障排查七、FAQ如何查询可用OpenAI引擎&…...
健身会员管理系统(ssh+jsp+mysql8.x)含运行文档
健身会员管理系统(sshjspmysql8.x) 对健身房的健身器材、会员、教练、办卡、会员健身情况进行管理,可根据会员号或器材进行搜索,查看会员健身情况或器材使用情况。...
数据结构——快排和归并排序(非递归)
快速排序和归并排序一般都是用递归来实现的,但是掌握非递归也是很重要的,说不定在面试的时候面试官突然问你快排或者归并非递归实现,递归有时候并不好,在数据量非常大的时候效率就不好,但是使用非递归结果就不一样了&a…...
Trae,字节跳动推出的 AI 编程助手插件
Trae 插件是 Trae 旗下全新一代的人工智能编程助手(前身为 MarsCode 编程助手),以插件形式集成在本地开发环境中,具备极高的兼容性和灵活性,旨在提升开发效率和代码质量。它支持超过100种编程语言,兼容主流…...
Qt项目——Tcp网络调试助手服务端与客户端
目录 前言结果预览工程文件源代码一、开发流程二、Tcp协议三、Socket四、Tcp服务器的关键流程五、Tcp客户端的关键流程六、Tcp服务端核心代码七、客户端核心代码总结 前言 这期要运用到计算机网络的知识,要搞清楚Tcp协议,学习QTcpServer ,学…...
2021-11-10 C++蜗牛爬井进3退1求天数
缘由C大一编程题目。-编程语言-CSDN问答 int n 0, t 0;cin >> n;while ((n - 3)>0)n, t;cout << t << endl;...
玛哈特整平机:工业制造中的关键设备
在现代工业制造中,平整度是衡量材料加工质量的核心指标之一。无论是金属板材、塑料片材还是复合材料,若存在弯曲、翘曲或波浪形缺陷,将直接影响后续加工效率和成品质量。整平机(又称校平机、矫平机)作为解决这一问题的…...
LINUX419 更换仓库(没换成)find命令
NAT模式下虚拟机需与网卡处在同一个网段中吗 和VM1同个网段 会不会影响 这个很重要 是2 改成点2 倒是Ping通了 为啥ping百度 ping到别的地方 4399 倒是ping通了 准备下载httpd包 下不下来 正在替换为新版本仓库 报错 failure: repodata/repomd.xml from local: [Er…...
C# 预定义类型全解析
在 C# 编程中,预定义类型是基础且重要的概念。下面我们来详细了解 C# 的预定义类型。 预定义类型概述 C# 提供了 16 种预定义类型,包含 13 种简单类型和 3 种非简单类型。所有预定义类型的名称都由全小写字母组成。 预定义简单类型 预定义简单类型表…...
【仓颉 + 鸿蒙 + AI Agent】CangjieMagic框架(16):ReactExecutor
CangjieMagic框架:使用华为仓颉编程语言编写,专门用于开发AI Agent,支持鸿蒙、Windows、macOS、Linux等系统。 这篇文章剖析一下 CangjieMagic 框架中的 ReactExecutor。 这个执行器名字中的"React"代表"Reasoning and Acti…...
13.第二阶段x64游戏实战-分析人物等级和升级经验
免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 本次游戏没法给 内容参考于:微尘网络安全 上一个内容:12.第二阶段x64游戏实战-远程调试 效果图: 如下图红框,…...
Linux疑难杂惑 | 云服务器重装系统后vscode无法远程连接的问题
报错原因:本地的known_hosts文件记录服务器信息与现服务器的信息冲突了,导致连接失败。 解决方法:找到本地的known_hosts文件,把里面的所有东西删除后保存就好了。 该文件的路径可以在报错中寻找:比如我的路径就是&a…...
使用EXCEL绘制平滑曲线
播主播主,你都多少天没更新了!!!泥在干什么?你还做这个账号麻?!!! 做的做的(哭唧唧),就是最近有些忙,以及…… 前言&…...
你的电脑在开“外卖平台”?——作业管理全解析
你的电脑在开“外卖平台”?——作业管理全解析 操作系统系列文章导航(点击跳转) 程序员必看:揭开操作系统的神秘面纱 :从进程、内存到设备管理,全面解析操作系统的核心机制与日常应用。告别电脑卡顿&#x…...
平均池化(Average Pooling)
1. 定义与作用 平均池化是一种下采样操作,通过对输入区域的数值取平均值来压缩数据空间维度。其核心作用包括: 降低计算量:减少特征图尺寸,提升模型效率。保留整体特征:平滑局部…...
JavaScript中的Event事件对象详解
一、事件对象(Event)概述 1. 事件对象的定义 event 对象是浏览器自动生成的对象,当用户与页面进行交互时(如点击、键盘输入、鼠标移动等),事件触发时就会自动传递给事件处理函数。event 对象包含了与事件…...
OSPF综合实验(HCIP)
1,R5为ISP,其上只能配置Ip地址;R4作为企业边界路由器, 出口公网地址需要通过ppp协议获取,并进行chap认证 2,整个OSPF环境IP基于172.16.0.0/16划分; 3,所有设备均可访问R5的环回&…...
Unreal 从入门到精通之如何接入MQTT
文章目录 前言MQTT 核心特性MQTT 在 UE5 中的应用场景在 UE5 中集成 MQTTMqtt Client 的APIMqtt Client 使用示例最后前言 MQTT(Message Queuing Telemetry Transport)是一种专为物联网(IoT)和低带宽、高延迟网络环境设计的轻量级消息传输协议。它采用发布/订阅(Pub/Sub)…...
数据结构实验6.2:稀疏矩阵的基本运算
文章目录 一,实验目的二,问题描述三,基本要求四、算法分析(一)稀疏矩阵三元组表示法存储结构(二)插入算法(三)创建算法(四)输出算法(五…...
BDO分厂积极开展“五个一”安全活动
BDO分厂为规范化学习“五个一”活动主题,按照“上下联动、分头准备 、差异管理、资源共享”的原则,全面激活班组安全活动管理新模式,正在积极开展班组安全活动,以单元班组形式对每个班组每周组织一次“五个一”安全活动。 丁二醇单…...
那就聊一聊mysql的锁
MySQL 的锁机制是数据库并发控制的核心,作为 Java 架构师需要深入理解其实现原理和适用场景。以下是 MySQL 锁机制的详细解析: 一、锁的分类维度 1. 按锁粒度划分 锁粒度特点适用场景全局锁锁定整个数据库(FLUSH TABLES WITH READ LOC…...
Python番外——常用的包功能讲解和分类组合
目录 1. Web开发框架与工具 2. 数据处理与分析 3. 网络请求与爬虫 4. 异步编程 5. 数据库操作 6. 图像与多媒体处理 7. 语言模型与NLP 8. 安全与加密 9. 配置与工具 10. 其他工具库 11.典型组合场景 此章节主要是记录我所使用的包,以及模块。方便供自己方…...
【mongodb】数据库操作
目录 1. 查看所有数据库2. 切换到指定数据库(若数据库不存在,则创建)3. 查看当前使用的数据库4. 删除当前数据库5.默认数据库 1. 查看所有数据库 1.show dbs2.show databases 2. 切换到指定数据库(若数据库不存在,则…...
四月下旬系列
CUHKSZ 校赛 期中考试 DAY -1。 省流:前 1h 切 6 题,后 3h 过 1 题,读错一个本来很【】的题,被大模拟构造创【】了。 本地除了 VSCode 没有 Extensions,别的和省选差不多。使用 DEVC。 前 6 题难度 < 绿&#x…...
计算机网络 3-4 数据链路层(局域网)
4.1 局域网LAN 特点 1.覆盖较小的地理范围 2.较低的时延和误码率 3.局域网内的各节点之间 4.支持单播、广播、多播 分类 关注三要素 (出题点) ①拓扑结构 ②传输介质 ③介质访问控制方式 硬件架构 4.2 以太网 4.2.1 层次划分 4.2.2 物理层标准…...
WebSocket介绍
在网页聊天项目中,为了实现消息的发送和及时接收,我们使用了WebSocket,接下来就简单介绍一下这个WebSocket。 了解消息的转发逻辑 当两个不同客户端在不同的局域网中互相发送消息时,假如这两个客户端分别是a和b,因为…...
rpcrt4!COMMON_AddressManager函数分析之和全局变量rpcrt4!AddressList的关系
第一部分: 1: kd> x rpcrt4!addresslist 77c839dc RPCRT4!AddressList 0x00000000 1: kd> g Breakpoint 2 hit RPCRT4!OSF_ADDRESS::CompleteListen: 001b:77c0c973 55 push ebp 1: kd> g Breakpoint 11 hit RPCRT4!COMMON_Addr…...
Java Web 之 Tomcat 100问
Tomcat 是什么? Tomcat 是一个开源的 Java Servlet 容器和 Web 容器。 Tomcat 的主要功能有哪些? 三大主要功能: 运行 Java Web 应用。处理 HTTP 请求。管理 Web 应用。 如何安装 Tomcat ? 下载 Tomcat 安装包(A…...
ESB —— 企业集成架构的基石:功能、架构与应用全解析
企业服务总线(Enterprise Service Bus,ESB)是一种重要的企业级集成架构,以下为你详细介绍: 一、概念与定义 ESB 是一种基于面向服务架构(SOA)的中间件技术,它充当了企业内部不同应…...
wordpress SMTP配置qq邮箱发送邮件,新版QQ邮箱授权码获取方法
新版的QQ邮箱界面不同了,以下是新版的设置方法: 1. 进入邮箱后,点右上角的设置图标: 2. 左下角的菜单里,选择“账号与安全” : 3. 然后如下图,开启SMTP 服务: 4. 按提示验证短信&am…...
【操作系统原理04】进程同步
文章目录 大纲一.进程同步与进程互斥0.大纲1.同步2.互斥 二.进程互斥的软件实现方法0.大纲1.单标志法2.双标志先检查法3.双标志后检查法4.Peterson算法 三.进程互斥的硬件实现方法0.大纲1.中断屏蔽方法2.TestAndSet指令3.Swap指令 四.互斥锁五.信号量机制0.大纲1.概念2.整形信号…...
Java ThreadPoolExecutor 深度解析:从原理到实战
在 Java 的多线程编程领域,ThreadPoolExecutor是一个至关重要的工具类,它为开发者提供了强大且灵活的线程池管理能力。合理使用ThreadPoolExecutor,不仅能够提升应用程序的性能和响应速度,还能有效控制资源消耗,避免因…...
MCP 协议——AI 世界的“USB-C 接口”:解锁智能协作的新时代
在过去十年中,科技的进步已经改变了我们日常生活的方方面面。从智能手机的普及到物联网的快速发展,人们的生活被各种创新的技术重新定义。今天,我们即将迎来另一个里程碑式的转折点——MCP 协议的推出,它将为人工智能世界的协作与…...
知识就是力量——一些硬件的使用方式
硬件平台 正点原子ATK-MD0430 V2.0(4.3寸TFT LCD电容触摸屏/使用cc2530控制)1.硬件连接2. 软件驱动实现3. 优化与注意事项4. 示例工程参考5. 常见问题 正点原子ATK-MD0430 V2.0(4.3寸TFT LCD电容触摸屏/使用cc2530控制) 1.硬件连…...
机器学习(1)— 开发环境安装
机器学习(1)— 准备开发环境 一、前言 二、Ubuntu开发环境安装 1、NumPy安装 使用如下命令安装: sudo apt-get install python3-numpy2、PyTorch 安装 由于我电脑暂时没有英伟达显卡,暂时安装CPU版: pip3 insta…...
深入实战:使用C++开发高性能RESTful API
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开…...
C++之虚函数 Virtual Function
1. 普通虚函数(Virtual Function) 定义:基类中用 virtual 声明,允许派生类 覆盖(Override)。特点: 基类可提供默认实现。派生类可选择性覆盖(若不覆盖,则调用基类版本&a…...
【java实现+4种变体完整例子】排序算法中【选择排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
以下是选择排序的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格: 一、选择排序基础实现 原理 每一轮遍历未排序部分,找到最小元素并交换到当前起始位置,逐步构建已排序序列。 代码示例 pu…...
DNS主从同步实验
dns域名解析原理 实验步骤1、主dns要完成dns解析:192.168.21.128 [rootlocalhost ~]# yum install bind -y [rootlocalhost ~]# systemctl start named [rootlocalhost ~]# vim /etc/named.conf options { listen-on port 53 { any; }; direct…...
UIjavaScritIU
1、直接执行js脚本:document.documentElement.scrollTop1000 document.getElementById(“su”).click() 弊端: js自己带的元素定位方法不如selenium的丰富 不支持xpath css 等 定位元素操作不是很灵活。 需要借助js脚本传入 -selenium定位 js 负责执行动…...
Manus技术架构、实现内幕及分布式智能体项目实战 线上高级实训班
Manus技术架构、实现内幕及分布式智能体项目实战 线上高级实训班 模块一:解密Manus分布式多智能体工作原理和架构内幕 基于Claude和Qwen的大模型智能体Manus为何能够迅速成为全球讨论热度最高、使用体验最好、产业界最火爆的大模型智能体产品? Ma…...
Java——二维数组
一、概念 二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组容器。 二、定义格式 1.数据类型[ ] [ ] 变量名; 2.数据类型 变量名 [ ] [ ]; 3.数据类型 [ ] 变量名 [ ]; 三、动态初始化 (一)书写 1.格式 数据…...
豆瓣图书数据采集与可视化分析(一)- 豆瓣图书数据爬取
文章目录 前言一、数据爬取步骤二、豆瓣图书页面分析1. 图书分类标签页面分析2. 图书页面分析 三、数据采集实现1. 图书分类标签数据采集2. 图书数据采集3. 把多个分类的CSV数据文件整合到一个CSV文件中 前言 在当今大数据时代,数据的获取与整理对于各个领域的研…...