当前位置: 首页 > news >正文

当函数参数为一级指针,二级指针

当函数参数为一级指针,二级指针

在讲述内容之前,先讲四点重要知识

1.当传入参数时,函数形参会立即申请形参的内存空间,函数执行完毕后,形参的内存空间立即释放掉

1.指针是存放其他变量地址的变量。指针有自己的内存空间,内存空间存放的是其他变量的地址。

2.指针具体指向谁,要看指针内存空间存放的地址。存放谁的地址就指向谁。

3.函数参数传参本质:实参传给形参,都是拷贝.

指针做函数参数的本质剖析,讲述四种情况

一、传变量

#include <iostream>
using namespace std;
#include <cstring>
using namespace std;
void change(int value)
{cout<<"change:: "<<&value<<endl;value = 20;
}int main()
{int a = 10;cout<<"main:: "<<&a<<endl;change(a);cout << a << endl;return 0;
}

在这里插入图片描述

为什么a的值没发生变化,请从地址空间的角度分析

在你的代码中,函数change接收的是变量a的值,而不是它的引用或指针。这意味着在函数change中,参数value是变量a的一个副本,它们在内存中的地址是不同的。因此,当你在函数change中修改value的值时,这个改变不会影响到原始变量a

这就是为什么打印出来的地址是不同的,并且变量a的值没有发生改变。如果你想在函数中修改变量a的值,你需要使用引用或指针。例如:

void change(int& value)
{cout<<"change:: "<<&value<<endl;value = 20;
}

或者

void change(int* value)
{cout<<"change:: "<<value<<endl;*value = 20;
}

在C++中,当我们将一个变量作为参数传递给一个函数时,通常有两种方式:值传递和引用传递。

  1. 值传递:当我们通过值传递一个变量时,实际上是在内存中创建了这个变量的一个副本。这个副本有自己的内存地址,与原始变量的地址不同。因此,当我们在函数中修改这个副本的值时,原始变量的值并不会改变。
  2. 引用传递:当我们通过引用或指针传递一个变量时,我们实际上是将原始变量的内存地址传递给了函数。因此,函数中对参数的任何修改都会直接反映到原始变量上,因为它们共享同一块内存空间

二、一级指针 传地址

#include <iostream>
using namespace std;
#include <cstring>
using namespace std;
void change(int* value)
{cout<<"change:: "<<value<<endl;*value = 20;
}int main()
{int a = 10;cout<<"main:: "<<&a<<endl;change(&a);cout << a << endl;return 0;
}

在这里插入图片描述

可见value 和 a的地址是相同的

三、一级指针 判断改变p的值不会影响到函数外部的指针


#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
void change(int *pp) { // int* pp=&Q;cout<<"pp的值"<<pp<<endl;cout<<"pp的地址"<<&pp<<endl;pp = (int *)malloc(sizeof(int));cout<<"malloc之后 pp的值"<<pp<<endl;cout<<"malloc之后 pp的地址"<<&pp<<endl;}int main() {int Q=3;int *p = &Q;cout<<"Q的地址"<<&Q<<endl;cout<<"p的值"<<p<<endl;cout<<"p的地址"<<&p<<endl;change(p);cout<<"malloc之后  p的值"<<p<<endl;cout<<"malloc之后  p的地址"<<&p<<endl;cout<<"malloc之后 Q的值 "<<*p<<endl;free(p);return 0;
}

产生中断,也就是说上面的程序存在问题,有什么问题呢?

为什么一级指针改变p的值不会影响到外部的指针

这是因为在C语言中,函数参数是通过值传递的。当你将一个一级指针作为参数传递给一个函数时,实际上传递的是这个指针的值(是它保存的内存地址,也就是它所指向的内存地址,)的一个副本。也就是说,str 的值等于 p的值,但str 本身的地址 和 p 本身的地址是不同的。

比如:

在这里插入图片描述

因为 str 和 p 的地址是不同的,所以他们是不同的指针。

在函数内部,你可以修改这个副本(把新分配的内存地址空间赋值给p,p的值(也就是p指向的内存空间变了)),但是这个修改不会影响到原来的指针。

