【C++】入门(一)

在这里插入图片描述

前言:
本篇博客将带大家认识C++,熟悉基本语法


文章目录

  • 认识C++
    • C++的诞生与发展
    • C++ 在行业中的运用
  • 一、命名空间
    • 1.1 命名空间的定义
    • 1.2 命名空间的使用
    • 1.3 命名空间的访问
  • 二、C++输入&输出
    • 输出操作符 `<<`
    • 输入操作符 `>>`
    • 换行符和刷新输出缓冲区
    • 关键字 using
  • 三、缺省参数
    • 3.1 概念
    • 3.2 缺省参数分类
  • 四、函数重载
    • 概念
    • 函数重载的原理

认识C++

C++的诞生与发展

C++ 是由丹麦计算机科学家贝尔纳斯·斯特劳斯特博士(Bjarne Stroustrup)于20世纪80年代初期开发的。他在贝尔实验室工作时,对 C 语言进行了扩展,加入了OOP(object oriented programming:面向对象)思想,从而诞生了 C++。C++ 的名字中的 “++” 表示在 C 语言的基础上的一个增量,暗示这是对 C 的增强和扩展。因此:它既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。

C++ 在其发展过程中经历了多个标准版本的发布,其中最早的标准是于1998年发布的 C++98,之后又有 C++03、C++11、C++14、C++17 和 C++20 等版本。每个版本都引入了新的特性和改进,使得 C++ 成为一个强大而灵活的编程语言。

" C with Classes" 是 C++ 的前身,这个术语最初用于描述贝尔纳斯·斯特劳斯特博士在开发 C++ 时的初期版本。C++ 最初是在 C 语言的基础上引入了一些面向对象编程的概念,而 “C with Classes” 就是这个过渡阶段的命名。

C++ 在行业中的运用

  1. 系统级编程: C++ 被广泛用于开发操作系统、驱动程序和其他系统级软件,因为它提供了对硬件的底层访问和高效的系统编程能力。

  2. 游戏开发: 许多游戏引擎和大型游戏项目都使用 C++。其高性能和底层控制使其成为游戏行业的首选语言之一。

  3. 嵌入式系统: C++ 被用于开发嵌入式系统,如智能家居设备、汽车控制系统等。它的效率和灵活性使其适用于资源受限的环境。

  4. 金融领域: 在金融行业,C++ 被广泛用于开发高性能的交易系统、风险管理工具和其他金融应用。

  5. 图形界面应用: C++ 被用于开发桌面应用程序、图形用户界面(GUI)和各种图形软件。

  6. 网络编程: C++ 的网络库和框架使其成为开发网络应用和服务器端程序的理想选择。

C++ 以其高性能、灵活性和底层控制能力,成为许多领域中首选的编程语言之一。


一、命名空间

命名空间(Namespace)是一种在C++中用于组织和封装代码的机制。它允许将一组相关的标识符(如变量、函数、类等)封装在一个逻辑单元中,目的是对标识符的名称进行本地化,以避免命名冲突或名字污染。命名空间可以被定义在全局作用域或其他命名空间内。

1.1 命名空间的定义

语法:

namespace 名称 {
    // 命名空间内的代码块
    // 变量、函数、类的声明和定义等
}
  1. 命名空间中可以定义变量/函数/类型

    namespace Namespace {
        // 变量
        int rand = 10;
    
        //函数
        int Add(int left, int right) {
    	    return left + right;
        }
    
        //类型
        struct Node {
    	       struct Node* next;
    	       int val;
        };
    }
    
  2. 命名空间可以嵌套

    // 外层命名空间
    namespace N1{
    	int a;
    	int Add(int left, int right){
    		return left + right;
    	}
    	
    	// 内层命名空间
    	namespace N2{
    		int c;
    		int Sub(int left, int right){
    			return left - right;
    		}
    	}
    }
    
  3. C++ 允许命名空间的逐渐定义,而多个定义会在编译时进行合并,确保同一命名空间内的内容是唯一的。
    在这个例子中,num3 命名空间的两个部分分别定义在不同的文件中,但它们最终会在编译时合并成为一个包含两个成员的命名空间。

    // 文件1.cpp
    namespace num3 {
        int rand = 3;
    }
    
    // 文件2.cpp
    namespace num3 {
        int y = 4;
    }
    

