C语言----指针入门篇
1. 指针是什么?
指针理解的两个要点:
1. 指针是内存中一个最小单元的编号 也就是地址
2. 平时口语中说的指针 通常指的是指针变量 是用来存放内存地址的变量
下面我将会具体解释上面两个要点 这时我们就不得不提一提内存了
1.1 什么是内存呢?
C语言中的内存布局
程序运行时,内存被划分为几个主要区域(由低地址到高地址):
- 代码区(Text Segment):存储编译后的机器指令(如函数代码)。
- 全局/静态区(Data Segment):存储全局变量和静态变量(如
static int x;
)。- 堆区(Heap):动态分配的内存(如
malloc
分配的空间),需手动管理。- 栈区(Stack):存储局部变量、函数参数等,由系统自动分配和释放。
高地址 ┌─────────────┐ │ 栈区 │ ← 局部变量、函数调用(向下增长) ├─────────────┤ │ 堆区 │ ← 动态内存(向上增长) ├─────────────┤ │ 全局/静态区 │ ← 全局变量、static变量 ├─────────────┤ │ 代码区 │ ← 程序指令 └─────────────┘ 低地址
1.2 变量与内存的关系
在C语言中,变量是内存的抽象。例如:
int a = 10; // 在栈上分配4字节(假设int占4字节)
a
的值10
存储在某个内存地址(如0x7ffd1234
)。- 通过
&a
可以获取它的地址。- 但a是int类型 占4个字节 每一个字节都有地址 那&a取出的是哪个字节的地址呢?
- &a实际上是取的第一个字节的地址(较小的地址)
1.3 指针的本质
指针是一种变量,专门用于存储另一个变量的内存地址。
语法:类型 *指针变量名;
示例:int a = 10; int *p = &a; // p 存储 a 的地址
p
指向a
的内存地址(如0x7ffd1234
)。- 通过
*p
可以访问或修改a
的值(解引用)。
我们可以试着打印看看 a的地址和pa的值
如上图 &a对a取地址的值和pa的值是一样的
总结:
指针变量是用来存放地址的 地址是唯一表示一个内存单元的
指针的大小在32位平台是4个字节 在64位平台是8个字节
那怎么使用指针呢? 下面我将简单解释指针的使用
1.4 指针的基本操作
(1) 声明指针
int *p; // 指向int类型的指针
char *str; // 指向char类型的指针
float *fp; // 指向float类型的指针
指针类型的意义
指针类型决定了 指针进行解引用操作的时候 一次性访问几个字节
// 如果是char*的指针 解引用访问1个字节
// 如果是int*的指针 解引用访问4个字节
// 如果是float*的指针 解引用访问4个字节
(2) 取地址(&)和解引用(*)
1. 取地址运算符
&
- 作用:获取变量的内存地址。
- 语法:
&变量名
- 返回值:该变量的内存地址(指针类型)。
- 关键点:
- 只能用于已定义的变量(如
int a;
),不能用于常量(如&10
是错的)。
2. 解引用运算符
*
- 作用:通过指针访问或修改该指针指向的内存中的值。
- 语法:
*指针变量名
- 关键点:
- 必须对已初始化的指针使用(否则是野指针)。
- 解引用时,指针的类型决定了如何解释内存中的数据(如
int*
按4字节读取,char*
按1字节读
用法如下:
int a = 10;
int *p = &a; // p 存储 a 的地址printf("%d\n", *p); // 输出 10(通过指针访问a的值)
*p = 20; // 修改 a 的值为 20
运行结果如下:
(3) 指针的算术运算
指针加减整数时,移动的单位是指向类型的大小:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {int arr[3] = { 1, 2, 3 };int* p = arr; // p 指向 arr[0]printf("%d\n", *p); // 输出 1printf("%d\n", *(p + 1)); // 输出 2(p+1 指向 arr[1])return 0;
}
运行结果如下:
我们可以试着输出他们的地址 来观察指针+1时 地址的具体变化
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {int arr[3] = { 1, 2, 3 };int* p = arr; // p 指向 arr[0]printf("%p\n", p); // 输出 1printf("%p\n", (p + 1)); // 输出 2(p+1 指向 arr[1])return 0;
}
运行结果如下:
可以看出来p和p+1的地址相差了4个字节 这是因为int类型的数据在内存种 占4个字节
下面我们来验证我们的猜想 char类型的是否是1个字节
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main() {char arr[3] = {'a','b','c'};char* p = arr; // p 指向 arr[0]printf("*p=%c\n", *p); // 输出 aprintf("*(p+1)=%c\n", *(p + 1)); // 输出 b(p+1 指向 arr[1])printf("p的地址%p\n", p); // 输出 a的地址printf("p+1的地址%p\n", (p + 1)); // 输出 b(p+1 指向 arr[1])的地址return 0;
}
运行结果如下:
可以看出 验证成功 char类型的指针+1 会让地址增加一个字节
2. 指针类型
指针类型的意义:
指针的不同类型 其实提供了不同的视角区观看和访问内存
char* 一次访问1个字节 +1跳过一个字节
int* 一次访问4个字节 +1跳过四个字节 同理也可以+2 +3等等
既 int* p+4跳过了4*sizeof(int)个字节 既16个字节 其他类型同理
总结:指针类型决定了指针向前或向后走一步有多大
指针的类型决定了指针解引用时候 有多大的权限 既操作几个字节
比如 char*的指针只能访问一个字节 而int*可以访问四个字节
3. 野指针
野指针是什么呢?
野指针就是指针指向的位置是不可知的(随机的 不正确的 没有明确限制的)
3.1 野指针产生的原因?
下面介绍第一种野指针
1. 指针未初始化
未赋初值:指针声明后未初始化,可能随机指向无效地址
下面我给大家举个例子 就知道它是如何产生的
int main()
{int* p;*p = 20;printf("%d", *p);return 0;
}
上面的代码粗看一遍感觉没什么问题 但实际上是有问题的 如下
这就是第一种野指针 未初始化的指针 可能引发程序崩溃、数据损坏或安全漏洞。
下面介绍第二种野指针
2. 越界访问
定义:指针访问超出其指向的内存边界(如数组、动态分配的内存块等)。
如下代码
int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int* p = arr;for (int i = 0; i <= 10; i++){printf("%d", *p);p++;}return 0;
}
错误原因:
细心的同学不难发现 arr数组只有10个元素 但是却循环了11次 既访问了arr[10]
但他并没有被定义 我们可以来看一下运行结果
返回了一个随机数 这就是越界访问 可能会导致缓冲区溢出问题
下面介绍第三种野指针
3. 悬垂指针
定义:指向已经被释放或失效的内存地址的指针 由于该内存可能已被系统回收或重新分配 解引用使用悬垂指针会导致 未定义行为
int* text()
{int a;return &a;
}
int main()
{int* p = text();printf("%d", *p);return 0;
}
错误原因如下 :
text()
函数返回了局部变量 a
的地址,但 a
在函数返回后会被销毁(栈内存自动回收),此时 p
指向的是一块已被释放的内存,访问 *p
是未定义行为 可能会导致以下行为
程序崩溃:最常见的是段错误(Segmentation Fault),因为访问了非法内存。
输出随机值:若系统未立即回收栈内存,可能读到残留数据(但不可依赖)。
3.2 野指针的解决方法
1. 初始化指针
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() {int a = 10;int* p = &a;//指针的初始化int* p = NULL;//NULL-空指针,专门用来初始化指针*p = 20;//安全检查 }
优点:
- 如果忘记初始化,解引用
NULL
指针通常会 立即崩溃(比随机内存访问更安全)。- 既指针指向空间释放 即时置NULL
- 便于调试(
gdb
或Valgrind
能检测NULL
解引用)
2. 指向已有变量
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() {int x = 10;int* p = &x; // 指向栈变量printf("%d", *p); // 安全 }
优点:
指针始终指向有效内存。
3. 使用静态/全局变量
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int main() {static int x = 10;int* p = &x; // 指向静态变量printf("%d", *p); // 安全}
优点:
- 静态变量的生命周期持续到程序结束,指针不会悬空。
4.小心指针越界
5. 避免返回局部变量的地址
6.指针使用前 检查有效性
4. 指针运算
4.1 指针+- 正数
下面我们通过具体的代码来理解指针+-正数的使用
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{float* values[5];float* vp;
//指针+-正数: 指针的关系运算for(vp=&values[0];vp<&values[5];){*vp++ = 0;}for (int i = 0; i < 5; i++){printf("%lf ", values[i]);}
}
定义了指针vp 并且把values[0]的地址赋给了vp 通过vp的++ 使得p指向的地址发生改变
并且是后置++ 先使用后改变 每次都往后走一步 指向下一个元素 直到数组元素都被更改为0
通过运行 不难看出 可以讲values数组元素都赋值位0.000000
4.2 指针-指针
下面我们通过具体的代码来理解指针-指针的使用
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{int arr[10] = { 0 };printf("%d\n", &arr[9] - &arr[0]);
}
上面这段代码运行结果是什么呢?
运行结果是9 为什么呢?
那是因为两个指针相减 得到的是指针直接的个数的绝对值 arr[9]和arr[0]直接相差9个元素 既arr[0~8]共9个元素
前提是 指针_指针 需要指针在同一块空间(指针类型相同) 如下 int类型和char类型指针相减是没有意义的
现在我们通过练习 写一个mystrlen的代码来练习一下
通过指针来实现计算字符串长度
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int My_strlen(char* arr)
{int count = 0;while (*arr != '\0'){arr++;count++;}return count;
}
int main()
{char arr[] = "abcdefg";int a = My_strlen(arr);printf("%d",a);return 0;
}
上面是我们之前学过的代码 现在看起来似乎更加浅显易懂了
我们对此稍加修改就能完成指针相减来实现目的 如下
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int My_strlen(char* arr)
{char* start = arr;while (*arr != '\0'){arr++;}return arr-start;
}
int main()
{char arr[] = "abcdefg";int a = My_strlen(arr);printf("%d",a);return 0;
}
运行结果也的确没有问题
4.3 指针的关系运算
关系运算其实就一个要点既需要满足标准规定
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较 但是不允许与指向第一个元素之前的那个内存位置的指针进行比较
如下代码 虽然可以运行 但是并不符合规定 应当避免
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{float values[5];float* vp;//指针+-正数: 指针的关系运算for (vp = &values[4]; vp >=&values[0];vp--){*vp= 0;}for (int i = 0; i < 5; i++){printf("%lf\n", values[i]);}
}
上述代码讲values[0]与它之前的地址进行比较 这并不符合规定 即使运算结果正确 也应该避免
5. 指针和数组
指针和数组的有什么关系呢? 回想之前的学习 其实我们也大概能猜出来 下面让我来为大家讲解他们之间的联系
指针和数组
1. 指针和数组是不同的对象
指针是一种变量 是存放地址的 大小是4/8字节的
而数组是一种相同元素的集合 可以放多个元素 大小是取决于元素个数和元素的类型的
2. 数组的数组名是首元素的地址 地址可以存放在指针变量中 可以通过指针访问变量
让我们通过指针来操作数组来熟悉一下
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{int arr[10] = { 0 };int* p = arr;int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0; i < sz; i++){*(p+i) = i + 1;}for (i = 0; i < sz; i++){printf("%d ", *p);p++;}return 0;
}
运行结果如下
我们使用了指针的运算来对数组进行了赋值 并且通过指针将数组的元素打印了出来
不仅可以对指针进行=- 其实数组也可以+-
int* p=arr; 证明了arr其实和p是等价的 *(p+i)=arr[i]=*(arr+i)=i[arr]
让我们验证一下
原因是什么呢?
因为 [ ] 是操作符 i和arr是[]这个操作符的操作数而已 相当于a+b=b+a
重点:数组名是数组首元素的地址
6. 二级指针
什么是二级指针呢?
在C语言中,二级指针(int **
、char **
等)是指向指针的指针 如下
int main() {int a = 10;int* p = &a; // 一级指针,存储 a 的地址int** pp = &p; // 二级指针,存储 p 的地址return 0;
}
如何理解**呢 你可以把int*看成一个整体 后面的*pp是一个整体 *pp说明pp是一个指针 而前面的int* 说明pp这个指针存放的是一个int类型的指针的地址
同理
int main() {int a = 10;int* p = &a; // 一级指针,存储 a 的地址int** pp = &p; // 二级指针,存储 p 的地址int*** ppp = &pp; // 三级指针, 存储 pp 的地址return 0;
}
但是三级及以上基本不怎么使用 了解即可
让我们观察一下他们三者的关系 让我们运行以下代码
int main() {int a = 10;int* p = &a; // 一级指针,存储 a 的地址int** pp = &p; // 二级指针,存储 p 的地址int*** ppp = &pp; // 三级指针, 存储 pp 的地址printf("***ppp = %d\n", ***ppp);printf("**pp = %d\n", **pp);printf("*p= %d\n",*p);printf("a= %d\n", a);return 0;
}
运行结果如下图
可以看出
***ppp=**pp=*p=a
说明通过ppp找到pp 通过pp找到p 通过p找到a
ppp存放pp的地址 pp存放p的地址 p存放a的地址 通过三次解引用ppp就可以找到a的值
可以总结为下图所示的关系
对于二级指针的运算有:
*pp 通过对pp中的地址进行解引用 这样就能找到p *pp其实就是访问p
int a=10;*pp=&a;//等价于p=&a
**pp先通过*pp找到p 再对p进行解引用操作:*p 找到a
**pp=30;
//等价于*p=30;
//等价于a=30;
7. 指针数组
首先我们需要明确指针数组是指针还是数组
中国人喜欢把重点放在后面 比如说好基友 是的 类似 指针数组的主语是数组
比如说字符数组--存放的是字符的数组--char[10] 整型数组--存放的是整型的数组--int[10]
int main() {int a = 10;int b = 20;int c = 30;int d = 40;int e = 50;int* arr[5] = { &a ,&b ,&c ,&d ,&e };for (int i = 0; i < 5; i++){printf("%d ", *arr[i]);}return 0;
}
如图 成功通过指针arr数组访问了a b c d e的值
因此arr数组的确是一个指针数组 但我们平时并不会这样使用
int main() {int a[] = { 1,2,3,4,5 };int b[] = { 6,7,8,9,10 };int c[] = { 11,12,13,14,15 };int* arr[5] = { a,b,c };for (int j = 0; j < 5; j++){for (int i = 0; i < 5; i++){printf("%d ", arr[j][i]);}printf("%\n");}return 0;
}
上述代码 我们成功实现了 使用一维数模拟了三维数组来使用 运行结果如下
以上就是初阶全部内容 如有帮助 请点点赞 谢谢
相关文章:
C语言----指针入门篇
1. 指针是什么? 指针理解的两个要点: 1. 指针是内存中一个最小单元的编号 也就是地址 2. 平时口语中说的指针 通常指的是指针变量 是用来存放内存地址的变量 下面我将会具体解释上面两个要点 这时我们就不得不提一提内存了 1.1 什么是内存呢? C语言中的内存布局 程序…...
GitHub 趋势日报 (2025年05月03日)
本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ 📈 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1hacksider/Deep-Live-Camreal time face swap and one-click video deepfake with only a single image⭐ 1582⭐ 59337Python2aip…...
Go-Spring 全新版本 v1.1.0
Go-Spring 全新版本 v1.1.0 已于 2025 年发布。该版本具有诸多新特性,具体如下: 命名与结构优化:命名更加符合 Go 规范,模块划分更加合理,核心设计更加简洁。功能增强:突破性地支持统一日志框架,…...
JVM——JVM是怎么实现invokedynamic的?
JVM是怎么实现invokedynamic的? 在Java 7引入invokedynamic之前,Java虚拟机(JVM)在方法调用方面相对较为“僵化”。传统的Java方法调用主要依赖于invokestatic、invokespecial、invokevirtual和invokeinterface这四条指令&#x…...
使用 IDEA + Maven 搭建传统 Spring MVC 项目的详细步骤(非Spring Boot)
搭建Spring MVC项目 第一步:创建Maven项目第二步:配置pom.xml第三步:配置web.xml第四步:创建Spring配置文件第五步:创建控制器第六步:创建JSP视图第七步:配置Tomcat并运行目录结构常见问题解决与…...
洛谷 P1495:【模板】中国剩余定理(CRT)/ 曹冲养猪
【题目来源】 https://www.luogu.com.cn/problem/P1495 https://www.acwing.com/problem/content/225/ 【题目描述】 自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干些事业,于是派他到中原养猪场养猪。可是曹冲满不高兴,于是在工作中马马虎…...
【iOS】 分类 拓展 关联对象
【iOS】 分类 拓展 关联对象 文章目录 【iOS】 分类 拓展 关联对象前言拓展分类分类与拓展的区别分类拓展关联对象哈希表(AssociationsHashMap) 大致工作流程setgetremove 关联对象的释放时机总结 前言 之前讲过有关于类对象的内容,这里学习一下有关于类的分类拓展和关联对象的…...
iview 老版本合并单元格
新版的iview中已经支持了合并单元格了,我的版本比较老,为:"iview": "^3.5.2"。暂不支持。记录一下别的大佬的方法。感觉思路比较活,正在这种思路需要在解决问题的过程中学习。 核心思路:通过rende…...
go语言实现用户管理系统
goweb实现用户管理系统 用户后台管理系统功能描述 登录功能 支持用户通过邮箱密码和密码进行登录。对输入的邮箱和密码进行验证,确保用户信息的正确性。登录成功后,更新用户的今日登录统计信息,并将用户信息存入会话(cookie&am…...
普通IT的股票交易成长史--20250504实盘记录
声明:本文章的内容只是自己学习的总结,不构成投资建议。价格行为理论学习可参考简介中的几位,感谢他们的无私奉献。 送给自己的话: 仓位就是生命,绝对不能满仓!!!!&…...
SQL手工注入(DVWA)
手工SQL注入攻击的标准思路 Low等级 (1)判断是否存在注入 (2)猜解字段个数 (3)确定字段顺序 (4)获取当前数据库 (5)获取当前数据库中的表 (…...
【LLM】deepseek R1之GRPO训练笔记(持续更新)
note 相关框架对比: 需微调模型且资源有限 → Unsloth;本地隐私优先的小规模推理 → Ollama;复杂逻辑或多模态任务 → SGLang;高并发生产环境 → vLLM 微调SFT和GRPO是确实能学到新知识的四种格式(messages、sharegpt…...
序列到序列学习
seq2seq 就是把一个句子翻译到另外一个句子。 机器翻译 给定一个源语言的句子,自动翻译成目标语言这两个句子可以有不同的长度 seq2seq 是一个 Encoder - Decoder 的架构 编码器是一个 RNN , 读取输入句子(可以是双向) 解码…...
去打印店怎么打印手机文件,网上打印平台怎么打印
在数字化时代,手机已成为我们存储和传输文件的重要工具。然而,当需要将手机中的文件转化为纸质文档时,许多人会面临选择:是前往线下打印店,还是利用线上打印平台?本文将为您解析这两种方式的优劣࿰…...
LeetCode每日一题5.4
1128. 等价多米诺骨牌对的数量 问题 问题分析 等价的定义为:两个骨牌 [a, b] 和 [c, d] 等价,当且仅当 (a c 且 b d) 或者 (a d 且 b c)。 思路 标准化骨牌表示: 为了方便比较,我们可以将每个骨牌 [a, b] 标准化为 [min(a…...
前端小练习————表白墙+猜数字小游戏
1,猜数字游戏 实现一个这个样式的 要猜的目标数字 点击重新开始游戏之后: 代码实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widt…...
五年级数学知识边界总结思考-上册
目录 一、背景二、过程1.小数乘法和除法小学五年级小数乘除法的知识点、由来、作用与意义解析**一、核心知识点梳理****二、知识点的由来****三、作用与意义****四、教学意义** **总结** 2.位置小学五年级“位置”知识点、由来、作用与意义解析**一、核心知识点梳理****二、知识…...
C与指针——内存操作与动态内存
1、内存常用操作 void* memcpy(void* dst,const void* src,size_t length); \\内存不允许重叠 void* memmove(void* dst,const void* src,size_t length); \\内存允许重叠 int memcmp(const void* dst,const void* src,size_t length); \\相等返回0 void* memset(void* dst,in…...
P3469 [POI 2008] BLO-Blockade
P3469 [POI 2008] BLO-Blockade 题目描述 B 城有 n n n 个城镇(从 1 1 1 到 n n n 标号)和 m m m 条双向道路。 每条道路连结两个不同的城镇,没有重复的道路,所有城镇连通。 把城镇看作节点,把道路看作边&…...
Linux网络编程 day3 五一结假
基本概念 三次握手 主动发起连接请求端,发送SYN标志位,请求建立连接。携带数据包包号、数据字节数(0)、滑动窗口大小。 被动接收连接请求端,发送ACK标志位,同时携带SYN请求标志位。携带序号、确认序号、数据包包号、数据字节数…...
解释一下NGINX的反向代理和正向代理的区别?
大家好,我是锋哥。今天分享关于【解释一下NGINX的反向代理和正向代理的区别?】面试题。希望对大家有帮助; 解释一下NGINX的反向代理和正向代理的区别? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 NGINX 作为一个高效的反向代理服务器&a…...
Coco AI 入驻 GitCode:打破数据孤岛,解锁智能协作新可能
在信息爆炸时代,企业正面临前所未有的挑战: 企业数据和信息分散,数据孤岛现象严重,员工往往浪费大量时间跨平台检索;跨部门协作困难,团队因信息隔阂导致项目延期;数据安全问题严峻,…...
【QT】QT中的网络编程(TCP 和 UDP通信)
QT中的网络编程(TCP 和 UDP通信) 1.tcp1.1 tcp通信1.1.1 相比linux中tcp通信:1.1.2 QT中的tcp通信: 1.2 tcp通信流程1.2.1 服务器流程:1.2.1.1 示例代码1.2.1.2 现象 1.2.2 客户端流程:1.2.2.1 示例代码1.2.2.2 现象: …...
个性化推荐:大数据引领电子商务精准营销新时代
个性化推荐:大数据引领电子商务精准营销新时代 引言 在电子商务的时代,个性化推荐系统已经成为提升用户体验、增强平台竞争力的重要技术。随着大数据技术的迅猛发展,传统的推荐方法已经无法满足用户日益增长的需求。为了精准地把握用户兴趣和消费倾向,商家们依赖大数据分析…...
【前端】【总复习】HTML
一、HTML(结构) HTML 是网页的骨架,主要负责网页的结构与语义表达,为 CSS 和 JavaScript 提供承载基础。 1.1 HTML 基本结构与语义化标签 1.1.1 HTML 基本结构 <!DOCTYPE html> <html lang"en"> <hea…...
Android 输入控件事件使用示例
一 前端 <EditTextandroid:id="@+id/editTextText2"android:layout_width="match_parent"android:layout_height="wrap_content"android:ems="10"android:inputType="text"android:text="Name" />二 后台代…...
JVM happens-before 原则有哪些?
理解Java Memory Model (JMM) 中的 happens-before 原则对于编写并发程序有很大帮助。 Happens-before 关系是 JMM 用来描述两个操作之间的内存可见性以及执行顺序的抽象概念。如果一个操作 A happens-before 另一个操作 B (记作 A hb B),那么 JMM 向你保证&#x…...
Python实例题:Python获取NBA数据
目录 Python实例题 题目 方式一:使用网页爬虫获取数据 代码解释 get_nba_schedule 函数: 主程序: 方式二:使用专业 API 获取数据 代码解释 运行思路 方式一 方式二 注意事项 以下是完整的 doubaocanvas 代码块&#…...
【中间件】brpc_基础_remote_task_queue
文章目录 remote task queue1 简介2 核心功能2.1 任务提交与分发2.2 无锁或低锁设计2.3 与 bthread 深度集成2.4 流量控制与背压 3 关键实现机制3.1 数据结构3.2 任务提交接口3.3 任务窃取(Work Stealing)3.4 同步与唤醒 4 性能优化5 典型应用场景6 代码…...
React-router v7 第七章(导航)
导航 在React-router V7中,大致有四种导航方式: 使用Link组件 link使用NavLink组件 navlink使用编程式导航useNavigate usenavigate使用redirect重定向 redirect Link Link组件是一个用于导航到其他页面的组件,他会被渲染成一个<a>…...
Terraform 中的 external 数据块是什么?如何使用?
在 Terraform 中,external 数据块(Data Block) 是一种特殊的数据源,允许你通过调用外部程序或脚本获取动态数据,并将结果集成到 Terraform 配置中。它适用于需要从 Terraform 外部的系统或工具获取信息的场景。 一、e…...
打印Excel表格时单元格文字内容被下一行遮盖的解决方法
本文介绍在打印Excel表格文件时,单元格最后一行的文字内容被下一行单元格遮挡的解决方法。 最近,需要打印一个Excel表格文件。其中,已知对于表格中的单元格,都设置了自动换行,如下图所示。 并且,也都设置了…...
【Linux】命令行参数与环境变量
🌟🌟作者主页:ephemerals__ 🌟🌟所属专栏:Linux 目录 前言 一、命令行参数 1. 什么是命令行参数 2. 命令行参数的作用 二、环境变量 1. 基本概念 2. 常见的环境变量 3. 环境变量相关操作 定义…...
Dify 完全指南(一):从零搭建开源大模型应用平台(Ollama/VLLM本地模型接入实战)》
文章目录 1. 相关资源2. 核心特性3. 安装与使用(Docker Compose 部署)3.1 部署Dify3.2 更新Dify3.3 重启Dify3.4 访问Dify 4. 接入本地模型4.1 接入 Ollama 本地模型4.1.1 步骤4.1.2 常见问题 4.2 接入 Vllm 本地模型 5. 进阶应用场景6. 总结 1. 相关资源…...
民法学学习笔记(个人向) Part.3
民法学学习笔记(个人向) Part.3 8. 诉讼时效🌸 概念: 是指权利主体在法定期间内不行使权利,则债务人享有抗辩权,可以导致权利人无法胜诉的法律制度(有权你不用,别人就有话说了&#…...
C# 方法(返回值、返回语句和void方法)
本章内容: 方法的结构 方法体内部的代码执行 局部变量 局部常量 控制流 方法调用 返回值 返回语句和void方法 局部函数 参数 值参数 引用参数 引用类型作为值参数和引用参数 输出参数 参数数组 参数类型总结 方法重载 命名参数 可选参数 栈帧 递归 返回值 方法可以向调用代码返…...
打电话玩手机检测数据集VOC+YOLO格式8061张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):8061 标注数量(xml文件个数):8061 标注数量(txt文件个数):8061 …...
详解如何压测RocketMQ
目录 1.如何设计压测 2.压测工具 3.硬件配置 4.写代码压测 5.自带压测脚本 1.如何设计压测 二八定律法则:按业务峰值的 120% 设计压测目标(若线上峰值1000TPS,压测目标至少1200TPS) 关注三个指标 吞吐量(TPS&…...
实验三 触发器及基本时序电路
1.触发器的分类?各自的特点是什么? 1 、 D 触发器 特点:只有一个数据输入端 D ,在时钟脉冲的触发沿,输出 Q 的状态跟随输入端 D 的 状态变化,即 ,功能直观,利于理解和感受…...
双列集合——map集合和三种遍历方式
双列集合的特点 键和值一一对应,每个键只能对应自己的值 一个键和值整体称为键值对或键值对对象,java中叫做entry对象。 map常见的api map接口中定义了双列集合所有的共性方法,下面三个实现类就没有什么额外新的方法要学习了。 map接口…...
WebRTC 服务器之Janus视频会议插件信令交互
1.基础知识回顾 WebRTC 服务器之Janus概述和环境搭建-CSDN博客 WebRTC 服务器之Janus架构分析-CSDN博客 2.插件使用流程 我们要使⽤janus的功能时,通常要执⾏以下操作: 1. 在你的⽹⻚引入 Janus.js 库,即是包含janus.js; <…...
LabVIEW温控系统热敏电阻滞后问题
在 LabVIEW 构建的温控系统中,热敏电阻因热时间常数大(2 秒左右)产生的滞后效应,致使控温出现超调与波动。在不更换传感器的前提下,可从算法优化、硬件调整和系统设计等维度着手解决。 一、算法优化 1. 改进 PI…...
【Unity】使用XLua进行热修复
准备工作: (1)将XLua的Tool拖入Asset (2)配置热修复 (3)运行Genrate Code (4)运行Hotfix Inject In Editor 编写脚本(注意类上带有[Hotfix]) [Hot…...
GateWay使用
首先创建一个网关服务,添加对应的依赖 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId&…...
如何使用责任链模式优雅实现功能(滴滴司机、家政服务、请假审批等)
在企业级开发中,我们经常会遇到一系列有先后顺序、逐步处理的逻辑链路,例如请假审批、报销审批、日志处理、事件处理、滴滴司机接单流程等。这些场景非常适合使用 责任链模式(Chain of Responsibility Pattern) 来优雅地实现。 本…...
opencv的contours
1.哪里来的contours: 我们常常用到这一句: contours, hierarchy cv2.findContours(img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 输出的contours的是一个tuple类型的: 1.它的len()就是contour的个数 2.每一…...
使用 OpenCV 和 Dlib实现轮廓绘制
文章目录 引言1.准备工作2.代码解析2.1 导入必要的库2.2 定义绘制直线函数2.3 定义绘制凸包函数2.4 加载图像和模型2.5 关键点检测与绘制2.6 显示结果 3.68个关键点索引说明4.应用场景5.优化建议6. 结语 引言 人脸关键点检测是计算机视觉中的重要任务,广泛应用于人…...
学习黑客Linux 命令
在操作下面的闯关题之前,给下学习资料 一图速览:20 条命令及练习手册 #命令 & 常用参数关键作用典型练习1ls -alh列文件(含隐藏 & 人类可读大小)(数字海洋)在 $HOME 统计目录数2cd / pwd切换、显示路径cd /tmp &&a…...
探秘 RocketMQ 的 DLedgerServer:MemberState 的技术解析与深度剖析
在 RocketMQ 构建高可靠、强一致性消息系统的架构中,DLedgerServer 扮演着举足轻重的角色,而 MemberState 作为 DLedgerServer 内部用于描述节点状态的核心类,更是整个分布式日志模块稳定运行的关键。深入理解 MemberState 的设计理念、功能特…...
【计算机网络】HTTP中GET和POST的区别是什么?
从以下几个方面去说明: 1.定义 2.参数传递方式 3.安全性 4.幂等性 1.定义: GET: 获取资源,通常请求数据而不改变服务器的状态。POST: 提交数据到服务器,通常会改变服务器的状态或副作用(如创建或更新资源…...