举个例子,假设你有一个指针p,它的值(也就是它所指向的内存地址)是0x1000。当你将p作为参数传递给一个函数时,这个函数会收到一个值为0x1000的新指针。如果你在函数内部改变这个新指针的值(例如将它设置为NULL),那么这个改变只会影响到这个新指针,而不会影响到原来的p

因此,当你在函数内部改变一级指针的值时,这个改变不会影响到外部的指针。

执行malloc 函数 之后

在这里插入图片描述
在这里插入图片描述

为什么指向同一个内存地址的两个一级指针,在函数内部改变这个新的一级指针的值时,这个改变不会影响到原来的p。

这是因为在C语言中,函数参数是通过值传递的。这意味着当你将一个指针(无论是一级指针还是二级指针)作为参数传递给一个函数时,实际上传递的是这个指针的值(也就是它所指向的内存地址)的一个副本。

当你传递一个一级指针p给一个函数时,函数会收到一个新的一级指针,这个新的一级指针和p有相同的值(也就是它们都指向同一个内存地址)。但是,这个新的一级指针和p并不是同一个指针(他们本身的地址不同),它们只是有相同的值而已。因此,当你在函数内部改变这个新的一级指针的值时,这个改变不会影响到原来的p

换句话说,当你在函数内部改变一级指针的值时,你实际上是改变了这个一级指针副本的值,而不是原来的一级指针p。因为副本和原来的一级指针p是两个不同的变量,它们只是恰好有相同的值(也就是它们都指向同一个内存地址)。所以,改变副本的值并不会影响到原来的一级指针p

四、二级指针 判断改变p的值不会影响到函数外部的指针

#include <stdio.h>
#include <stdlib.h>void change(int **pp) {*pp = (int *)malloc(sizeof(int));**pp = 100;
}int main() {int *p = NULL;change(&p);printf("%d\n", *p);  // 输出:100free(p);return 0;
}

在你的代码中,change函数的参数是一个二级指针pp。当你调用change(&p)时,你实际上是将指针p的地址传递给了函数。这个地址就是二级指针pp所指向的地址。

因此,pp&p实际上是同一个地址。当你在函数中通过解引用操作符*来访问并修改pp时,你实际上是在修改原始指针p的值。这就是为什么这段代码能够成功运行并正确地修改p的值。

在这里插入图片描述
在这里插入图片描述

为什么指向同一个一级指针的二级指针,当我在函数内部改变这个新的二级指针所指向的一级指针时,这个改变会影响到原来的一级指针。

这是因为当你传递一个二级指针到一个函数时,你实际上是传递了一个指向一级指针的指针的副本。这个副本指向的是原始一级指针的内存地址。因此,当你在函数内部改变这个二级指针所指向的一级指针时,你实际上是改变了原始一级指针的值。

举个例子,假设你有一个一级指针p,它的值(也就是它所指向的内存地址)是0x1000。然后你有一个二级指针pp,它的值(也就是它所指向的内存地址)是p的地址。当你将pp作为参数传递给一个函数时,这个函数会收到一个新的二级指针,这个新的二级指针和pp有相同的值(也就是它们都指向同一个一级指针)。但是,这个新的二级指针和pp并不是同一个二级指针,它们只是有相同的值而已。然而,由于这个新的二级指针和pp都指向同一个一级指针,所以当你在函数内部改变这个新的二级指针所指向的一级指针(例如将它设置为NULL),那么这个改变会影响到原来的一级指针。

因此,当你在函数内部改变二级指针所指向的一级指针时,这个改变会影响到外部的一级指针。

这个为什么拷贝成功了呢?

