C/C++语言知识点一
目录
1. 请对这段代码进行解释:char *const *(*next)( );
2. 函数指针数组:解释这个表达式char *(*c[10])(int **p);
3. 字符串常量:分析下面这段代码。
4. 访问指定内存地址
5. typedef 和 define 的区别
6. 函数返回局部变量地址问题
7. 无符号整数和有符号整数相加问题
8. 大端模式和小端模式如何用代码判断
9. 显示无符号int类型的最大值和最小值
10. 逻辑运算符 (&&) 和 位运算符 (&)
11. printf函数的返回值
12. 通过#运算符,利用宏参数来创建字符串
13. “##” 运算符的作用
14. 结构体中使用字符数组还是字符指针
15. 内存越界问题
16. free 和 delete 是如何处理指针
1. 请对这段代码进行解释:char *const *(*next)( );
next是一个函数指针,指向一个没有参数的函数,并且该函数的返回值是一个指针,该指针指向一个类型为char的常量指针。
1.(*next)表示next是一个指针,指向某个函数,因为后面跟着(),所以这个指针指向一个函数。
2.next是一个函数指针,函数 (*next)() 的返回类型是 char *const * :最外层 *:返回值是一个指针const:该指针是常量(指针本身不可修改)char *:这个常量指针指向一个 char 类型的指针
3.char *const,这表示一个指向char的指针,而且这个指针是const的,也就是说,它指向的地址不能被修改。
讨论:我认为,char * const *(*next)( )指的是,返回值为char * const *(这是一个char类型的二级指针)的函数指针,我们把p代指这个二级指针,这个p具有的特点为,p的值可以改变,*p的值不能改变,**p的值可以改变,因为const的原理是它后面修饰的变量不能改变,而在p中const后面只有一个*,所以仅*p不能改变其值。
2. 函数指针数组:解释这个表达式char *(*c[10])(int **p);
c 是一个数组,包含 10 个函数指针,每个函数指针指向的函数接受一个 int ** 类型的参数,并返回一个 char * 类型的结果。
char *(*c[10])(int **p);
分析:c 是一个数组,包含10个元素,每个元素是函数指针;*c 表示数组的每个元素都是指针;(*c) 后的 (int **p) 表示这些指针指向函数,且函数接受一个 int** (指向整型指针的指针)类型的参数;最外层的 char * 表示这些函数返回 字符指针(char*)。
螺旋法则(Clockwise/Spiral Rule)详解:
螺旋法则是 解析C语言复杂声明 的核心方法,由计算机科学家 David Anderson 提出。它通过从变量名出发,按顺时针方向(螺旋式)解析修饰符,帮助开发者直观理解多层指针、数组和函数组合的声明。
解析步骤(四步法则):
- 起点:从变量名(标识符)开始
- 方向:按顺时针方向(优先向右,无法继续时向左)解析修饰符
- 优先级:
()>[]>*- 终止:处理完所有修饰符或遇到结束符
;
3. 字符串常量:分析下面这段代码。
char *s = "AAA";
printf("%s", s);
s[0] = 'B';
printf("%s", s);
解析:s[0] = 'B'; 这行代码试图修改字符串常量的第一个字符,这是不安全的,因为字符串常量通常存储在只读内存区域。
4. 访问指定内存地址
问题:嵌入式系统经常需要程序员访问特定的内存位置,读取或写入新的值,尤其是在嵌入式处理器开发中操作寄存器时。例如,在某个项目中,需要设置一个绝对内存地址为0x40020800的位置,并将该地址的内容设置为整数值0x3456。现在需要编写代码来完成这个任务。
考点:访问地址时,强制类型转换,强制为一个整形数,该操作是合法 的。
#include <stdint.h> // 包含标准整型定义// 方法1:直接指针操作
*(volatile uint32_t *)0x40020800 = 0x3456;// 方法2:宏定义(推荐)
#define REGISTER_ADDR ((volatile uint32_t *)0x40020800)
*REGISTER_ADDR = 0x3456;// 方法3:通过结构体映射(适用于多寄存器场景)
typedef struct {volatile uint32_t reg;
} DeviceReg;DeviceReg *const device = (DeviceReg *)0x40020800;
device->reg = 0x3456;// 方法4:创建一个指向特定地址的指针
volatile uint32_t *reg = (uint32_t *)0x40020800;
*reg = 0x3456;
注意:
1. 是否需要使用volatile关键字?是的,因为访问硬件寄存器必须使用volatile,防止编译器优化掉写入操作,或者重复读取时使用缓存的值。
2. uint32_t 和 unsigned int 的主要区别在于大小的固定性。uint32_t 始终是32位,而 unsigned int 的大小可能会因平台而异。在跨平台编程、嵌入式系统或处理网络协议和文件格式时,使用 uint32_t 可以确保数据类型的精确匹配,避免溢出或截断问题。
5. typedef 和 define 的区别
5.1 功能与行为
(1)#define 是预处理指令,在编译前进行文本替换。#define INT_PTR int *INT_PTR a, b; // 展开为 int *a, b; (b 是 int 类型,非指针)
(2)typedef 是类型别名定义,由编译器处理,创建新的类型名称。typedef int *INT_PTR;INT_PTR a, b; // a 和 b 都是 int* 类型
5.2 作用域
(1)#define 从定义点开始,到文件末尾或 #undef 取消定义为止。无块作用域,不可在局部范围内定义。
void func() {#define LOCAL_MACRO 10 // 宏定义作用域为整个文件
}
(2)typedef 支持块作用域,可在局部范围内定义。
void func() {typedef int MyInt; // 类型别名作用域为 func 函数内MyInt a = 10;
}
5.3 类型检查
#define 无类型检查,直接替换文本,可能导致意外错误。
typedef 由编译器处理,支持类型检查,语义更明确。
5.4 复杂类型支持
#define 需要额外括号和小心使用,否则可能出错。
#define FUNC_PTR int (*)(int)
FUNC_PTR f1, f2; // 展开为 int (*f1)(int), f2; (f2 是 int 类型,非函数指针)
typedef 直接支持复杂类型,语法更清晰。
typedef int (*FUNC_PTR)(int);
FUNC_PTR f1, f2; // f1 和 f2 都是函数指针类型
5.5 与 const 结合
#define 宏替换可能导致意外结果。
#define PTR int *
const PTR a = NULL; // 展开为 const int *a = NULL; (a 是指向常量的指针,非常量指针)
typedef 语义明确,与 const 结合行为可预测。
typedef int *PTR;
const PTR a = NULL; // a 是常量指针,类型为 int *const
5.6 使用场景对比
适合使用 #define 的场景:
// 1.定义常量:
#define PI 3.14159// 2.条件编译:
#define DEBUG
#ifdef DEBUG
printf("Debug mode\n");
#endif// 3.简单文本替换:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
适合使用 typedef 的场景:
// 1.定义类型别名:
typedef unsigned char uint8_t;// 2.简化复杂类型:
typedef int (*FuncPtr)(int, int);// 3.提高代码可读性:
typedef struct {int x;int y;
} Point;
6. 函数返回局部变量地址问题
问题:请指出下面这段代码的错误。
#include <stdio.h>char *get_str(void);int main(void)
{char *p = get_str();printf("%s\n", p);return 0;
}char *get_str(void)
{char str[] = {"abcd"};return str;
}
问题分析
-
局部变量的生命周期
-
get_str函数中,str是一个 局部数组,其内存分配在栈上。 -
当
get_str函数返回时,str的内存会被释放,返回的指针指向 无效内存。
-
-
未定义行为
-
在
main函数中,p指向了get_str返回的地址,但此时该地址的内容已经无效。 -
访问
p会导致 未定义行为(程序可能崩溃、输出乱码或看似正常但存在隐患)。
-
如何修改:
方案1:返回静态局部变量(不推荐)
将 str 声明为 static,使其生命周期延长到程序结束:
char *get_str(void)
{static char str[] = {"abcd"}; // 静态局部变量return str;
}
- 优点:简单直接,程序可以正确运行。
- 缺点:静态局部变量在程序运行期间始终占用内存,且多线程环境下不安全。
方案2:返回字符串常量(推荐)
直接返回字符串常量,常量存储在只读内存中,生命周期为整个程序:
char *get_str(void)
{return "abcd"; // 字符串常量
}
- 优点:简单高效,内存安全。
- 缺点:返回的字符串不可修改(只读)。
方案3:返回字符串常量的地址
#include <stdio.h>char *get_str(void);int main(void)
{char *p = get_str();printf("%s\n", p); // 输出 "abcd"return 0;
}char *get_str(void)
{char *str = {"abcd"}; // 指针指向字符串常量return str;
}
- 优点:程序可以正确运行,不会出现未定义行为。
- 缺点:返回的字符串不可修改(只读)。但是,这种用法仍然存在问题,因为它违反了函数的封装性,即函数的实现细节(如返回字符串常量的指针)应该对调用者隐藏。
方案4:动态分配内存(推荐)
使用 malloc 动态分配内存,返回堆上的地址:
#include <stdio.h>
#include <stdlib.h> // 引入stdlib.h以使用malloc和freechar *get_str(void);int main(void)
{char *p = get_str();if (p != NULL) {printf("%s\n", p);free(p); // 释放内存}return 0;
}char *get_str(void)
{char *str = (char *)malloc(5 * sizeof(char)); // 动态分配内存if (str == NULL) {return NULL; // 如果内存分配失败,返回NULL}strcpy(str, "abcd"); // 复制字符串到动态分配的内存return str;
}
- 优点:返回的字符串可修改,内存管理灵活。
- 缺点:需要手动释放内存,否则会导致内存泄漏。
7. 无符号整数和有符号整数相加问题
段代码的目的是检查两个整数相加的结果是否大于6,并根据结果输出相应的字符串。
#include <stdio.h>int main(void)
{unsigned int a = 6; // 无符号整数int b = -20; // 有符号整数(a + b > 6) ? puts(">6") : puts("<=6");return 0;
}
注意:
1.在 C 语言中,当无符号整数和有符号整数混合运算时,有符号整数会 隐式转换 为无符号整数。
2.在计算机中,整数通常以补码的形式存储。
3.负数的补码
a + b的实际计算过程:a是无符号整数,值为6。b被转换为无符号整数,其值为UINT_MAX - 19(假设unsigned int是 32 位,则值为4294967276)。- 因此,
a + b的值为6 + 4294967276 = 4294967282。

8. 大端模式和小端模式如何用代码判断
- 大端模式:数据的 高位字节 存储在内存的 低地址 处。
- 小端模式:数据的 低位字节 存储在内存的 低地址 处。
方法1:通过检查一个多字节数据(如 int)在内存中的存储方式,可以判断当前系统的字节序。
#include <stdio.h>int is_little_endian() {int num = 1; // 定义一个整数char *p = (char *)# // 将整数的地址转换为 char*return *p == 1; // 检查第一个字节是否为 1
}int main() {if (is_little_endian()) {printf("小端模式\n");} else {printf("大端模式\n");}return 0;
}
方法二:使用联合体判断。联合体的特性是 所有成员共享同一块内存,因此可以通过联合体访问同一数据的不同字节。
#include <stdio.h>int is_little_endian() {union {int num; // 多字节类型char c; // 单字节类型} u;u.num = 1; // 将联合体的 int 成员设为 1,其二进制表示为 0x00000001return u.c == 1; // 检查 char 成员是否为 1
}int main() {if (is_little_endian()) {printf("小端模式\n");} else {printf("大端模式\n");}return 0;
}
9. 显示无符号int类型的最大值和最小值
为了正确地获取当前系统下 unsigned int 类型的最大值,可以使用 UINT_MAX 宏,这个宏定义在 <limits.h> 或 limits 头文件中:
#include <stdio.h>
#include <limits.h>int main() {unsigned int zero = 0;unsigned int max_value = UINT_MAX;printf("The value of 0 for unsigned int: %u\n", zero);printf("The maximum value for unsigned int: %u\n", max_value);return 0;
}
注意:也可以直接对0取反操作。
unsigned int zero = 0;
unsigned int max_value = ~zero; // 对0取反,得到无符号整数的最大值
10. 逻辑运算符 (&&) 和 位运算符 (&)