1.2 命名空间的使用

以下是一些常见的命名空间的使用场景和实践:

  1. 避免全局命名冲突: 命名空间允许将相关的标识符封装在一个独立的逻辑单元中,从而避免与其他代码中的相同名称的标识符发生冲突。这对于大型项目或多人协作的代码库非常重要。

    // 定义命名空间
    namespace MyNamespace {
        int myVariable;
        void myFunction();
        class MyClass { /* ... */ }
    }
    
  2. 组织和模块化代码: 命名空间使得代码更加模块化和易于组织。通过将相关的功能放置在同一个命名空间中,代码结构更加清晰,对于代码的理解和维护更加方便。

    // 在项目中的不同文件中使用同一个命名空间
    // File1.cpp
    namespace Math {
        int add(int a, int b);
    }
    
    // File2.cpp
    namespace Math {
        int subtract(int a, int b);
    }
    
  3. 防止全局污染: 将标识符限定在命名空间中,避免了全局命名空间的污染。这样有助于控制和隔离代码的影响范围。

    // 不使用命名空间的情况
    int globalVariable;
    
    // 使用命名空间
    namespace MyNamespace {
        int myVariable;
    }
    
  4. 版本控制: 在不同的版本中,可以使用命名空间来隔离和管理不同版本的功能或接口,以确保向后兼容性或易于升级。

    // Version 1
    namespace MyApp_v1 {
        void someFunction();
    }
    
    // Version 2
    namespace MyApp_v2 {
        void someFunction();
        void newFunction();
    }
    
  5. 解决命名冲突: 当使用第三方库或合作开发时,可能会遇到不同部分使用相同名称的情况。使用命名空间可以帮助解决这些命名冲突。

    // 第三方库的命名空间
    namespace ExternalLibrary {
        void commonFunction();
    }
    
    // 项目的命名空间
    namespace MyProject {
        void commonFunction();
        void myFunction();
    }
    

1.3 命名空间的访问

命名空间的成员可以通过作用域解析运算符 :: 进行访问。通过 :: 运算符,你可以指定要访问的命名空间的名称,从而使用其中的变量、函数或类等成员。

以下是一些命名空间访问的示例:

通过 MyNamespace::,我们可以访问命名空间 MyNamespace 中的变量、函数和类。这样的方式可以有效地避免全局命名冲突,同时使得代码更具可读性。

// 定义命名空间
namespace MyNamespace {
    int myVariable = 42;

    void myFunction() {
        // 函数定义
    }

    class MyClass {
        // 类定义
    }
}

int main() {
    // 访问命名空间中的变量
    int value = MyNamespace::myVariable;

    // 访问命名空间中的函数
    MyNamespace::myFunction();

    // 访问命名空间中的类
    MyNamespace::MyClass myObject;

    return 0;
}

通过 NS1:: 和 NS2:: 分别指定了要访问的命名空间,从而区分了两个同名的变量。

namespace NS1 {
    int x;
}

namespace NS2 {
    int x;
}

int main() {
    // 访问不同命名空间中的同名变量
    int value1 = NS1::x;
    int value2 = NS2::x;

    return 0;
}

当你有一个嵌套的命名空间结构时。在这个示例中,OuterNamespace 是外层命名空间,InnerNamespace 是内层命名空间。通过作用域解析运算符 ::,我们可以访问这两个命名空间中的变量。value1 获取了外层命名空间的变量值,而 value2 获取了内层命名空间的变量值。

// 外层命名空间
namespace OuterNamespace {
    int outerVariable = 42;

    // 内层命名空间
    namespace InnerNamespace {
        int innerVariable = 10;
    }
}

int main() {
    // 访问外层命名空间的变量
    int value1 = OuterNamespace::outerVariable;

    // 访问内层命名空间的变量
    int value2 = OuterNamespace::InnerNamespace::innerVariable;

    return 0;
}

二、C++输入&输出

C++ 中的输入和输出操作符是 <<(输出操作符)和 >>(输入操作符)。这些操作符用于在控制台或文件中进行输入和输出操作。

std 是C++标准库(Standard Library)的命名空间,coutcinendl 是C++标准库中命名空间std的对象,它们属于输入输出流相关的头文件 <iostream> 中的一部分。

输出操作符 <<

