指针(C语言)从0到1掌握指针,为后续学习c++打下基础
目录
一,指针
二,内存地址和指针
1,什么是内存地址
2,指针在不同系统下所占内存
三,指针的声明和初始化以及类型
1,指针的声明
2,指针 的初始化
1, 初始化方式优点及适用场景
4,指针的声明初始化类型
四,野指针(永远都要避免)
1,野指针的定义
2,野指针产生的原因
1,指针没有初始化
2,释放内存后未置空
3.局部变量超出作用域
3,野指针的危害
4,如何避免野指针
五,取地址符和解引用
1,取地址符&
2,解引用 *
六,指针的算术运算
1. 指针加法
2. 指针减法
3. 指针自增/自减
4. 指针与整数的比较
七,指针与数组
1,定义
2,初始化
3,指针数组与字符串
八,指针与函数
1. 函数参数传递指针
2. 函数返回指针
3. 函数指针
4,注意事项(必看)
九,多级指针
1. 多级指针的定义与初始化
1,定义
2,初始化
2. 多级指针的使用场景
1,动态二维数组
2,函数参数传递
3. 多级指针的注意事项
一,指针
在C语言中,指针是一种特殊的数据类型,用于存储另一个变量的内存地址。这使得程序可以直接操作计算机的物理内存位置,从而实现高效的内存管理和灵活的数据结构设计。
二,内存地址和指针
1,每个变量存储在内存中的唯一位置。
2,指针是存储内存地址的特殊变量。
int var = 10;
int *ptr = &var; // ptr存储var的地址
1,什么是内存地址
内存是计算机用于存储数据和程序的地方,它被划分成一个个连续的存储单元,每个存储单元都有一个唯一的编号,这个编号就是内存地址。内存地址就像图书馆里书架上的格子编号一样,通过它可以准确地找到和操作存储在相应位置的数据。CPU 通过内存地址来访问和读写内存中的数据,数据在内存中的存储、读取和修改等操作都依赖于内存地址来确定具体位置。
2,指针在不同系统下所占内存
指针占用的内存大小取决于所使用的计算机系统的架构和编译器等因素:
以下是一个简易输出在64位32位的情况下所占用字节。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{int* intPtr; size_t ptrSize = sizeof(intPtr);printf("int指针占用的字节数: %zu 字节\n", ptrSize);return 0;
}
在 32 位系统中,指针通常占用 4 个字节的内存空间。这是因为 32 位系统的地址总线是 32 位的,它能够表示的地址范围是2的32次方个不同的地址,所以需要 4 个字节来存储一个地址。
在 64 位系统中,指针一般占用 8 个字节的内存。因为 64 位系统的地址总线是 64 位,可表示的地址范围是2的64次方个,所以需要 8 个字节来存储一个地址。
三,指针的声明和初始化以及类型
1,指针的声明
指针是一种变量,它存储的是内存地址。通过指针,我们可以直接访问和操作内存中的数据。定义指针的一般形式为。
数据类型 *指针变量名;
1.这里定义了一个名为p
的指针变量,它可以指向一个int
类型的数据。
int *p;
2,指针 的初始化
1, 指针在定义后可以进行初始化,使其指向一个已存在的变量。
int num = 10;
int *p = #
2,里&
是取地址运算符,它获取变量num的内存地址,并将其赋值给指针p
,此时p就指向了变量num。也可以先定义指针,再进行赋
int num = 10;
int *p;
p = #
3,这是最安全的初始化方式之一,将指针初始化位null(空指针),表示指针不知想任何有效的内存地址。null是一个特殊的指针值,通常定义位0。
int* p = NULL; // 初始化为NULLif(p == NULL) {printf("p是NULL\n");}
4,通过动态内存分配函数(如malloc、calloc
、realloc
)分配内存,并将指针初始化为分配的内存地址。这种方式适用于需要在运行时动态分配内存的场景(仅展示malloc)。
#include <stdio.h>
#include <stdlib.h>
int main()
{int* p = (int*)malloc(sizeof(int)); // 动态分配一个整型变量的内存if (p != NULL) {*p = 10; // 使用分配的内存printf("%d\n", *p);free(p); // 释放分配的内存}else {printf("失败\n");}return 0;
}
1, 初始化方式优点及适用场景
初始化方式 | 优点 | 适用场景 |
初始化为NULL | 避免野指针错误 | 不确定指针指向 |
初始化为动态分配的内存 | 动态管理内存 | 需要动态分配内存 |
初始化为变量的地址 | 简单直观,方便操作变量 | 需要通过指针修改变量 |
4,指针的声明初始化类型
在C语言中,指针的初始化不单单只有int类型可以初始化,还有以下:
int *p1; // 整型指针
char *p2; // 字符指针
float *p3; // 浮点指针
double *p4; // 双精度指针
void *p5; // 无类型指针
四,野指针(永远都要避免)
野指针是C语言中一个非常危险且常见的问题,它是指向一个无效、未分配或已经被释放的内存地址的指针。野指针的存在可能导致程序出现不可预知的行为,甚至崩溃。以下是关于野指针的详细解释,包括定义、产生原因、危害以及预防方法
1,野指针的定义
野指针是指向未知或无效内存区域的指针。它不是NULL
指针,而是指向已经被释放或从未被分配的内存的指针。野指针的值是随机的,因此它可能指向任何内存位置,这使得野指针的使用非常危险。
2,野指针产生的原因
1,指针没有初始化
任何指针变量刚被创建时不会自动成为 NULL 指针,其缺省值是随机的。如在 C 语言中 int *p;
这样声明一个指针后,如果不对其初始化就使用,它就是野指针。
int *p; // 未初始化,p是一个野指针
*p = 10; // 随机地址赋值,可能导致程序崩溃
2,释放内存后未置空
当使用 free
或 delete
等操作释放了动态分配的内存后,如果没有将指针设置为 NULL
,而是继续使用该指针,那么它就会变成野指针。例如在 C 语言中,int *p = (int *)malloc(sizeof(int)); free(p);
执行完 free
后,p
就成为野指针。
int *p = (int*)malloc(sizeof(int)); // 分配内存
free(p); // 释放内存,但 p 仍指向原地址
// 此时 p 成为野指针,访问 *p 会导致未定义行为
3.局部变量超出作用域
不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。例如在函数内部定义一个局部变量,然后返回指向该局部变量的指针,当函数结束后,该局部变量的内存被释放,指针就成了野指针。
int* createDanglingPointer()
{int localVar = 10;return &localVar; // 返回局部变量的地址
}// 函数结束后,localVar 内存被释放,返回的指针变为野指针
3,野指针的危害
问题 | 表现 |
程序崩溃 | 访问已释放的内存可能导致段错误 |
数据损坏 | 野指针可能意外修改其他有效内存区域的数据。 |
安全问题 | 攻击者可能利用野指针篡改程序逻辑 |
调试困难 | 野指针引发的错误具有随机性,难以复现和定位。 |
4,如何避免野指针
1,初始化指针:在声明指针时,如果可能的话,立即将其初始化为 NULL
或一个有效的内存地址。
2,释放内存后设置指针为 NULL:在释放了指针所指向的内存后,立即将指针设置为 NULL
,以防止野指针的产生。
3,避免数组越界:确保数组访问在有效的索引范围内。使用循环和条件语句来检查索引是否在有效范围内。
4,避免返回局部变量地址:确保返回的指针指向堆内存或静态存储区的数据。
5,使用工具进行内存检查:使用如 Valgrind 这样的内存检查工具可以帮助发现野指针和其他内存相关的问题。(Valgrind、Clang Static Analyzer)
五,取地址符和解引用
1,取地址符&
去支付是指针的核心要在,没有去支付就算不的它是一个指针。
int age = 25;
int *ptr = &age;
2,解引用 *
指针是一个变量,它存储的是另一个变量的内存地址。解引用操作就是通过指针访问其所指向的内存地址中的值。在 C 语言中,使用星号
*
来进行解引用操作
printf("%d", *ptr); // 输出25
*ptr = 30; // 修改实际变量值
六,指针的算术运算
指针的算术运算是C语言中一个非常重要的概念,它允许我们通过指针来访问和操作数组、字符串等数据结构。指针的算术运算包括加法、减法和自增/自减运算。
1. 指针加法
指针加法是指将一个整数加到指针上,结果是一个新的指针,它指向原指针所指向的地址加上该整数乘以指针类型所占字节数的内存位置。
#include <stdio.h>
int main()
{int arr[5] = { 10, 20, 30, 40, 50 };int* p = arr; // 指针p指向数组arr的首元素// 指针p加上2p = p + 2;printf("指针移动后所指向的值: %d\n", *p); // 输出30return 0;
}
2. 指针减法
指针减法是指将一个整数从指针中减去,结果是一个新的指针,它指向原指针所指向的地址减去该整数乘以指针类型所占字节数的内存位置。
#include <stdio.h>
int main()
{int arr[5] = { 10, 20, 30, 40, 50 };int* p = arr + 4; // 指针p指向数组arr的最后一个元素// 指针ptr减去1p = p - 1;printf("指针移动后所指向的值: %d\n", *p); // 输出40return 0;
}
3. 指针自增/自减
指针自增(p++
)和自减(p--
)运算符用于将指针移动到下一个或上一个元素的位置。这相当于在指针上加或减1。
#include <stdio.h>
int main()
{char str[] = "Hello";char* c = str;while (*c != '\0') {putchar(*c);c++; // 逐个访问字符}
}
4. 指针与整数的比较
指针可以与整数进行比较,但这种比较通常没有意义,因为指针的值是内存地址,而整数是数值。唯一有意义的比较是指针与NULL
的比较,这可以用来检查指针是否为空。
#include <stdio.h>
int main() {int* p = NULL;if (p == NULL) {printf("NULL\n");}return 0;
}
七,指针与数组
在 C 语言中,指针数组是一种非常实用的数据结构,它结合了指针和数组的特性。下面将从定义、初始化、使用场景、注意事项等方面详细介绍指针数组。
1,定义
指针数组是一个数组,数组中的每个元素都是一个指针。
数据类型 *数组名[数组大小];
2,初始化
指针数组可以在定义时进行初始化,也可以在后续的代码中逐个赋值。
#include <stdio.h>
int main()
{int num1 = 10, num2 = 20, num3 = 30;int* ptrArray[3] = { &num1, &num2, &num3 };for (int i = 0; i < 3; i++) {printf("ptrArray[%d] 指向的值: %d\n", i, *ptrArray[i]);}return 0;
}
3,指针数组与字符串
指针数组在处理字符串时非常有用,因为 C 语言中的字符串实际上是字符数组,我们可以使用指针数组来存储多个字符串。
#include <stdio.h>
int main()
{char* strArray[] = { "Hello", "World", "C Language" };for (int i = 0; i < 3; i++) {printf("strArray[%d]: %s\n", i, strArray[i]);}return 0;
}
如上述示例所示,指针数组可以方便地存储和操作多个字符串,比二维字符数组更加灵活。
八,指针与函数
在 C 语言中,指针和函数有着紧密的联系,它们相互配合可以实现许多强大的功能。下面从函数参数传递指针、函数返回指针、函数指针这三个方面详细介绍指针与函数的关系。
1. 函数参数传递指针
在 C 语言里,函数参数传递分为值传递和地址传递(指针传递)。值传递只是将实参的值复制给形参,在函数内部对形参的修改不会影响到实参;而地址传递是将实参的地址传递给形参,这样函数内部就可以通过指针直接操作实参所指向的内存空间,从而修改实参的值。
#include <stdio.h>
// 交换两个整数的值,使用指针作为参数
void swap(int* a, int* b)
{int temp = *a;*a = *b;*b = temp;
}
int main()
{int x = 10, y = 20;printf("交换前: x = %d, y = %d\n", x, y);swap(&x, &y);printf("交换后: x = %d, y = %d\n", x, y);return 0;
}
2. 函数返回指针
函数可以返回一个指针,这样可以将函数内部动态分配的内存地址或者某个变量的地址返回给调用者。需要注意的是,返回的指针必须指向有效的内存区域,避免返回局部变量的地址,因为局部变量在函数执行结束后会被销毁,其地址将变得无效。
#include <stdio.h>
#include <stdlib.h>
// 动态分配内存并存储一个整数,返回指向该内存的指针
int* createInt(int value)
{int* ptr = (int*)malloc(sizeof(int));if (ptr != NULL) {*ptr = value;}return ptr;
}
int main()
{int* numPtr = createInt(100);if (numPtr != NULL) {printf("动态分配内存中存储的值: %d\n", *numPtr);free(numPtr); // 释放动态分配的内存}return 0;
}
3. 函数指针
函数指针是指向函数的指针变量,它可以存储函数的入口地址,通过函数指针可以调用相应的函数。函数指针的定义形式为:返回类型(*指针名)(参数列表);
#include <stdio.h>
// 定义两个函数
int add(int a, int b)
{return a + b;
}
int subtract(int a, int b)
{return a - b;
}
int main()
{// 定义一个函数指针,指向返回值为int,参数为两个int类型的函数int (*funcPtr)(int, int);// 让函数指针指向add函数funcPtr = add;printf("add函数调用结果: %d\n", funcPtr(5, 3));// 让函数指针指向subtract函数funcPtr = subtract;printf("subtract函数调用结果: %d\n", funcPtr(5, 3));return 0;
}
4,注意事项(必看)
- 内存管理:当函数返回指针时,要确保返回的指针指向有效的内存区域,并且在不再使用时及时释放动态分配的内存,防止内存泄漏。
- 空指针检查:在使用函数返回的指针或函数指针之前,最好进行空指针检查,避免对空指针进行操作导致程序崩溃。
- 函数指针类型匹配:函数指针的类型必须与所指向的函数的返回类型和参数列表完全匹配,否则会导致编译错误或未定义行为。
九,多级指针
多级指针,也就是指针的指针,在 C 语言里是一个较为高级且强大的特性。下面会从多级指针的定义、初始化、使用场景、注意事项等方面进行详细介绍。
1. 多级指针的定义与初始化
1,定义
多级指针是指指向指针的指针,常见的有二级指针、三级指针等。
数据类型 *指针变量名; //一级指针
数据类型 **指针变量名; //二级指针
数据类型 ***指针变量名; //三级指针
2,初始化
多级指针的初始化需要关联到一个已存在的指针。
#include <stdio.h>
int main()
{int num = 10;int *p = #int **pp = &p;printf("通过二级指针访问num的值: %d\n", **pp);return 0;
}
2. 多级指针的使用场景
1,动态二维数组
在 C 语言里,可以借助二级指针来动态创建二维数组。
#include <stdio.h>
#include <stdlib.h>
int main()
{int rows = 3, cols = 4;int** matrix;// 为行指针分配内存matrix = (int**)malloc(rows * sizeof(int*));if (matrix == NULL) {fprintf(stderr, "内存分配失败\n");return 1;}// 为每一行分配内存for (int i = 0; i < rows; i++) {matrix[i] = (int*)malloc(cols * sizeof(int));if (matrix[i] == NULL) {fprintf(stderr, "内存分配失败\n");return 1;}}// 初始化二维数组for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {matrix[i][j] = i * cols + j;}}// 输出二维数组for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {printf("%d ", matrix[i][j]);}printf("\n");}// 释放内存for (int i = 0; i < rows; i++) {free(matrix[i]);}free(matrix);return 0;
}
2,函数参数传递
在函数中使用多级指针作为参数,可以修改调用函数中的指针变量。
#include <stdio.h>
#include <stdlib.h>
void allocateMemory(int** ptr)
{*ptr = (int*)malloc(sizeof(int));if (*ptr != NULL) {**ptr = 100;}
}
int main()
{int* p = NULL;allocateMemory(&p);if (p != NULL) {printf("分配内存中存储的值: %d\n", *p);free(p);}return 0;
}
3. 多级指针的注意事项
-
内存管理:当使用多级指针进行动态内存分配时,必须注意内存的分配和释放顺序。一般来说,要先释放内层指针指向的内存,再释放外层指针指向的内存,避免内存泄漏。例如在上面动态二维数组的例子中,要先释放每一行的内存,再释放存储行指针的内存。
-
查空指针检:在使用多级指针之前,要进行空指针检查,防止对空指针进行解引用操作,从而避免程序崩溃。比如在分配内存时,如果返回
NULL
,就需要进行错误处理。 -
理解解引用操作:多级指针涉及多次解引用操作,要清楚每次解引用所访问的对象。例如,二级指针
**pp
需要两次解引用才能访问到最终的数据,理解这个过程有助于正确使用多级指针。
相关文章:

指针(C语言)从0到1掌握指针,为后续学习c++打下基础
目录 一,指针 二,内存地址和指针 1,什么是内存地址 2,指针在不同系统下所占内存 三,指针的声明和初始化以及类型 1,指针的声明 2,指针 的初始化 1, 初始化方式优点及适用场景 4,指针的声明初始化类型…...

实验八 JSP访问数据库
实验八 JSP访问数据库 目的: 1、熟悉JDBC的数据库访问模式。 2、掌握使用My SQL数据库的使用 实验要求: 1、通过JDBC访问mysql数据,实现增删改查功能的实现 2、要求提交实验报告,将代码和实验结果页面截图放入报告中 实验过程&a…...
Day31-【AI思考】-关键支点识别与战略聚焦框架
文章目录 关键支点识别与战略聚焦框架**第一步:支点目标四维定位法****第二步:支点验证里程碑设计****第三步:目标网络重构方案****第四步:动态监控仪表盘** 执行工具箱核心心法 关键支点识别与战略聚焦框架 让思想碎片重焕生机的…...
DeepSeek与其他大模型相比
DeepSeek与其他大模型相比 与GPT-4对比 性能方面 推理速度:DeepSeek在解决复杂的数学、物理和逻辑推理问题方面速度惊人,是ChatGPT的两倍。“幻觉”现象:在处理需要网络信息检索的任务时,DeepSeek的“幻觉”现象似乎比ChatGPT更少。创意任务:ChatGPT在创意性任务,如创作…...

在深度Linux (Deepin) 20中安装Nvidia驱动
文章创作不易,麻烦大家点赞关注收藏一键三连。 在Deepin上面跑Tensorflow, pytorch等人工智能框架不是一件容易的事情。特别是如果你要使用GPU,就得有nvidia的驱动。默认情况下Deepin系统自带的是nouveau开源驱动。这是没办法用tensorflow的。下面内容是…...
“LoRA技术中参数初始化策略:为何A参数采用正态分布而B参数初始化为0”
在LoRA(Low-Rank Adaptation)中,参数A和B的初始化策略是经过精心设计的,以确保模型训练的稳定性和有效性。具体来说,参数A通常被初始化为正态分布,而参数B则初始化为0。这样的设计有以下几个优点࿱…...

C语言初阶力扣刷题——349. 两个数组的交集【难度:简单】
1. 题目描述 力扣在线OJ题目 给定两个数组,编写一个函数来计算它们的交集。 示例: 输入:nums1 [1,2,2,1], nums2 [2,2] 输出:[2] 输入:nums1 [4,9,5], nums2 [9,4,9,8,4] 输出:[9,4] 2. 思路 直接暴力…...
理解动手学深度学习的自编包d2l
跟着李沐的《动手学深度学习-PyTorch版》入门Python编程和Pytorch框架,以前是重度Matlab用户,对于Python里的各种包很不习惯。特别是,本书还自己做了一个名为d2l包,有几个问题很是困惑。今天终于弄明白了,写在这里&…...
RK3568使用opencv(使用摄像头捕获图像数据显示)
文章目录 一、opencv相关的类1. **cv::VideoCapture**2. **cv::Mat**3. **cv::cvtColor**4. **QImage**5. **QPixmap**总结 二、代码实现 一、opencv相关的类 1. cv::VideoCapture cv::VideoCapture 是 OpenCV 中用于视频捕捉的类,常用于从摄像头、视频文件、或者…...

OpenEuler学习笔记(十六):搭建postgresql高可用数据库环境
以下是在OpenEuler系统上搭建PostgreSQL高可用数据环境的一般步骤,通常可以使用流复制(Streaming Replication)或基于Patroni等工具来实现高可用,以下以流复制为例: 安装PostgreSQL 配置软件源:可以使用O…...
数学平均数应用
给定一个长度为 n 的数组 a。在一次操作中,你可以从索引 2 到 n−1中选择一个索引i,然后执行以下两个操作之一: 将 a[i−1] 减少 1,同时将 a[i1] 增加 1。 将 a[i1] 减少 1,同时将 a[i−1] 增加 1。 在每次操作后&…...

元旦和春节取名的历史变迁
在中国漫长的历史长河中的春节,真要追溯起来也只有一百多年历史——是从晚清时期才逐渐出现在国人的生活里的,而且那时不叫“春节”而叫“元旦”。只不过随着历史的发展过程,“过年”这个名词也一直在演变,直至1949年最终才定下来…...
USB鼠标的数据格式
USB鼠标的数据格式由HID(Human Interface Device)协议定义,通常包含3个字节的标准数据,具体格式如下: 字节内容描述第1字节按键状态Bit 0: 左键按下(1)<br>Bit 1: 右键按下(1…...

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.27 线性代数王国:矩阵分解实战指南
1.27 线性代数王国:矩阵分解实战指南 #mermaid-svg-JWrp2JAP9qkdS2A7 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-JWrp2JAP9qkdS2A7 .error-icon{fill:#552222;}#mermaid-svg-JWrp2JAP9qkdS2A7 .erro…...
Kafka常见问题之 java.io.IOException: Disk error when trying to write to log
文章目录 Kafka常见问题之 java.io.IOException: Disk error when trying to write to log1. 问题概述2. 问题排查方向(1)磁盘空间不足(2)磁盘 I/O 故障(3)Kafka 日志文件损坏(4)Kaf…...

libOnvif通过组播不能发现相机
使用libOnvif库OnvifDiscoveryClient类, auto discovery new OnvifDiscoveryClient(QUrl(“soap.udp://239.255.255.250:3702”), cb.Build()); 会有错误: end of file or no input: message transfer interrupted or timed out(30 sec max recv delay)…...
Flink (十二) :Table API SQL (一) 概览
Apache Flink 有两种关系型 API 来做流批统一处理:Table API 和 SQL。Table API 是用于 Scala 和 Java 语言的查询API,它可以用一种非常直观的方式来组合使用选取、过滤、join 等关系型算子。Flink SQL 是基于 Apache Calcite 来实现的标准 SQL。无论输入…...

FFmpeg(7.1版本)的基本组成
1. 前言 FFmpeg 是一个非常流行的开源项目,它提供了处理音频、视频以及其他多媒体内容的强大工具。FFmpeg 包含了大量的库,可以用来解码、编码、转码、处理和播放几乎所有类型的多媒体文件。它广泛用于视频和音频的录制、转换、流媒体传输等领域。 2. F…...
基于微信小程序的辅助教学系统的设计与实现
标题:基于微信小程序的辅助教学系统的设计与实现 内容:1.摘要 摘要:随着移动互联网的普及和微信小程序的兴起,基于微信小程序的辅助教学系统成为了教育领域的一个新的研究热点。本文旨在设计和实现一个基于微信小程序的辅助教学系统,以提高教…...

单片机基础模块学习——超声波传感器
一、超声波原理 左边发射超声波信号,右边接收超声波信号 左边的芯片用来处理超声波发射信号,中间的芯片用来处理接收的超声波信号 二、超声波原理图 T——transmit 发送R——Recieve 接收 U18芯片对输入的N_A1信号进行放大,然后输入给超声…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...

DeepSeek越强,Kimi越慌?
被DeepSeek吊打的Kimi,还有多少人在用? 去年,月之暗面创始人杨植麟别提有多风光了。90后清华学霸,国产大模型六小虎之一,手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水,单月光是投流就花费2个亿。 疯…...
boost::filesystem::path文件路径使用详解和示例
boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类,封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解,包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...
2025.6.9总结(利与弊)
凡事都有两面性。在大厂上班也不例外。今天找开发定位问题,从一个接口人不断溯源到另一个 接口人。有时候,不知道是谁的责任填。将工作内容分的很细,每个人负责其中的一小块。我清楚的意识到,自己就是个可以随时替换的螺丝钉&…...
后端下载限速(redis记录实时并发,bucket4j动态限速)
✅ 使用 Redis 记录 所有用户的实时并发下载数✅ 使用 Bucket4j 实现 全局下载速率限制(动态)✅ 支持 动态调整限速策略✅ 下载接口安全、稳定、可监控 🧩 整体架构概览 模块功能Redis存储全局并发数和带宽令牌桶状态Bucket4j Redis分布式限…...