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

TypeScript 函数

函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义 行为 的地方。 TypeScript为JavaScript函数添加了额外的功能,让我们可以更容易地使用。

在 TypeScript 中,函数是用于执行特定任务并可能返回结果的代码块。

函数类型

可以为函数定义类型来明确函数的参数类型和返回值类型。

// 有名字的函数
function sum(a: number, b: number): number {return a + b;
}
// 匿名函数
let mySum = function(x: number, y: number): number { return x + y; };

这里明确了 sum 函数接受两个 number 类型的参数 ab,并返回一个 number 类型的值。

书写完整函数类型

函数类型包含两部分:参数类型和返回值类型。 当写出完整函数类型的时候,这两部分都是需要的。

在函数和返回值类型之前使用( =>)符号。

返回值类型是函数类型的必要部分,如果函数没有返回任何值,必须指定返回值类型为 void 而不能留空。

let mySum: (x: number, y: number) => number =function(x: number, y: number): number { return x + y; };

在这段代码中:

  • let mySum: (x: number, y: number) => number 这部分定义了一个变量 mySum,并指定了它的类型为接受两个 number 类型参数并返回 number 类型值的函数类型。
  • 然后通过 function(x: number, y: number): number { return x + y; }mySum 变量赋值了一个具体的函数实现。

以参数列表的形式写出参数类型,为每个参数指定一个名字和类型:

let mySum: (a: number, b: number) => number =function(x: number, y: number): number { return x + y; };

在这段代码中,虽然函数定义中的参数名 ab 与函数实现中的参数名 xy 不同,但它们的类型都是 number,这是匹配的。

TypeScript 在类型检查时关注的是参数的类型,而不是参数的名称。只要参数的类型符合函数类型定义的要求,代码就可以通过类型检查。

在定义函数的类型时,只考虑参数的类型和返回值的类型。

函数中使用的捕获变量不会体现在类型里。 实际上,这些变量是函数的隐藏状态并不是组成API的一部分。
这是因为这些捕获变量属于函数的内部实现细节,对于使用该函数的外部代码来说,并不需要知道这些内部的状态。函数的 API 主要是通过其公开的参数和返回值来与外部进行交互和通信。
示例:

let outerValue = 10;function myFunction(x: number): number {let innerValue = 5;return x + outerValue + innerValue;
}

在上述 myFunction 函数中,outerValue 是捕获的外部变量,innerValue 是函数内部的变量,它们都不会体现在函数的类型 (x: number) => number 中。

推断类型

如果在赋值语句的一边指定了类型,但是另一边没有类型的话,TypeScript编译器会自动识别出类型:

let mySum = function(x: number, y: number): number { return x + y; };

在这个例子中,mySum 的类型会被推断为 (x: number, y: number) => number
在这里插入图片描述

可选参数和默认参数

JavaScript里,每个参数都是可选的,可传可不传。 没传参的时候,它的值就是undefined

TypeScript里的每个函数参数都是必须的。传递给一个函数的参数个数必须与函数期望的参数个数一致。

在 TypeScript 中,可选参数和默认参数为函数提供了更灵活的参数设置方式。

可选参数

通过在参数名后面添加 ? 来标记参数为可选参数。调用函数时,可以选择不传递该参数。
示例:

function printInfo(name: string, age?: number) {console.log(`Name: ${name}, Age: ${age ?? 'no age'}`);
}printInfo("张三");      // "Name: 张三, Age: no age"
printInfo("李四", 25);  // "Name: 李四, Age: 25" 
printInfo("王二", 0);   // "Name: 王二, Age: 0" 

可选参数必须跟在必须参数后面。
这是为了确保在调用函数时,必需的参数能够按照正确的顺序被传递,而不会因为可选参数的存在导致参数传递的混乱。

默认参数

可以为参数指定一个默认值,如果调用函数时没有传递该参数或传递的值是undefined时,就会使用默认值。

function printInfo(name: string, age: number = 18) {console.log(`Name: ${name}, Age: ${age}`);
}
printInfo("张三");      // "Name: 张三, Age: 18" 
printInfo("李四", 25);  // "Name: 李四, Age: 25" 
printInfo("王二", undefined);   // "Name: 王二, Age: 18" 