在C++中,<< 是输出流操作符,用于将右侧的数据插入到左侧的输出流中(通常是标准输出流,即屏幕)。std::cout 是标准输出流对象,<< 将数据输出到流中。多个 << 操作符可以串联使用,将多个数据输出到同一个流中。

#include <iostream>

int main() {
    int number = 42;
    std::cout << "The value of number is: " << number << std::endl;
    return 0;
}

输入操作符 >>

在C++中,>> 是输入流操作符,用于从流中读取数据。std::cin 是标准输入流对象,>> 从流中读取数据并存储在 number 变量中。

#include <iostream>

int main() {
    int number;
    std::cout << "Enter a number: ";
    std::cin >> number;
    std::cout << "You entered: " << number << std::endl;
    return 0;
}

换行符和刷新输出缓冲区

std::endl 是C++标准库中的一个操作符,用于表示换行符和刷新输出缓冲区。它实际上是一个函数模板,定义在头文件 中,并属于 std 命名空间。

使用 std::endl 可以在输出流中插入一个换行符,并确保输出缓冲区被刷新。刷新输出缓冲区是为了确保立即将输出内容显示在屏幕上,而不是等待缓冲区被填满或遇到显式的刷新操作。等效地,也可以使用 '\n' 来表示换行符。

#include <iostream>

int main() {
    int number = 42;

    // 使用 std::endl 插入换行符并刷新输出缓冲区
    std::cout << "The value of number is: " << number << std::endl;

    return 0;
}

关键字 using

使用 using 关键字可以展开命名空间中的标识符,使其在代码中更直接可用,而不需要显式加上命名空间的前缀。

以下是使用 using 展开命名空间的示例:

#include <iostream>

// 使用 using 展开命名空间
using namespace std;

int main() {
    // std::cout 可以直接使用为 cout
    cout << "Hello, World!" << endl;
    
    return 0;
}

需要注意的是,虽然 using namespace std; 提供了方便,但在大型项目中或与其他库集成时,可能会引入潜在的命名冲突。为了避免这些问题,一种更安全的方式是只使用需要的特定标识符,而不是整个命名空间。例如:

#include <iostream>

// 使用 using 展开需要的标识符
using std::cout;
using std::endl;

int main() {
    // 直接使用展开后的标识符
    cout << "Hello, World!" << endl;
    
    return 0;
}

三、缺省参数

3.1 概念

缺省参数(default parameters)允许在函数声明中为一个或多个参数指定默认值。这意味着在调用函数时,如果没有提供相应的参数值,将使用该参数的默认值

void Func(int a = 0){
	cout << a << endl;
}

int main(){
	Func();     // 没有传参时,使用参数的默认值
	Func(10);   // 传参时,使用指定的实参
	return 0;
}

3.2 缺省参数分类

函数的参数可以全部使用缺省参数,也可以部分使用缺省参数,实现全缺省参数和半缺省参数的效果。

全缺省参数:
printInfo 函数的所有参数都使用了缺省参数,可以在调用时不提供任何参数值,或者提供部分或全部参数值。

#include <iostream>

// 函数声明时全部使用缺省参数
void printInfo(int a = 1, int b = 2, int c = 3);

int main() {
    // 调用函数时不提供任何参数值,使用了所有参数的默认值
    printInfo();

    // 提供部分参数值
    printInfo(4);

    // 提供所有参数值,不使用默认值
    printInfo(7, 8, 9);

    return 0;
}

// 函数定义时也使用全部缺省参数
void printInfo(int a, int b, int c) {
    std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}

半缺省参数:
半缺省参数必须从右往左依次来给出,不能间隔着

#include <iostream>

// 函数声明时部分使用缺省参数
void printInfo(int a, int b = 2, int c = 3);

int main() {
    // 调用函数时提供所有参数值,不使用默认值
    printInfo(7, 8, 9);

    // 提供部分参数值
    printInfo(4);

    // 调用函数时不提供任何参数值,使用了第一个参数的默认值
    printInfo();

    return 0;
}

// 函数定义时也使用部分缺省参数
void printInfo(int a, int b, int c) {
    std::cout << "a: " << a << ", b: " << b << ", c: " << c << std::endl;
}

需要注意的是, 缺省参数应避免函数声明和定义中同时出现,当缺省参数在函数声明和定义中同时出现时,编译器会面临二义性的问题