在讲述之前,先注意p是二级指针,*p是一级指针,GetMemory(&str)传参时,指针变量p申请内存空间,这时有两个内存空间,str的地址拷贝给p的内存空间,即p的内存空间的内容是str的地址,这时p指向str的内存空间—>p = &str,*p = str,p 和 str两个名字,其实是相等的,指向的是同一块内存空间(上述程序在此时是NULL)。 p = (char )malloc(sizeof(100)),在堆上面申请一个100的内存空间,返回这个内存空间的首地址赋值给p;*p是一级指针,p(str)内存空间就有值了,不再是NULL,内存空间的内容是这个地址,也就是p和str指向这块内存空间,这个内存空间可以存放100个变量的地址,所以指针是存放其他变量地址的变量还是对的。接下来的strcpy(str, “hello world”)也就成功了,free(str)释放掉str(*p)所指向的内存空间.请注意,在这个过程中,p的内存空间的地址始终是str的地址,没有改变。

以上内容纯粹个人理解,如有不对之处,欢迎批评指正。


在这里插入图片描述
在这里插入图片描述

总结 二级指针和一级指针作为函数参数的区别

二级指针和一级指针作为函数参数传递时的区别

一级指针和二级指针在作为函数参数传递时的主要区别在于它们可以修改的内容。

当你传递一个一级指针到一个函数时,你可以通过这个指针修改它所指向的值,但是你不能改变这个指针本身所指向的内存地址。例如:

void func(int *p) {*p = 5;  // 可以修改p所指向的值p = NULL;  // 这里改变p的值不会影响到函数外部的指针
}

而当你传递一个二级指针到一个函数时,你既可以修改这个指针所指向的值,也可以改变这个指针本身所指向的内存地址。例如:

void func(int **p) {**p = 5;  // 可以修改p所指向的值*p = NULL;  // 这里改变*p的值会影响到函数外部的指针
}

因此,如果你想在一个函数中动态地改变一个指针所指向的内存地址,你需要传递一个二级指针。如果你只是想通过一个函数来改变一个值,那么传递一级指针就足够了。

在C++中,一级指针和二级指针作为函数参数有着不同的用途。

  1. 一级指针:当我们将一个一级指针作为函数参数时,我们可以在函数内部修改该指针所指向的值,但不能改变该指针本身。例如:
void changeValue(int *p) {*p = 100;  // 修改p所指向的值
}int main() {int a = 10;int *p = &a;changeValue(p);cout << a << endl;  // 输出:100return 0;
}

在上述代码中,我们将一级指针p作为参数传递给了changeValue函数,并在函数内部修改了p所指向的值。因此,当我们回到主函数并打印出a的值时,输出的结果是100。

  1. 二级指针:当我们将一个二级指针作为函数参数时,我们可以在函数内部修改该二级指针所指向的一级指针本身。例如:
void changePointer(int **pp) {*pp = (int *)malloc(sizeof(int));**pp = 100;  // 修改pp所指向的一级指针所指向的值
}int main() {int *p = NULL;changePointer(&p);cout << *p << endl;  // 输出:100free(p);return 0;
}

在上述代码中,我们将一级指针p的地址(也就是一个二级指针)作为参数传递给了changePointer函数,并在函数内部修改了该二级指针所指向的一级指针本身。因此,当我们回到主函数并打印出*p的值时,输出的结果是100。


#include <stdio.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
void change(int **npp) {cout<<"npp的值"<<npp<<endl;cout<<"npp的地址"<<&npp<<endl;*npp = (int *)malloc(sizeof(int));**npp = 100;cout<<"malloc之后 npp的值"<<npp<<endl;cout<<"malloc之后 npp的地址"<<&npp<<endl;
}int main() {int Q=3;int *p = &Q;int **pp=&p;cout<<"Q的地址"<<&Q<<endl;cout<<"p的值"<<p<<endl;cout<<"p的地址"<<&p<<endl;cout<<"pp的值"<<pp<<endl;cout<<"pp的地址"<<&pp<<endl;change(&p);cout<<"malloc之后  p的值"<<p<<endl;cout<<"malloc之后  p的地址"<<&p<<endl;cout<<"malloc之后  pp的值"<<pp<<endl;cout<<"malloc之后  pp的地址"<<&pp<<endl;cout<<"malloc之后 Q的值 "<<*p<<endl;free(p);return 0;
}为什么这段代码中 pp 和npp 操作的是同一块内存空间

