当函数参数为一级指针,二级指针
当函数参数为一级指针,二级指针
在讲述内容之前,先讲四点重要知识
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++中,当我们将一个变量作为参数传递给一个函数时,通常有两种方式:值传递和引用传递。
- 值传递:当我们通过值传递一个变量时,实际上是在内存中创建了这个变量的一个副本。这个副本有自己的内存地址,与原始变量的地址不同。因此,当我们在函数中修改这个副本的值时,原始变量的值并不会改变。
- 引用传递:当我们通过引用或指针传递一个变量时,我们实际上是将原始变量的内存地址传递给了函数。因此,函数中对参数的任何修改都会直接反映到原始变量上,因为它们共享同一块内存空间
二、一级指针 传地址
#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++中,一级指针和二级指针作为函数参数有着不同的用途。
- 一级指针:当我们将一个一级指针作为函数参数时,我们可以在函数内部修改该指针所指向的值,但不能改变该指针本身。例如:
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。
- 二级指针:当我们将一个二级指针作为函数参数时,我们可以在函数内部修改该二级指针所指向的一级指针本身。例如:
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`。
相关文章:

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

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

阿里云推出AI编程工具“通义灵码“;生成式 AI 入门教程 2
🦉 AI新闻 🚀 阿里云推出AI编程工具"通义灵码",支持多种语言及实时续写功能 摘要:阿里云推出了一款名为"通义灵码"的AI编程工具,支持多种主流编程语言,包括Java、Python、Go等。该工…...

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

逆袭Flutter? Facebook 发布全新跨平台引擎 Hermes!
Facebook 于前日发布了新的 JavaScript 引擎:Hermes,专注于提高 React Native 应用的性能,并且在市面上那些内存较少、存储速度较慢且计算能力低下的移动设备上都有良好的表现。但是不是为了追赶Flutter?这块作者没有说明。 移动应…...
c++ 互斥锁使用详解 lock_guard
c 互斥锁使用详解 std::mutex 用于保护共享资源,防止多个线程同时修改共享资源而引发竞争条件。 成员函数 lock:锁定互斥,若互斥不可用则阻塞。try_lock:尝试锁定互斥,若互斥不可用则返回。unlock:解锁…...

【快速解决】Android Button页面跳转功能
目录 让我们直接开始 第一步:先建立一个新的activity 编辑 第二步:打开第一个页面的Java文件MainActivity 方法一:直接跳转功能如下: 方法二:输入密码才能进行跳转功能如下: 需要注意的地方 结语 让…...
C语言 pthread_create
备注void *,最好添加返回值 原因:在实践中,虽然你的函数可能不需要返回任何值,但为了与 pthread_create 函数的预期函数指针格式相匹配,最好遵守函数指针所需的返回类型。这是一种良好的编程实践,确保你的代…...
前端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的简单介绍和功能实操,实操主要是OpenFeign的超时和重试,在阅读本文章前,请完成《Nacos 注册中心介绍与实操》内的Nacos多模块生产消费者项目 什么是OpenFeign OpenFeign全名Spring Cloud OpenFeignÿ…...

webpack 高级
高级配置就是要进行 webpack 优化,让代码在编译、运行时性能更好 主要从以下角度去优化: 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 项目用的依赖和实现 摸索了大半年了大概构建一套用起来还算轻松的体系……?基本上应该是说可以应对大部分的项目了 使用的依赖 目前项目还在 refactoring 的阶段,所以乱得很,这里是新建一个…...

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

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

Mongoose 开源库--Filesystem(文件系统)使用笔记
一、相关API Mongoose 开源库中也包含 文件系统 相关的 API,如下: 文件虚拟层: 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…...

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

【Linux】Nginx安装使用负载均衡及动静分离(前后端项目部署),前端项目打包
一、Nginx导言 1、引言 Nginx 是一款高性能的 Web 服务器和反向代理服务器,也可以充当负载均衡器、HTTP 缓存和安全防护设备。它的特点是内存占用小、稳定性高、并发性强、易于扩展,因此在互联网领域得到了广泛的使用。 总结出以下三点: 负载均衡&#…...

银行和金融企业为何青睐这8款项目管理工具
银行、金融行业中主流的8款项目管理系统:1.PingCode;2.Worktile;3.Microsoft Project;4.Jira by Atlassian;5.Asana;6.Trello;7.Wrike;8.Teambition。 银行和金融性质的公司在项目管…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...