如果缺省参数在函数声明和定义中同时出现:

  • 编译阶段:

    • 编译器首先会处理声明,其中包含缺省参数的值。这个信息在汇编代码中被保存。
    • 接着,编译器会处理定义,其中也包含缺省参数的值。
  • 链接阶段:

    • 链接器需要解析符号,即函数名和参数列表。但现在存在两个相同的函数符号,一个来自声明,一个来自定义。
    • 缺省参数的值在编译阶段已经确定,但由于声明和定义提供了相同的信息,链接器无法准确地选择应该使用哪个缺省参数的值。

因此,在声明和定义中同时出现缺省参数会导致链接阶段的二义性,编译器无法确定应该使用哪个值,从而引发错误。为了避免这种情况,建议在声明中指定缺省参数的值,而在定义中不再提供。这样,在链接阶段,编译器就能够使用声明中的默认值。


四、函数重载

概念

函数重载是指在同一个作用域内定义多个同名函数,但它们的参数列表 (包括参数的类型、顺序或数量)不同

#include <iostream>

using namespace std;

// 重载函数,按类型
void print(int x) {
    cout << "Integer: " << x << endl;
}

void print(double x) {
    cout << "Double: " << x << endl;
}

// 重载函数,参数个数不同
void display(int x) {
    cout << "Display Integer: " << x << endl;
}

void display(int x, double y) {
    cout << "Display Integer and Double: " << x << ", " << y << endl;
}

// 重载函数,参数顺序不同
void show(double x, int y) {
    std::cout << "Show Double and Integer: " << x << ", " << y << endl;
}

void show(int x, double y) {
    cout << "Show Integer and Double: " << x << ", " << y << endl;
}

int main() {
    // 函数按类型重载
    print(42);       // 调用第一个 print 函数
    print(3.14);     // 调用第二个 print 函数

    // 函数参数个数不同重载
    display(10);                   // 调用第一个 display 函数
    display(20, 3.5);              // 调用第二个 display 函数

    // 函数参数顺序不同重载
    show(2.5, 15);                 // 调用第一个 show 函数
    show(7, 4.2);                  // 调用第二个 show 函数

    return 0;
}

函数重载的原理

C++中使用名称修饰来实现函数重载。而在C语言中,并不使用名称修饰的方式,函数名是直接暴露的,因此C语言不支持函数重载

函数重载的编译阶段和链接阶段:

  1. 编译阶段:

    • 函数定义: 在源代码中,定义了多个同名但参数列表不同的函数,即进行函数重载。例如:

      void print(int x);
      void print(double x);
      
    • 名称修饰: 编译器在编译阶段根据函数的名称和参数列表生成唯一的名称修饰后的标识符。这个过程被称为名称修饰或符号修饰。

      • 例如,生成的标识符可能为 _Z5printi_Z5printd
    • 生成目标文件: 编译器将源代码编译成目标文件(通常是 .o 文件),其中包含了函数的名称修饰后的标识符。

  2. 链接阶段:

    • 符号表生成: 在链接阶段,链接器将汇总所有目标文件中的符号,创建一个符号表。符号表记录了函数和变量名与其对应的地址或标识符。

      • 符号表可能包含了 _Z5printi_Z5printd 这样的名称修饰后的标识符。
    • 解析函数调用: 当程序中有函数调用时,链接器查找符号表,尝试解析函数名。

      • 如果有一个唯一匹配的标识符,链接器确定正确的函数地址或标识符。
    • 写入可执行文件: 链接器将正确的函数地址或标识符写入最终的可执行文件中,确保在运行时能够正确调用相应的函数。

  3. 运行时:

    • 函数调用: 当程序运行时,根据函数调用,执行相应的函数。函数的具体实现取决于编译时和链接时确定的地址或标识符。

函数重载的过程涉及编译阶段和链接阶段:编译阶段中,编译器根据函数的名称和参数列表生成唯一的名称修饰后的标识符,汇总所有标识符并创建一个符号表;链接阶段中,链接器通过符号表解析函数调用,将正确的函数地址或标识符写入最终的可执行文件,确保在运行时能够正确调用相应的函数。