当然可以。让我们用一个比喻来理解一下:

假设你有
一个房子(变量),这个房子有一个地址(指针)。你把这个地址写在一张纸上(一级指针作为函数参数),然后给了你的朋友(函数)。你的朋友可以通过这个地址找到你的房子,并且可以改变房子里面的东西(修改指针所指向的值),但是他不能改变房子的位置(不能改变指针本身)。

现在,假设你不仅把房子的地址写在纸上,而且还把这张纸的地址(二级指针)也写在另一张纸上,然后给了你的朋友。这次,你的朋友不仅可以改变房子里面的东西,还可以改变第一张纸上写的地址(可以改变一级指针本身)。这就好比他可以把第一张纸上的地址擦掉,然后写上一个新的地址。这样,当你看第一张纸时,你会发现房子的"位置"已经改变了。

希望这个比喻能帮助你理解一级指针和二级指针作为函数参数的区别!

例子


int recvMsg(int cfd, char** msg)
{if(msg == NULL || cfd <= 0){
return -1;}// 接收数据// 1. 读数据头int len = 0;readn(cfd, (char*)&len, 4);len = ntohl(len);printf("数据块大小: %d\n", len);// 根据读出的长度分配内存char *buf = (char*)malloc(len+1);int ret = readn(cfd, buf, len);if(ret != len){return -1;}buf[len] = '\0';*msg = buf;return ret;
}

在这个函数中,二级指针msg被用作传出参数,这是因为函数需要修改外部变量的值。在函数内部,msg指向的内存被分配给了新的数据,然后这个新的地址被赋值给了*msg。如果我们只使用一级指针作为参数,那么在函数内部对指针的修改(例如分配新的内存)将不会影响到外部的指针,因为函数参数是通过值传递的。

使用二级指针作为参数允许我们在函数内部修改一级指针的值(即改变一级指针所指向的地址),这样我们就可以将新分配的内存地址传递回函数的调用者。这就是为什么在这个函数中选择二级指针作为传出参数,而不是一级指针。

如果你选择一级指针作为传出参数,那么在函数内部对指针的修改(例如分配新的内存)将不会影响到外部的指针,因为函数参数是通过值传递的。这就意味着,即使你在函数内部为指针分配了新的内存,这个新的内存地址也无法传递回函数的调用者。

下面是一个示例,展示了如果使用一级指针作为传出参数会发生什么:

void recvMsg(int cfd, char* msg)
{// 假设len是通过某种方式获取的int len = 100;// 分配内存char *buf = (char*)malloc(len+1);// 假设我们已经将数据读入buf// ...buf[len] = '\0';msg = buf;  // 这里只是修改了函数内部的msg副本,对外部的msg没有影响
}int main() {char *str = NULL;recvMsg(cfd, str);// 此时str仍然是NULL,因为recvMsg函数内部对msg的修改并未影响到strreturn 0;
}

在上述代码中,recvMsg函数接收一个一级指针msg作为参数。然而,由于msg是通过值传递的,所以在函数内部对msg的修改并不会影响到外部的str。这就是为什么在调用recvMsg(cfd, str)后,str仍然是NULL
= 100;
// 分配内存
char buf = (char)malloc(len+1);
// 假设我们已经将数据读入buf
// …
buf[len] = ‘\0’;
msg = buf; // 这里只是修改了函数内部的msg副本,对外部的msg没有影响
}

int main() {
char *str = NULL;
recvMsg(cfd, str);
// 此时str仍然是NULL,因为recvMsg函数内部对msg的修改并未影响到str
return 0;
}

在上述代码中,`recvMsg`函数接收一个一级指针`msg`作为参数。然而,由于`msg`是通过值传递的,所以在函数内部对`msg`的修改并不会影响到外部的`str`。这就是为什么在调用`recvMsg(cfd, str)`后,`str`仍然是`NULL`。

相关文章:

当函数参数为一级指针,二级指针