当一个参数在所有必需参数之后并且有默认初始化值时,它就具有了可选的性质。
printInfo 函数中,age 参数具有默认值 18 ,所以在调用函数时可以省略它,就像可选参数一样。

与普通可选参数不同的是,带默认值的参数不需要放在必须参数的后面。 如果带默认值的参数出现在必须参数前面,用户必须明确的传入 undefined值来获得默认值。
示例:

function printInfo(name: string = "张三", age: number) {console.log(`Name: ${name}, Age: ${age}`);
}
printInfo(undefined, 18);   // "Name: 张三, Age: 18" 
printInfo("李四", 25);      // "Name: 李四, Age: 25" // 假如只传入 age 
printInfo(25); // Error: Expected 2 arguments, but got 1.

剩余参数

必要参数、默认参数、可选参数有个共同点:它们表示某一个参数。
有时,想同时操作多个参数,或者并不知道会有多少参数传递进来。 在JavaScript里,你可以使用 arguments来访问所有传入的参数。

在 TypeScript 中,剩余参数用于表示不确定数量的参数。它使用 ... 语法来定义。
剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。

function sumAll(numbers: number[], ...restNum: number[]) {let total = 0;for (const num of numbers) {total += num;}for (const num of restNum) {total += num;}return total;
}// 没有剩余参数
console.log(sumAll([1, 2, 3])); // 6// 有 3 个剩余参数
console.log(sumAll([1, 2, 3], 4, 5, 6));  // 21

在为带有剩余参数的函数定义类型时,也需要正确地表示剩余参数的部分。
实现 sumAll 函数的类型定义:

let myFunction: (numbers: number[], ...restNum: number[]) => number = sumAll;// 参数名字可以不一样,但是参数的类型必须一样
let myFunc: (nums: number[], ...rest: number[]) => number = sumAll;

this和箭头函数

在普通函数中,this 的值取决于函数的调用方式。如果是作为对象的方法被调用,this 指向该对象;如果是独立调用,非严格模式下,this 通常指向全局对象(在浏览器环境中是 window,在 Node.js 环境中是 global)。严格模式下, thisundefined

非严格模式下:

// 作为对象的方法被调用
let obj = {method: function() {console.log(this);  // 这里的 this 指向 obj 对象}
};
obj.method();// 独立调用
function standalone() {console.log(this);  // 在浏览器中,这里的 this 指向 window 对象
}
standalone();

严格模式下:

// 作为对象的方法被调用
let strictObj = {strictMethod: function() {"use strict";console.log(this);  // 这里的 this 指向 strictObj 对象}
};
strictObj.strictMethod();// 独立调用
function strictStandalone() {"use strict";console.log(this);  // 这里的 this 是 undefined
}
strictStandalone();

可以在浏览器中执行代码来验证结果。

箭头函数中的 this 继承自其定义时所在的上下文,不会因为调用方式的不同而改变。

let obj = {method: () => {// "use strict";console.log(this); // 在浏览器中,这里的 this 指向 window 对象}
};
obj.method();

这段代码中,无论是严格模式还是非严格模式,this 都指向 window 对象。
箭头函数 method 是在对象 obj 中定义的,由于是箭头函数,this 并不指向 obj ,而是继承了外部(即全局)的 this 值。在浏览器环境中,全局的 this 就是 window 对象。

使 this 指向obj

let obj = {width: 10,height: 10,method() {return () => {return console.log(this)}}
};
obj.method()();// 把obj.method()赋值给method变量
let method = obj.method();
method()

在这里插入图片描述
由上图运行结果可知,箭头函数里的 this 指向obj。此时,this 的 类型 是 any

this 参数

在 TypeScript 中,this 可以被显式地作为参数添加到函数的参数列表中,用于更明确地控制和处理函数内部的 this 指向。

提供一个显式的 this 参数, 让this 的类型不是any

interface OBJ {width: number;height: number;method(this: OBJ): () => number;
}let obj: OBJ = {width: 10,height: 10,method(this: OBJ) {return () => {return this.width + this.height}}
};
console.log(obj.method()()); // 20let method = obj.method(); 
console.log(method); // 20

这段代码中,thisOBJ 类型的。不论如何调用method()this始终指向OBJ

this参数在回调函数里

当把一个函数作为回调传递给库函数,并且在回调函数中使用了 this 时,确实经常会遇到 this 指向错误或为 undefined 的问题。
这是因为函数的调用方式会影响 this 的指向。如果回调函数被库函数以普通函数的方式调用,而不是作为对象的方法调用,那么 this 就不会指向预期的对象,通常会是 undefined
例如,假设有一个库函数 doAsyncOperation ,它接受一个回调函数:

function doAsyncOperation(callback: () => void) {// 模拟异步操作完成后调用回调setTimeout(callback, 1000);
}

然后有一个类 MyClass ,其中有一个方法想要在回调中使用 this

class MyClass {data: string = "Some data";performOperation() {doAsyncOperation(this.someCallback);}someCallback() {console.log(this.data);  // undefined}
}
let myC = new MyClass();
myC.performOperation();

执行myC.performOperation()语句, doAsyncOperation 内部以普通函数的方式调用 callback ,当 doAsyncOperation 调用回调函数时,this 不是指向 MyClass 的实例,而是 undefined ,导致无法访问 data 属性。回调函数的输出结果为undefined

因为在 setTimeout 内部,如果传递的回调函数是一个普通函数,那么 this 的指向取决于运行环境和调用方式。

在非严格模式下,如果是在浏览器环境中,this 通常指向 window 对象;在 Node.js 环境中,this 通常指向 global 对象。
在严格模式下,this 的值会是 undefined

someCallback 改为箭头函数:

class MyClass {data: string = "Some data";performOperation() {doAsyncOperation(this.someCallback);}someCallback = () => {console.log(this.data);  // "Some data"}
}
let myC = new MyClass();
myC.performOperation();

在上述代码中,someCallback 被定义为箭头函数。
箭头函数不会创建自己的 this 上下文,而是继承外层(即定义它的 MyClass 实例)的 this 上下文。
doAsyncOperation 函数中的异步操作完成并调用 callback (即 this.someCallback )时,由于 someCallback 是箭头函数,它所使用的 this 仍然是其定义时所在的 MyClass 实例的 this
所以,在 someCallback 函数内部,能够正确访问到 MyClass 实例的属性 data ,并将其打印出来,即输出结果为 “Some data” 。

或者:

class MyClass {data: string = "Some data";performOperation() {doAsyncOperation(() => this.someCallback());}someCallback() {console.log(this.data);  // "Some data"}
}
let myC = new MyClass();
myC.performOperation();

doAsyncOperation(() => this.someCallback()); 中,使用了一个立即执行的箭头函数。
箭头函数不会创建自己的 this 上下文,而是继承外层(即定义它的 MyClass 实例)的 this 上下文。
在这个箭头函数内部,this 正确地指向了 MyClass 的实例。

上面这个例子比较简单,再举一个复杂一点的例子。
例如,假设有一个库函数 UIElement ,库函数的作者要指定 this的类型:

interface UIElement {addClickListener(onclick: (this: void, e: CustomEvent,  params?: {[propName: string]: any}) => void): void;
}

有一个Handler类,处理自定义事件以及在不同类型的回调函数中处理数据和 this 的指向。

class Handler {info: string = "";onClickGood(this: void, e: CustomEvent) {// 通过指定 this: void ,表明该回调函数在被调用时不期望或不依赖于特定的 this 上下文。console.log(this); // undefinedconsole.log("clicked!");}onClickGood2 = (e: CustomEvent) => {// 箭头函数,this 指向 Handlerthis.info = e.detail.message;};doOther (this: void, e: CustomEvent, params?: {[propName: string]: any}) {// 在这里根据传入的 params 进行相应的处理// 如果要操作this,就使用箭头函数。console.log(e.detail.message);console.log(params);};
}let h = new Handler();
let uiElement: UIElement = {addClickListener(onclick) {const event = new CustomEvent("click", { detail: { message: "Hello" } });onclick(event);}
};uiElement.addClickListener(h.onClickGood);
uiElement.addClickListener(h.onClickGood2);let uiElementDo: UIElement = {addClickListener(onclick) {const event = new CustomEvent("click", { detail: { message: "输出用户的输入" } });let word = prompt("输入你想说的话", "");let params = {word: word}onclick(event, params);}
};uiElementDo.addClickListener(h.doOther)

函数重载

在 TypeScript 中,函数重载是指可以为同一个函数定义多个不同的签名(参数类型和返回类型的组合)。
示例:

function add(a: number, b: number): number;
function add(a: string, b: string): string;function add(a: any, b: any): any {if (typeof a === 'number' && typeof b === 'number') {return a + b;}if (typeof a ==='string' && typeof b ==='string') {return `${a} ${b}`;}throw new Error('Invalid parameters');
}console.log(add(1, 2));  // 3
console.log(add('hello', 'world')); // "hello world" 

在上述示例中,add 函数有两个不同的函数签名:一个接受两个数字参数并返回一个数字,另一个接受两个字符串参数并返回一个字符串。

函数的实现部分根据传入参数的类型来决定执行不同的逻辑。

相关文章:

TypeScript 函数

函数是JavaScript应用程序的基础。 它帮助你实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义 行为 的地方。 TypeScript为JavaScript函数添加了额外的功能&…...

C++ : namespace,输入与输出,函数重载,缺省参数

一,命名空间(namespace) 1.1命名空间的作用与定义 我们在学习c的过程中,经常会碰到命名冲突的情况。就拿我们在c语言中的一个string函数来说吧: int strncat 0; int main() {printf("%d", strncat);return 0; } 当我们运行之后&…...

目标检测 | yolov1 原理和介绍

1. 简介 论文链接:https://arxiv.org/abs/1506.02640 时间:2015年 作者:Joseph Redmon 代码参考:https://github.com/abeardear/pytorch-YOLO-v1 yolo属于one-stage算法,仅仅使用一个CNN网络直接预测不同目标的类别与…...

excel中有些以文本格式存储的数值如何批量转换为数字

一、背景 1.1 文本格式存储的数值特点 在平时工作中有时候会从别地方导出来表格,表格中有些数值是以文本格式存储的(特点:单元格的左上角有个绿色的小标)。 1.2 文本格式存储的数值在排序时不符合预期 当我们需要进行排序的时候…...

原神升级计划数据表:4个倒计时可以修改提示信息和时间,可以点击等级、命座、天赋、备注进行修改。

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><title>原神倒计时</title><style>* {margin: 0;padding: 0;box-sizing: border-box;body {background: #0b1b2c;}}header {width: 100vw;heigh…...

YoloV10 论文翻译(Real-Time End-to-End Object Detection)

​摘要 近年来&#xff0c;YOLO因其在计算成本与检测性能之间实现了有效平衡&#xff0c;已成为实时目标检测领域的主流范式。研究人员对YOLO的架构设计、优化目标、数据增强策略等方面进行了探索&#xff0c;并取得了显著进展。然而&#xff0c;YOLO对非极大值抑制&#xff0…...

第R1周:RNN-心脏病预测

本文为&#x1f517;365天深度学习训练营 中的学习记录博客 原作者&#xff1a;K同学啊 要求&#xff1a; 1.本地读取并加载数据。 2.了解循环神经网络&#xff08;RNN&#xff09;的构建过程 3.测试集accuracy到达87% 拔高&#xff1a; 1.测试集accuracy到达89% 我的环境&a…...

Golang | Leetcode Golang题解之第321题拼接最大数

题目&#xff1a; 题解&#xff1a; func maxSubsequence(a []int, k int) (s []int) {for i, v : range a {for len(s) > 0 && len(s)len(a)-1-i > k && v > s[len(s)-1] {s s[:len(s)-1]}if len(s) < k {s append(s, v)}}return }func lexico…...

远程连接本地虚拟机失败问题汇总

前言 因为我的 Ubuntu 虚拟机是新装的&#xff0c;并且应该装的是比较纯净的版本&#xff08;纯净是指很多工具都尚未安装&#xff09;&#xff0c;然后在使用远程连接工具 XShell 连接时出现了很多问题&#xff0c;这些都是我之前没遇到过的&#xff08;因为之前主要使用云服…...

WebRTC 初探

前言 项目中有局域网投屏与文件传输的需求&#xff0c;所以研究了一下 webRTC&#xff0c;这里记录一下学习过程。 WebRTC 基本流程以及概念 下面以 1 对 1 音视频实时通话案例介绍 WebRTC 的基本流程以及概念 WebRTC 中的角色 WebRTC 终端,负责音视频采集、编解码、NAT 穿…...

Python:read,readline和readlines的区别

在Python中&#xff0c;read(), readline(), 和 readlines() 是文件操作中常用的三个方法&#xff0c;它们都用于从文件中读取数据&#xff0c;但各自的使用方式和适用场景有所不同。 read() 方法&#xff1a; read(size-1) 方法用于从文件中读取指定数量的字符。如果指定了si…...

重生之我学编程

编程小白如何成为大神&#xff1f;大学新生的最佳入门攻略 编程已成为当代大学生的必备技能&#xff0c;但面对众多编程语言和学习资源&#xff0c;新生们常常感到迷茫。如何选择适合自己的编程语言&#xff1f;如何制定有效的学习计划&#xff1f;如何避免常见的学习陷阱&…...

如何将PostgreSQL的数据实时迁移到SelectDB?

PostgreSQL 作为一个开源且功能强大的关系型数据库管理系统&#xff0c;在 OLTP 系统中得到了广泛应用。很多企业利用其卓越的性能和灵活的架构&#xff0c;应对高并发事务、快速响应等需求。 然而对于 OLAP 场景&#xff0c;PostgreSQL 可能并不是最佳选择。 为了实现庞大规…...

关于c语言的const 指针

const * type A 指向的数据是常量 如上所示&#xff0c;运行结果如下&#xff0c;通过解引用的方式&#xff0c;改变了data的值 const type * A 位置是常量&#xff0c;不能修改 运行结果如下 type const * A 指针是个常量&#xff0c;指向的值可以改变 如上所示&#xff0c…...

万能门店小程序开发平台功能源码系统 带完整的安装代码包以及安装搭建教程

互联网技术的迅猛发展和用户对于便捷性需求的不断提高&#xff0c;小程序以其轻量、快捷、无需安装的特点&#xff0c;成为了众多商家和开发者关注的焦点。为满足广大商家对于门店线上化、智能化管理的需求&#xff0c;小编给大家分享一款“万能门店小程序开发平台功能源码系统…...

C#初级——字典Dictionary

字典 字典是C#中的一种集合&#xff0c;它存储键值对&#xff0c;并且每个键与一个值相关联。 创建字典 Dictionary<键的类型, 值的类型> 字典名字 new Dictionary<键的类型, 值的类型>(); Dictionary<int, string> dicStudent new Dictionary<int, str…...

git版本控制的底层实现

目录 前言 核心概念串讲 底层存储形式探测 本地仓库的详细解析 提交与分支的深入解析 几个问题的深入探讨 前言 Git的重要性 Git是一个开源的版本控制工具&#xff0c;广泛用于编程开发领域。它极大地提高了研发团队的开发协作效率。对于开发者来说&#xff0c;Git是一个…...

深入解析数据处理的技术与实践

欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 工💗重💗hao💗:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、应用领域等内容。 ⭐…...

python-调用c#代码

环境&#xff1a; win10&#xff0c;net framework 4&#xff0c;python3.9 镜像&#xff1a; C#-使用IronPython调用python代码_ironpython wpf-CSDN博客 https://blog.csdn.net/pxy7896/article/details/119929434 目录 hello word不接收参数接收参数 其他例子 hello word 不…...

构建铁路安全防线:EasyCVR视频+AI智能分析赋能铁路上道作业高效监管

一、方案背景 随着我国铁路特别是高速铁路的快速发展&#xff0c;铁路运营里程不断增加&#xff0c;铁路沿线的安全环境对保障铁路运输的安全畅通及人民群众的生命财产安全具有至关重要的作用。铁路沿线安全环境复杂多变&#xff0c;涉及多种风险因素&#xff0c;如人员入侵、…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...