在这里插入图片描述
如果你喜欢这篇文章,点赞👍+评论+关注⭐️哦!
欢迎大家提出疑问,以及不同的见解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/340434.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何在CentOS8使用宝塔面板本地部署Typecho个人网站并实现公网访问【内网穿透】

文章目录 前言1. 安装环境2. 下载Typecho3. 创建站点4. 访问Typecho5. 安装cpolar6. 远程访问Typecho7. 固定远程访问地址8. 配置typecho 前言 Typecho是由type和echo两个词合成的&#xff0c;来自于开发团队的头脑风暴。Typecho基于PHP5开发&#xff0c;支持多种数据库&#…

vmware 安装Rocky-9.3系统

安装系统截图 安装完成&#xff0c;启动 查看版本和内核 开启远程登陆授权 1、编辑配置文件 #提升权限&#xff0c;输入su,并输入密码 su #编辑ssh文件开启root远程登陆 vi /etc/ssh/sshd_config找到以下内容&#xff1a;#PermitRootLogin prohibit-password 添加&#xff1a…

C#winform上位机开发学习笔记5-串口助手的定时发送功能添加

1.功能描述 选择自动发送功能后&#xff0c;按照设定的发送时间发送发送框中的信息数据&#xff0c;设定时间可以手动输入&#xff0c;当手动输入信息无效&#xff08;非数字&#xff09;时&#xff0c;系统弹出错误提示&#xff0c;并将其设置为默认定时时间。 2.代码部分 步…

【MySQL进阶】视图_存储过程_存储函数_触发器

文章目录 视图基本介绍视图操作视图创建视图查询视图修改视图删除 存储过程基本介绍基本操作存储语法变量IF语句参数传递CASEWHILEREPEATLOOP游标 存储函数触发器基本介绍基本操作 总结 视图 基本介绍 视图概念&#xff1a;视图是一种虚拟存在的数据表&#xff0c;这个虚拟的表…

【Linux对磁盘进行清理、重建、配置文件系统和挂载,进行系统存储管理调整存储结构】

Linux 调整存储结构 前言一、查看磁盘和分区列表二、创建 ext4 文件系统&#xff0c;即&#xff1a;格式化分区为ext4文件系统。1.使用命令 mkfs.ext4 (make file system)报错如下&#xff1a;解决办法1&#xff1a;&#xff08;经测试&#xff0c;不采用&#xff09;X解决办法…

Docker-Jenkins编译android-app的两种方案

Docker-Jenkins编译android-app的两种方案 android开发使用jenkins编译&#xff0c;自动集成修改点/自动命名/自动备份&#xff0c;将修改的apk发布到测试服务器发布网盘&#xff0c;而不需要用通讯工具传来传去。 jenkins用在互联网开发编译比较常见&#xff0c;如果android开…

电力电子技术

文章目录 5 直流直流变流电路5.0 简介5.1 基本斩波电路5.1.1 降压斩波电路 Buck Chopper5.1.1.1 小纹波近似 5.1.2升压斩波电路 11 DC-DC 变换器数字控制11.1 基于单片机控制11.2 基于 DSP 控制11.3 基于 FPGA 控制 12 多相交错并联拓扑结构12.1 多相交错并联12.1 多相交错并联…

CS8370错误,这是由于使用了C# 7.3中不支持的功能

目录 背景: 第一种方法: 第二种办法: 背景: 在敲代码的时候&#xff0c;程序提示报错消息提示:CS8370错误&#xff0c;那么这是什么原因导致的&#xff0c;这是由于使用了C# 7.3中不支持的功能&#xff0c;不支持该功能&#xff0c;那就是版本太低我们就需要升级更高的版本&…

韩国访问学者如何申请?

作为访问学者&#xff0c;前往韩国学术机构进行研究是一项令人期待的经历。首先&#xff0c;申请者需要查找目标学术机构的官方网站&#xff0c;下面知识人网小编带大家了解其访问学者计划的具体要求和申请流程。 通常&#xff0c;申请程序包括填写在线申请表格&#xff0c;提交…

《WebKit 技术内幕》学习之八(3):硬件加速机制

3 其他硬件加速模块 3.1 2D图形的硬件加速机制 其实网页中有很多绘图操作是针对2D图形的&#xff0c;这些操作包括通常的网页绘制&#xff0c;例如绘制边框、文字、图片、填充等&#xff0c;它们都是典型的2D绘图操作。在HTML5中&#xff0c;规范又引入了2D绘图的画布功能&a…