当函数参数为一级指针&#xff0c;二级指针 在讲述内容之前&#xff0c;先讲四点重要知识 1.当传入参数时&#xff0c;函数形参会立即申请形参的内存空间&#xff0c;函数执行完毕后&#xff0c;形参的内存空间立即释放掉。 1.指针是存放其他变量地址的变量。指针有自己的内…...

Hydra post登录框爆破

文章目录 无token时的Hydra post登录框爆破带Token时的Hydra post登录框爆破 无token时的Hydra post登录框爆破 登录一个无验证码和token的页面&#xff0c;同时抓包拦截 取出发送数据包&#xff1a;usernameadb&password133&submitLogin 将用户名和密码替换 userna…...

阿里云推出AI编程工具“通义灵码“;生成式 AI 入门教程 2

&#x1f989; AI新闻 &#x1f680; 阿里云推出AI编程工具"通义灵码"&#xff0c;支持多种语言及实时续写功能 摘要&#xff1a;阿里云推出了一款名为"通义灵码"的AI编程工具&#xff0c;支持多种主流编程语言&#xff0c;包括Java、Python、Go等。该工…...

使用Qt Installer Framework将自己的程序打包成安装包程序

使用Qt Installer Framework将自己的程序打包成安装包程序 制作安装包程序就是将自己的程序打包成一个可执行的exe&#xff0c;双击之后进行安装。 1. 在制作安装包程序之前需要安装qt官方提供的安装包制作工具Qt Installer Framework 去qt官方网址&#xff0c;下载对应的 Q…...

逆袭Flutter? Facebook 发布全新跨平台引擎 Hermes!

Facebook 于前日发布了新的 JavaScript 引擎&#xff1a;Hermes&#xff0c;专注于提高 React Native 应用的性能&#xff0c;并且在市面上那些内存较少、存储速度较慢且计算能力低下的移动设备上都有良好的表现。但是不是为了追赶Flutter&#xff1f;这块作者没有说明。 移动应…...

c++ 互斥锁使用详解 lock_guard

c 互斥锁使用详解 std::mutex 用于保护共享资源&#xff0c;防止多个线程同时修改共享资源而引发竞争条件。 成员函数 lock&#xff1a;锁定互斥&#xff0c;若互斥不可用则阻塞。try_lock&#xff1a;尝试锁定互斥&#xff0c;若互斥不可用则返回。unlock&#xff1a;解锁…...

【快速解决】Android Button页面跳转功能

目录 让我们直接开始 第一步&#xff1a;先建立一个新的activity ​编辑 第二步&#xff1a;打开第一个页面的Java文件MainActivity 方法一&#xff1a;直接跳转功能如下&#xff1a; 方法二&#xff1a;输入密码才能进行跳转功能如下&#xff1a; 需要注意的地方 结语 让…...

C语言 pthread_create

备注void *&#xff0c;最好添加返回值 原因&#xff1a;在实践中&#xff0c;虽然你的函数可能不需要返回任何值&#xff0c;但为了与 pthread_create 函数的预期函数指针格式相匹配&#xff0c;最好遵守函数指针所需的返回类型。这是一种良好的编程实践&#xff0c;确保你的代…...

前端uniapp提交表单调用接口方法最新

目录 源码1源码2最后 源码1 <template><view class"my-add-bank-card"><!-- name"bank_name" form表单提交的input里面一定要加name绑定要传的参数 name"bank_name" type"text" v-model"address.bank_name"…...

OpenFeign的简单介绍和功能实操

前言 本文主要做一下OpenFeign的简单介绍和功能实操&#xff0c;实操主要是OpenFeign的超时和重试&#xff0c;在阅读本文章前&#xff0c;请完成《Nacos 注册中心介绍与实操》内的Nacos多模块生产消费者项目 什么是OpenFeign OpenFeign全名Spring Cloud OpenFeign&#xff…...

webpack 高级

高级配置就是要进行 webpack 优化&#xff0c;让代码在编译、运行时性能更好 主要从以下角度去优化&#xff1a; 1、提升开发体验 2、提升打包构建速度 3、减少代码体积 4、优化代码运行性能 一、提升体验 1、SourceMap 为什么 打包出来的所有css和js合并成了一个文件&#…...