关键区别:
- 短路求值:
&&会短路,避免不必要的计算和潜在的错误。&不会短路,总是计算所有条件。
- 安全性:
- 使用
&&是安全的,因为它可以防止数组越界访问。 - 使用
&是危险的,可能会导致程序崩溃或未定义行为。
- 使用
11. printf函数的返回值
代码分析:答案:4321
#include <stdio.h>int main() {int i = 43;printf("%d\n", printf("%d", printf("%d", i)));return 0;
}
总结:
printf的返回值是打印的字符数。- 嵌套的
printf调用会从内到外依次执行。 - 最终的输出是
4321,包括换行符。
12. 通过#运算符,利用宏参数来创建字符串
在 C 语言中,# 运算符是 字符串化运算符,它可以将宏参数转换为字符串字面量。通过结合宏定义和 # 运算符,可以轻松地将宏参数转换为字符串。
代码分析:
#include <stdio.h>// 定义宏
#define SQUARE(x) (printf(""#x" square is: %d\n", (x) * (x)))int main() {int num = 5;SQUARE(num);SQUARE(3 + 2);SQUARE(10);return 0;
}
输出:
num square is: 25
3 + 2 square is: 25
10 square is: 100
解释:
-
SQUARE(num):#x被替换为"num"。(x) * (x)计算为5 * 5 = 25。- 输出:num square is: 25
-
SQUARE(3 + 2):#x被替换为"3 + 2"。(x) * (x)计算为5 * 5 = 25。- 输出:3 + 2 square is: 25
-
SQUARE(10):#x被替换为"10"。(x) * (x)计算为10 * 10 = 100。- 输出:10 square is: 100
总结:
- 这个宏定义通过
#运算符将参数x转换为字符串,方便在输出中显示参数的具体形式。 - 同时,宏会计算参数的平方值并输出。
- 这种技巧在调试或需要显示表达式及其结果时非常有用。
13. “##” 运算符的作用
在 C 语言中,## 是 令牌粘贴运算符(Token Pasting Operator),用于将两个令牌(tokens)连接成一个新的令牌。它在宏定义中非常有用,特别是在需要动态生成标识符或代码时。
基本用法:
#include <stdio.h>// 定义宏,将两个令牌连接
#define CONCAT(a, b) a##bint main() {int var1 = 10;int var2 = 20;// 使用宏连接令牌printf("%d\n", CONCAT(var, 1)); // 输出 var1 的值printf("%d\n", CONCAT(var, 2)); // 输出 var2 的值return 0;
}
进阶用法:动态生成代码。## 运算符可以用于动态生成变量名、函数名或代码片段。
#include <stdio.h>// 定义宏,动态生成函数名
#define CALL_FUNCTION(func_name, arg) func_name##_version_##arg()// 定义函数
void greet_version_1() {printf("Hello from version 1!\n");
}void greet_version_2() {printf("Hello from version 2!\n");
}int main() {// 使用宏调用不同版本的函数CALL_FUNCTION(greet, 1); // 调用 greet_version_1CALL_FUNCTION(greet, 2); // 调用 greet_version_2return 0;
}
14. 结构体中使用字符数组还是字符指针
代码分析:
#include <stdio.h>
#include <string.h>struct std {unsigned int id;char *name;unsigned int age;
} per;int main(void) {per.id = 0001;strcpy(per.name, "Micheal Jackson");per.age = 20;printf("%s\n", per.name);return 0;
}
结论:
- 优先使用字符数组。
- 如果写成 per.name = "Micheal Jackson" ,只是将字符串的地址给了指针,该字符串的内容并不在结构体内,无法直接修改。
15. 内存越界问题
分析代码:
char *p1 = "ABCABC";
char *p2 = (char *)malloc(strlen(p1));
strcpy(p2, p1);
分析:
-
strlen函数:这个函数计算字符串的长度,但是不包括字符串结束符'\0'。因此,对于字符串"ABCABC",strlen(p1)的结果是 6,而不是 7(如果包括'\0')。 -
strcpy函数:这个函数用于复制字符串,并且会连同字符串结束符'\0'一起复制。
16. free 和 delete 是如何处理指针
#include <iostream>
#include <cstring>
using namespace std;int main(void)
{char *p = new char[100]; // 使用new操作符分配100字节的内存空间,用于存储字符数组strcpy(p, "ABCABC"); // 使用strcpy函数将字符串"ABCABC"复制到p指向的内存空间cout << "p = " << p << endl; // 输出p指向的字符串delete [] p; // 使用delete[]操作符释放p指向的内存空间p = NULL; // 将p设置为NULL,避免悬垂指针问题return 0;
}
结论:两者只是将指针指向的内存给释放掉了,但是指针还是存在;不能再次访问的原因是此时指针是野指针,可能出现不必要的麻烦
改进操作:
-
释放后置空指针
在调用 free 或 delete 后,将指针置为 NULL(C)或 nullptr(C++),避免悬空指针。free(ptr); ptr = NULL;delete ptr; ptr = nullptr; -
避免重复释放:确保每个指针只释放一次。
-
匹配分配和释放函数:
- 使用
malloc分配的内存用free释放。 - 使用
new分配的内存用delete释放。 - 使用
new[]分配的内存用delete[]释放。
- 使用
-
检查空指针:在释放前检查指针是否为空,避免不必要的操作。
总结:
free和delete用于释放动态分配的内存,但不会自动置空指针。- 释放后,指针仍然指向原来的地址,但访问它是未定义行为。
- 最佳实践是在释放后将指针置空,并避免重复释放。
相关文章:
C/C++语言知识点一
目录 1. 请对这段代码进行解释:char *const *(*next)( ); 2. 函数指针数组:解释这个表达式char *(*c[10])(int **p); 3. 字符串常量:分析下面这段代码。 4. 访问指定内存地址 5. typedef 和 define 的区别 6. 函数返回局部变量地址问…...
前端面试题---在vue中为什么要用路由
在vue中为什么要用路由, 毕竟a标签可以直接跳转页面 在 Vue 中使用 Vue Router 的主要原因是提高 单页面应用(SPA) 的用户体验和性能。 相比传统的 <a> 标签跳转,Vue Router 提供了以下优势: 避免页面刷新: V…...
Three.js 快速入门教程【十】常见的纹理类型
系列文章目录 Three.js 快速入门教程【一】开启你的 3D Web 开发之旅 Three.js 快速入门教程【二】透视投影相机 Three.js 快速入门教程【三】渲染器 Three.js 快速入门教程【四】三维坐标系 Three.js 快速入门教程【五】动画渲染循环 Three.js 快速入门教程【六】相机控件 Or…...
文档识别-C#中英文文档识别接口-PDF文件内容识别API
文档识别接口可满足用户在数字化转型过程中对文档处理的高效、准确需求。翔云文档识别接口以成熟的文字识别技术、自然语言处理技术、图像识别技术为核心,能够将文档上的非可编辑文本转化为可编辑的数据,从而提升信息处理的速度与实现文档数字化管理的准…...
gRPG协议
gRPG协议是一种用于游戏开发的网络通信协议,全称为Game Real-time Protocol。它主要用于实现实时多人游戏中的数据传输和同步。gRPG协议的设计目标是提供低延迟、高可靠性的数据传输,以支持游戏中的实时互动和状态同步。 gRPG协议的特点 低延迟&#x…...
【maven打包错误】 无效的目标发行版:16
maven打包错误 错误截图 About 故事在一个风和日丽的下午,我一如往常的摸鱼,突如其来的事情打乱我的摸鱼节奏,“为什么测试不能用了” ,随着前端帅哥一声轻咦,故事便开始了,我检查发现是是磁盘满了&#x…...
Oracle 查询表空间使用情况及收缩数据文件
本文介绍Oracle收缩数据文件的相关操作,运维工作中有时会需要通过收缩数据文件来释放磁盘空间。 数据文件初始化方式: 1.我们创建表空间一般有两种方式初始化其数据文件,即指定初始大小为32G(很大的值)或指定初始大小为…...
Transformer 代码剖析1 - 数据处理 (pytorch实现)
引言 Transformer 架构自《Attention Is All You Need》论文发表以来,在自然语言处理领域引起了巨大的变革。它摒弃了传统的循环结构,完全基于注意力机制,显著提高了处理序列数据的效率和性能。本文将通过对一个具体的项目代码结构进行详细分…...
Python异常处理面试题及参考答案
目录 什么是 Python 中的异常?程序为什么需要异常处理机制? 解释 BaseException 和 Exception 的区别 Python 的异常处理与传统的错误代码返回机制相比有哪些优势? 列出至少 5 个 Python 内置异常类型并说明触发场景 语法错误 (SyntaxError) 与运行时异常 (Runtime Erro…...
Python多线程知多少
目录 目标 Python版本 官方文档 概述 线程 守护线程 线程同步 事件对象(Event Object) 实战 创建线程的基本语法 阻塞线程 守护线程 线程同步的方法 互斥锁(排他锁) 信号量(Semaphore) 事件…...
C++ Qt常见面试题(8):C++ Qt中的线程同步与互斥
在C++ Qt中,线程同步和互斥通常通过 QMutex 和 QMutexLocker 来实现。线程同步确保多个线程不会同时访问共享资源,而互斥机制通过锁定一个资源,确保在任何给定时刻只有一个线程能够访问它。 以下是一个使用 QMutex 来同步和互斥访问共享资源的详细示例代码: 1. 使用 QMut…...
数字内容个性化推荐的关键是什么?
智能算法交互体系构建 构建数字内容体验的智能推荐系统,本质上是实现数据驱动与算法响应的动态协同。其核心在于建立多维度用户数据与机器学习模型的深度交互链路——通过实时采集用户点击、停留时长、交互路径等行为特征,结合设备属性、场景状态等上下…...
DeepSeek-OpenSourceWeek-第三天-Release of DeepGEMM
DeepGEMM:这是一款专为高效的 FP8(8 位浮点)通用矩阵乘法(GEMMs)而开发的尖端库。GEMMs 是许多 AI 工作负载(尤其是深度学习)中的基本操作。 特点: 支持稠密和 MoE GEMMs:它可以处理标准的稠密矩阵乘法以及混合专家(MoE)模型中使用的矩阵乘法。MoE 是一种神经网络架…...
LeetCode 1472.设计浏览器历史记录:一个数组完成模拟,单次操作均O(1)
【LetMeFly】1472.设计浏览器历史记录:一个数组完成模拟,单次操作均O(1) 力扣题目链接:https://leetcode.cn/problems/design-browser-history/ 你有一个只支持单个标签页的 浏览器 ,最开始你浏览的网页是 homepage ,…...
AI+游戏,正在进行时!
2月,DeepSeek引领的AI浪潮对游戏行业造成了巨大冲击。 2月17日马斯克在社交平台宣布,xAI将成立一家AI游戏工作室,高调宣布两大核心理念,打破大公司的垄断,利用AI重构游戏体验。随后的新闻中还表示,团队计划…...
贪心算法精品题
1.找钱问题 本题的贪心策略在于我们希望就可能的保留作用大的5元 class Solution { public:bool lemonadeChange(vector<int>& bills) {std::map<int ,int> _map;for(auto ch:bills){if(ch 5) _map[ch];else if(ch 10){if(_map[5] 0) return false;else{_m…...
sql server 复制从备份初始化数据
参考 : 从备份初始化订阅(事务) - SQL Server | Microsoft Learn sql server 复制默认是用快照初始化数据的,也支持从备份初始化数据,参考如上...
【蓝桥杯】1.k倍区间
前缀和 #include <iostream> using namespace std; const int N100010; long long a[N]; int cnt[N]; int main(){int n, m;cnt[0] 1;cin >> n >> m;long long res 0;for(int i 1; i < n; i){scanf("%d", &a[i]);a[i] a[i-1];res cnt…...
Qt互斥锁(QMutex)的使用、QMutexLocker的使用
Qt互斥锁【QMutex】的使用、QMutexLocker的使用 Chapter1 Qt互斥锁(QMutex)的使用、QMutexLocker的使用一、QMutexLocker和QMutex实现示例图二、QMutex和QMutexLocker的关系(个人理解)三、QMutex使用和QMutexLocker使用1.QMutex的使用2.QMutexLocker的使…...
具身智能(Embodied AI)的物理交互基准测试:构建真实世界的智能体评估体系
文章目录 引言:从虚拟到物理的智能跃迁一、具身智能测试体系设计1.1 评估维度矩阵1.2 测试平台技术栈二、核心测试场景构建2.1 基础运动能力测试集2.2 复杂操作任务设计三、物理仿真引擎关键技术3.1 高精度接触力学模型3.2 传感器噪声模拟四、评估指标体系4.1 量化指标公式4.2…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