枚举问题刷题

考研机试题目中的很多问题往往能通过暴力方法来求解&#xff0c;这些题目并不需要进行过多的思考&#xff0c;而只需枚举所有可能的情况&#xff0c;或者模拟题目中提出的规则&#xff0c;便可以得到解答。虽然说这种方法看上并不高明&#xff0c;但对于一些简单的题目来说却是…

力扣日记1.21-【回溯算法篇】77. 组合

力扣日记&#xff1a;【回溯算法篇】77. 组合 日期&#xff1a;2023.1.21 参考&#xff1a;代码随想录、力扣 终于结束二叉树了&#xff01;听说回溯篇也是个大头&#xff0c;不知道这一篇得持续多久了…… 77. 组合 题目描述 难度&#xff1a;中等 给定两个整数 n 和 k&#…

最优传输学习及问题总结

文章目录 参考内容lam0.1lam3lam10lam50lam100lam300画图线性规划matlabpython代码 欢迎关注我们组的微信公众号&#xff0c;更多好文章在等你呦&#xff01; 微信公众号名&#xff1a;碳硅数据 公众号二维码&#xff1a; 参考内容 https://blog.csdn.net/qq_41129489/artic…

Ubuntu下安装Gazebo仿真器

Ubuntu下安装Gazebo仿真器 Gazebo仿真平台通常需要配合ROS使用&#xff0c;因此需要先安装ROS。可以参考ROS安装教程 首先安装一些必要的工具 sudo apt-get update sudo apt-get install lsb-release wget gnupg修改源 sudo wget https://packages.osrfoundation.org/gazebo…

【教程】npm的时候ssh报错ssh://git@github.com/frozeman/bignumber.js-nolookahead.git

问题&#xff1a; fiscoubuntu:~/fisco/benchmarks$ npm install install web30.20.7 npm ERR! code 128 npm ERR! An unknown git error occurred npm ERR! command git --no-replace-objects ls-remote ssh://gitgithub.com/frozeman/bignumber.js-nolookahead.git npm ERR! …

UE5 Windows打包时报错“SDK Not Found”解决方案

在Unreal Engine 5.0.3 Windows平台下打包时报错&#xff1a;“Windows的SDK未正常安装&#xff0c;而其是生成数据的必需项。请检查主工具栏中“启动“菜单SDK部分来更新SDK。” 解决方案&#xff1a; 1、打开 Visual Studio Installer&#xff0c;点击“修改”按钮&#xf…

【技术分享】远程透传网关-单网口快速实现西门子S7-1200/1500 PLC程序远程上下载

准备工作 一台可联网操作的电脑一台单网口的远程透传网关及博达远程透传配置工具网线一条&#xff0c;用于实现网络连接和连接PLC一台西门子S7-1200/1500 PLC及其编程软件一张4G卡或WIFI天线实现通讯(使用4G联网则插入4G SIM卡&#xff0c;WIFI联网则将WIFI天线插入USB口&…

jieba.net使用NuGet管理器安装后初始化TfidfExtractor对象时报错

在引用安装jieba.net后,引用的Resources下只有如图几个文件 导致初始化TfidfExtractor时报错,报找不到 Could not find file E:\\TZKJNet\\robotindustry\\modules\\Tzkj.Superhard.SupplyDemand\\src\\Tzkj.Superhard.SupplyDemand.HttpApi.Host\\bin\\Debug\\net7.0\\Reso…

SpringSecurity(11)——核心组件和认证流程

获取用户信息 // 获取安全上下文对象&#xff0c;就是那个保存在 ThreadLocal 里面的安全上下文对象 // 总是不为null(如果不存在&#xff0c;则创建一个authentication属性为null的empty安全上下文对象) SecurityContext securityContext SecurityContextHolder.getContext(…

JS进阶-作用域、垃圾回收机制、闭包、变量提升(一)

• 作用域 作用域&#xff08;scope&#xff09;规定了变量能够被访问的“范围”&#xff0c;离开了这个“范围”变量便不能被访问 作用域分为&#xff1a; 局部作用域 全局作用域 • 局部作用域 局部作用域分为函数作用域和块作用域。 1. 函数作用域&#xff1a; 在函数内…