OLE DB 访问接口所需的(最大)数据长度为 18,但返回的数据长度为 6。

sqlserver查询oracle链接服务器视图,报错 给最终返回的字符串进行类型转换,字符串大小按返回值最大的那个oracle源本字段类型长度 aaaaaa AS yljgbmcast(aaaaaa AS varchar(10)) AS yljgbm...

oracle (9)Storage Relationship Strut

目录 一、基础知识 1、数据库逻辑结构图 2、Types of Segments 段的类型 3、Storage Clause Precedence 存储条款的优先顺序 4、Extent Alloc & Dealloc 区的范围分配和取消分配 5、 Used and Free Extents 使用和自由区 6、Database Block 数据库块 7、Multiple B…...

React 项目结构小结

React 项目结构小结 简单的记录一下目前 React 项目用的依赖和实现 摸索了大半年了大概构建一套用起来还算轻松的体系……&#xff1f;基本上应该是说可以应对大部分的项目了 使用的依赖 目前项目还在 refactoring 的阶段&#xff0c;所以乱得很&#xff0c;这里是新建一个…...

4.网络之TCP

TCP协议(传输层) 文章目录 TCP协议(传输层)1. TCP报文格式2. TCP相关机制2.1 确认应答机制2.2 超时重传机制2.3 连接管理机制&#xff08;重点&#xff09;2.3.1 三次握手2.3.2 四次挥手 2.4 滑动窗口机制2.5 流量控制机制2.6 拥塞控制机制2.7 延迟应答机制2.8 捎带应答机制 3.…...

电池原理与分类

1 电池基础知识 电池目前大量应用于我们的生活中&#xff0c;主要包括3C消费类、动力类、储能类。 图1 电池应用方向 备注&#xff1a;3C指的是计算机(Computer )、通讯&#xff08;Communication&#xff09;消费类电子产品&#xff08;Consumer Electronic&#xff09;三类…...

Mongoose 开源库--Filesystem(文件系统)使用笔记

一、相关API Mongoose 开源库中也包含 文件系统 相关的 API&#xff0c;如下&#xff1a; 文件虚拟层&#xff1a; struct mg_fs {int (*st)(const char *path, size_t *size, time_t *mtime); // stat filevoid (*ls)(const char *path, void (*fn)(const char *, void *), v…...

新兴初创企业参展招募

一般来说&#xff0c;创业公司的生存率较低&#xff0c;失败率较高。根据不同的数据来源&#xff0c;创业公司的失败率高达 80%-90%。据统计&#xff0c;在中国每年新注册的企业数量超过 100 万家&#xff0c;但能够存活到 5 年以上的企业不足 7%&#xff0c;10 年以上不足 2%。…...

【Linux】Nginx安装使用负载均衡及动静分离(前后端项目部署),前端项目打包

一、Nginx导言 1、引言 Nginx 是一款高性能的 Web 服务器和反向代理服务器&#xff0c;也可以充当负载均衡器、HTTP 缓存和安全防护设备。它的特点是内存占用小、稳定性高、并发性强、易于扩展&#xff0c;因此在互联网领域得到了广泛的使用。 总结出以下三点: 负载均衡&#…...

银行和金融企业为何青睐这8款项目管理工具

银行、金融行业中主流的8款项目管理系统&#xff1a;1.PingCode&#xff1b;2.Worktile&#xff1b;3.Microsoft Project&#xff1b;4.Jira by Atlassian&#xff1b;5.Asana&#xff1b;6.Trello&#xff1b;7.Wrike&#xff1b;8.Teambition。 银行和金融性质的公司在项目管…...

FreeRTOS源码解析(9)任务通知

1.任务通知本质&#xff1a;直接操作目标任务的 TCB 字段。 它不自带控制块、不分配独立存储、不维护自己的等待列表——全程只做一件事&#xff1a;读写目标任务 TCB 里已有的 ulNotifiedValue 和 ucNotifyState&#xff0c;必要时将对方从延迟列表移到就绪列表。正因如此&…...

Elsevier投稿追踪插件:科研工作者的智能审稿管家

Elsevier投稿追踪插件&#xff1a;科研工作者的智能审稿管家 【免费下载链接】Elsevier-Tracker 项目地址: https://gitcode.com/gh_mirrors/el/Elsevier-Tracker 当您的论文投稿到Elsevier期刊后&#xff0c;漫长的审稿等待期往往成为科研工作者的焦虑来源。Elsevier投…...

AI智能体的开发与测试

AI智能体&#xff08;AI Agent&#xff09;的开发与测试是一项将大语言模型&#xff08;LLM&#xff09;能力转化为企业级稳定应用的系统工程。它不仅需要先进的算法&#xff0c;更依赖于严密的工程架构与创新的测试方法。以下是AI智能体开发与测试的全景指南&#xff1a;第一部…...

别再只会用DC-DC了!手把手教你用电荷泵搞定液晶屏的VGH和VGL电压

电荷泵实战&#xff1a;低成本实现LCD屏VGH/VGL电压的工程方案 在TFT-LCD驱动电路设计中&#xff0c;VGH&#xff08;栅极开启电压&#xff09;和VGL&#xff08;栅极关闭电压&#xff09;的生成一直是硬件工程师面临的挑战。传统方案多依赖DC-DC转换器&#xff0c;但面对16.4V…...

减少重复劳作,气泡图软件助力质检效率升级

在制造业做过质量或工程的人&#xff0c;一定都有过这种体验&#xff1a;一张复杂图纸几百个尺寸&#xff0c;一个个手动画气泡、编号、抄 Excel&#xff0c;眼睛越看越花&#xff0c;手指越敲越累。更折磨的是&#xff0c;图纸一改&#xff0c;气泡编号几乎要全部重来&#xf…...

Obsidian Quiz Generator:用AI与间隔重复打造动态知识库

1. 项目概述&#xff1a;当笔记遇上主动回忆如果你和我一样&#xff0c;是 Obsidian 的用户&#xff0c;并且对知识管理、学习效率有追求&#xff0c;那么你一定遇到过这个困境&#xff1a;笔记越记越多&#xff0c;知识库越来越庞大&#xff0c;但真正能“记住”并“调用”的知…...

Ghost区块链集成:NFT内容所有权与分发方案

Ghost区块链集成&#xff1a;NFT内容所有权与分发方案 内容创作者的数字版权困境 传统内容发布平台存在严重的数字版权问题&#xff1a;文章被随意转载、原创收益被平台抽成、作品归属权难以证明。根据2024年《数字内容版权报告》&#xff0c;78%的独立创作者曾遭遇内容侵权&…...

3大核心功能揭秘:MAA如何让《明日方舟》日常任务实现全自动托管

3大核心功能揭秘&#xff1a;MAA如何让《明日方舟》日常任务实现全自动托管 【免费下载链接】MaaAssistantArknights 《明日方舟》小助手&#xff0c;全日常一键长草&#xff01;| A one-click tool for the daily tasks of Arknights, supporting all clients. 项目地址: ht…...

通用 Agent 与领域 Agent 的架构差异

从GPT-4o到AI程序员助手:通用Agent与领域Agent的核心架构差异及选型指南 摘要/引言 你有没有试过同时用两款截然不同的AI工具帮你干活?比如前一秒用GPT-4o对着一张写满Python报错的截图问“为什么我的分布式爬虫在Kubernetes集群里总是崩溃”,后一秒打开Cursor编辑器的AI助…...

淘金币自动化助手架构深度解析:基于Auto.js的移动端自动化工程实践

淘金币自动化助手架构深度解析&#xff1a;基于Auto.js的移动端自动化工程实践 【免费下载链接】taojinbi 淘宝淘金币自动执行脚本&#xff0c;包含蚂蚁森林收取能量&#xff0c;芭芭农场全任务&#xff0c;解放你的双手 项目地址: https://gitcode.com/gh_mirrors/ta/taojin…...