【C++】C++ 引用详解 ① ( 变量的本质 - 引入 “ 引用 “ 概念 | 引用语法简介 | 引用做函数参数 | 复杂类型引用做函数参数 )

news2024/11/23 3:20:33

文章目录

  • 一、变量的本质 - 引入 " 引用 " 概念
    • 1、变量的本质 - 内存别名
    • 2、引入 " 引用 " 概念 - 已定义变量的内存别名
    • 3、" 引用 " 的优点
  • 二、引用语法简介
    • 1、语法说明
    • 2、代码示例 - 引用的定义和使用
  • 三、引用做函数参数
    • 1、普通引用必须初始化 - 函数参数除外
    • 2、代码示例 - 使用普通变量作为参数 ( 无法实现变量交换 )
    • 3、代码示例 - 使用指针变量作为参数 ( C 语言中实现变量交换的方法 )
    • 4、代码示例 - 使用引用作为参数 ( C++ 语言中实现变量交换的方法 )
    • 5、代码示例 - 完整代码示例
  • 四、复杂类型引用做函数参数
    • 1、复杂类型参数的三种传递方式
      • I 、传递结构体对象本身
      • II 、传递结构体指针
      • III 、传递结构体引用
    • 2、代码示例 - 使用三种传递方式传递参数





一、变量的本质 - 引入 " 引用 " 概念



" 引用 " 语法 是 C++ 语言中 特有的 , 在 C 语言中是没有 引用 这个概念的 ;


1、变量的本质 - 内存别名


分析 引用 之前 , 先回顾下 变量 :

在 【C 语言】变量本质 ( 变量概念 | 变量本质 - 内存空间别名 | 变量存储位置 - 代码区 | 变量三要素 ) 博客中 , 介绍了变量的本质 :

变量 的本质是 内存空间 的 " 别名 " , 简称 " 内存别名 " , 相当于 " 门牌号 " ;

C 语言 / C++ 语言 的 程序 , 通过 变量 来申请 内存空间 , 并为该 内存空间 命名 , 名称就是变量名 ;

下面的代码中 , 定义变量 a , 就是在 栈内存 中申请了 4 字节内存 , 这 4 字节连续内存的别名是 a , 为该变量赋值 10 , 就是将 10 存储到 4 字节内存中 ;

int a = 10;

通过 " 变量名称 " 可以使用 变量名 代表的 连续内存空间 , 之后使用变量 a 进行计算 , 就是 使用 变量 a 表示的 4 字节内存中的数据进行计算 ;


2、引入 " 引用 " 概念 - 已定义变量的内存别名


下面讨论下 , 上述 变量 a 是 4 字节连续内存空间的别名 , 那么 这段 4 字节的内存空间 只能有一个内存别名吗 ? 还是可以有多个内存别名 ?

答案是可以的 , 如果想要为 上述 4 字节内存空间再次 赋予 一个 " 内存别名 " , 就需要使用 " 引用 " 了 ;


" 引用 " 就是 已定义 变量 的 内存别名 ;

  • 第一次为 一块内存 赋予 别名 , 是 定义变量 的时候 ;
  • 第二次再为 该内存 赋予 别名 , 就是 获取该变量的 " 引用 " ;

3、" 引用 " 的优点


C++ 语言中的 引用 是特殊的变量 , 通过引用可以访问已经存在的变量 ;


使用 " 引用 " 的优点 :

  • 提高访问效率 : 向 函数 传递参数时 , 使用引用可以减少消耗 , 类似于传入指针 , 如果传入一个较大的数组 , 需要拷贝整个数组作为变量副本 , 拷贝会消耗很多性能 ;
  • 提高代码可读性 : 引用使用时 , 类似于 一级指针 , 使用引用期间 , 不需要 使用 取地址符 & 和 指针符号 * , 提高了代码可读性 和 可维护性 ;
  • 函数返回值 : 函数引用参数 可以作为 返回值使用 ;




二、引用语法简介




1、语法说明


" 引用 " 语法如下 :

类型& 引用名称 = 变量;

& 符号建议紧贴类型写 , 与 引用名称 使用空格隔开 ;

( 指针符号 * 建议也是紧贴 指针类型 , 与指针名称使用空格隔开 , 如 : int* p = NULL; )

引用 定义后 , 可以当做变量使用 ;

通过引用 , 可以操作变量 , 访问 , 修改 引用 , 变量也会进行相应修改 ;


使用引用作为函数参数时 ,

  • 传入的实参不需要使用取地址符获取 , 直接将变量传入函数即可 ;
  • 在函数中 访问引用 时 , 不需要使用指针 , 直接使用引用访问传入的变量 ;

代码示例 :

	// 定义变量 a , 变量本质是内存别名
	int a = 10;

	// 定义引用 b , 是变量 a 的别名
	int& b = a;

	// 通过引用修改变量的值
	b = 100;

引用是 C++ 的概念 , 在 C 语言中不能使用引用 ;

上述代码在 C 语言中实现 是完全不同的 , 下面是 上述代码在 C 语言中的实现 :

	// 定义变量 a , 变量本质是内存别名
	int a = 10;

	// 获取 变量 a 的地址 , 赋值给 指针常量 b 
	// 指针常量 是 常量 - 指针本身不能修改 , 常量指针 是 指针 - 指向常量的指针 
	// 左数右指 , const 在 指针 * 的右边 , 指针 是常量 , 指针的指向不能更改
	int* const b = &a;

	// 通过 指针常量 修改 指针指向的内存空间的值
	// 指针指向不能修改 , 指向的内存中的内容可以修改
	*b = 100;

在上述代码中 ,

  • 首先 , 获取 变量 a 的地址 , 赋值给 指针常量 b ;
    • 指针常量 是 常量 - 指针本身不能修改 ;
    • 常量指针 是 指针 - 指向常量的指针 ;
    • 左数右指 , const 在 指针 * 的右边 , 指针 是常量 , 指针的指向不能更改 ;
  • 然后 , 通过 指针常量 修改 指针指向的内存空间的值 ;
    • 指针指向的地址不能修改 ;
    • 指针指向的内存中的内容可以修改 ;

2、代码示例 - 引用的定义和使用


下面的代码中 , 引用 b 是 变量 a 的别名 , 通过 引用 b 可以访问 变量 a 的内存空间 ;

代码中同时打印 引用 b 和 变量 a , 都可以打印出 变量值 10 ;

修改 引用 b 的值 , 变量 a 的值也会被修改 ;


代码示例 :

// 包含 C++ 头文件
#include "iostream"

// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;

// 导入 C 头文件
#include <stdio.h>

int main()
{
	// 定义变量 a , 变量本质是内存别名
	int a = 10;

	// 定义引用 b , 是变量 a 的别名
	int& b = a;

	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);

	// 通过引用修改变量值
	b = 100;

	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);


	// 控制台暂停 , 按任意键继续向后执行
	//system("pause");
    return 0;
}

执行结果 :

a = 10, b = 10
a = 100, b = 100

在这里插入图片描述





三、引用做函数参数




1、普通引用必须初始化 - 函数参数除外


普通的引用 , 必须要依附于某个变量 , 在定义 " 引用 " 时 , 必须进行初始化 , 否则就会报如下错误 :

引用 变量 x 需要初始值设定项

在这里插入图片描述


这里有一种特殊情况 , 在声明时可以不进行初始化 ,

" 引用 " 做 函数 形参 时 , 可以不进行初始化 ;


使用 引用 作为 函数参数 , 与 一级指针 效果相同 , 并且用起来比较简单 , 不需要操作指针 ;

引用 比较符合 Java / C# 语言风格 , 不需要操作繁琐的指针 ;


定义两个变量 :

	// 定义变量 a , b ,  变量本质是内存别名
	int a = 10, b = 20;

写一个函数 , 交换这两个变量的值 ;


2、代码示例 - 使用普通变量作为参数 ( 无法实现变量交换 )


下面的代码中 , 定义的交换函数 , 传入的形参是普通变量 ;

参数是普通变量 , 实参就是变量的副本 , 变量的作用域仅限于函数内 , 无法传递到函数外部 , 外部的变量无法被改变 ;


代码示例 :

// 包含 C++ 头文件
#include "iostream"

// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;

// 导入 C 头文件
#include <stdio.h>

// 交换 a 和 b 的值
// 该函数无法实现交换 , 因为传入的实参只是副本
// 并不能真实的改变传入的值
void swap(int a, int b) 
{
	int c = 0;
	c = a;
	a = b;
	b = c;
}

int main()
{
	// 定义变量 a , b ,  变量本质是内存别名
	int a = 10, b = 20;

	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);

	// 传入变量副本 : 交换 a 和 b 的值 , 交换失败
	swap(a, b);
	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
    return 0;
}

执行结果 :

a = 10, b = 20
a = 10, b = 20

在这里插入图片描述


3、代码示例 - 使用指针变量作为参数 ( C 语言中实现变量交换的方法 )


在下面的代码中 , 使用 C 语言的方式实现了 变量交换函数 ;

函数参数接收 指针变量 作为 参数 , 传入的实参是变量的地址 ;

在函数内部 , 访问变量需要通过 指针 * 符号进行 ;

这样可以实现 外部变量 的数值交换 , 但是 使用 指针 * 进行操作 , 代码十分复杂繁琐 , 不易理解 ;


代码示例 :

// 包含 C++ 头文件
#include "iostream"

// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;

// 导入 C 头文件
#include <stdio.h>

// 交换 a 和 b 的值
// C 语言中可以使用该方法
void swap(int* a, int* b)
{
	int c = 0;
	c = *a;
	*a = *b;
	*b = c;
}

int main()
{
	// 定义变量 a , b ,  变量本质是内存别名
	int a = 10, b = 20;

	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);

	// 传入指针地址 : 交换 a 和 b 的值 , 交换成功
	swap(&a, &b);
	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
    return 0;
}

执行结果 :

a = 10, b = 20
a = 20, b = 10

在这里插入图片描述


4、代码示例 - 使用引用作为参数 ( C++ 语言中实现变量交换的方法 )


在下面的代码中 , 使用引用作为函数参数 , 也实现了变量交换 ;

C++ 中的引用使用非常简单 , 没有使用指针进行操作 ;

在使用引用时 , 可以看到 引用的效果 , 实际上等同于一级指针 ;

使用引用作为函数参数时 , 传入的实参不需要使用取地址符获取 , 直接将变量传入函数即可 , 在函数中获取引用的值时 , 不需要使用指针 , 直接使用引用访问传入的变量 ;


代码示例 :

// 包含 C++ 头文件
#include "iostream"

// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;

// 导入 C 头文件
#include <stdio.h>

// 交换 a 和 b 的值
// C++ 中推荐的方法
// 使用引用作为函数参数 
void swap(int& a, int& b)
{
	int c = 0;
	c = a;
	a = b;
	b = c;
}

int main()
{
	// 定义变量 a , b ,  变量本质是内存别名
	int a = 10, b = 20;

	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);

	// 传入引用本 : 交换 a 和 b 的值 , 交换成功
	swap(a, b);
	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
    return 0;
}

执行结果 :

a = 10, b = 20
a = 20, b = 10

在这里插入图片描述


5、代码示例 - 完整代码示例


完整代码示例 :

// 包含 C++ 头文件
#include "iostream"

// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;

// 导入 C 头文件
#include <stdio.h>

// 交换 a 和 b 的值
// 该函数无法实现交换 , 因为传入的实参只是副本
// 并不能真实的改变传入的值
void swap1(int a, int b) 
{
	int c = 0;
	c = a;
	a = b;
	b = c;
}

// 交换 a 和 b 的值
// C 语言中可以使用该方法
void swap2(int* a, int* b)
{
	int c = 0;
	c = *a;
	*a = *b;
	*b = c;
}

// 交换 a 和 b 的值
// C++ 中推荐的方法
void swap3(int& a, int& b)
{
	int c = 0;
	c = a;
	a = b;
	b = c;
}

int main()
{
	// 定义变量 a , b ,  变量本质是内存别名
	int a = 10, b = 20;

	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);

	// 传入变量副本 : 交换 a 和 b 的值 , 交换失败
	swap1(a, b);
	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);

	// 传入指针 : 交换 a 和 b 的值 , 交换成功
	swap2(&a, &b);
	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);

	// 传入引用 : 交换 a 和 b 的值 , 交换成功
	swap3(a, b);
	// 打印 变量 a 和 引用 b 的值
	printf("a = %d, b = %d\n", a, b);


	// 控制台暂停 , 按任意键继续向后执行
	//system("pause");
    return 0;
}

执行结果 :

a = 10, b = 20
a = 10, b = 20
a = 20, b = 10
a = 10, b = 20

在这里插入图片描述





四、复杂类型引用做函数参数




1、复杂类型参数的三种传递方式


定义一个结构体类型 , 想要传递结构体对象到函数中 , 有三种方式 ;

// 定义一个结构体 
// C++ 中结构体就是类
struct Student
{
	char name[64];
	int age;
};

在栈内存中先创建该结构体对象 , 为该对象赋值 ;

	Student s;
	s.age = 18;

I 、传递结构体对象本身


第一种方式 , 直接传递结构体对象本身 ,

  • 函数传递 : 这种方式传递的是 结构体 对象的副本 , 需要拷贝对象然后将拷贝副本作为实参传递给函数 , 拷贝的过程非常消耗性能 ;
  • 参数访问 : 传入的参数在函数中正常访问 ,使用 . 访问结构体成员 ;
  • 参数修改 : 修改该参数 , 不会影响外部结构体对象的值 , 因为修改的是拷贝后的副本 ;
// 直接传入结构体类对象本身
void printStudent1(Student s)
{
	// 使用变量 , 直接使用 . 访问结构体成员
	cout << "printStudent1 开始执行 age : " << s.age << endl;
	s.age = 19;
}

II 、传递结构体指针


第二种方式 , 传递结构体 指针 ,

  • 函数传递 : 这种方式传递的是 结构体 指针 , 实际上是指针的副本 , 几乎不消耗性能 ;
  • 参数访问 : 传入的 指针 参数 在函数中 使用 -> 访问结构体成员 ;
  • 参数修改 : 通过指针 修改该参数 , 外部的结构体对象也会被修改 ;
// 传入结构体类对象指针
void printStudent2(Student* s)
{
	// 通过 问结构体指针 访问成员需要使用 -> 访问
	cout << "printStudent2 开始执行 age : " << s->age << endl;
	s->age = 20;
}

III 、传递结构体引用


第三种方式 , 传递结构体 引用 ,

  • 函数传递 : 这种方式传递的是 结构体 引用 , 引用只是变量的一个别名 , 几乎不消耗性能 ;
  • 参数访问 : 传入的 引用 参数 在函数中 使用 . 访问结构体成员 , 与变量用法一样 ;
  • 参数修改 : 通过指针 修改该参数 , 外部的结构体对象也会被修改 ;
// 传入结构体类对象指针
void printStudent2(Student* s)
{
	// 通过 问结构体指针 访问成员需要使用 -> 访问
	cout << "printStudent2 开始执行 age : " << s->age << endl;
	s->age = 20;
}

2、代码示例 - 使用三种传递方式传递参数


代码示例 :

// 包含 C++ 头文件
#include "iostream"

// 使用 std 标准命名空间
//		该命名空间中 , 定义了很多标准定义
using namespace std;

// 导入 C 头文件
#include <stdio.h>

// 定义一个结构体 
// C++ 中结构体就是类
struct Student
{
	char name[64];
	int age;
};

// 直接传入结构体类对象本身
void printStudent1(Student s)
{
	// 使用变量 , 直接使用 . 访问结构体成员
	cout << "printStudent1 开始执行 age : " << s.age << endl;
	s.age = 19;
}

// 传入结构体类对象指针
void printStudent2(Student* s)
{
	// 通过 问结构体指针 访问成员需要使用 -> 访问
	cout << "printStudent2 开始执行 age : " << s->age << endl;
	s->age = 20;
}

// 传入结构体类对象引用
void printStudent3(Student& s)
{
	// 使用 引用 跟普通变量用法相同, 不需要使用 -> 访问
	cout << "printStudent3 开始执行 age : " << s.age << endl;
	s.age = 21;
}

int main()
{
	Student s;
	s.age = 18;

	// 传入对象 消耗性能
	printStudent1(s);
	cout << "printStudent1 执行完毕 age : " << s.age << endl;

	// 传入指针 需要取地址
	printStudent2(&s);
	cout << "printStudent2 执行完毕 age : " << s.age << endl;

	// 传入引用 直接传入
	printStudent3(s);
	cout << "printStudent3 执行完毕 age : " << s.age << endl;


	// 控制台暂停 , 按任意键继续向后执行
	system("pause");
    return 0;
}

执行结果 :

printStudent1 开始执行 age : 18
printStudent1 执行完毕 age : 18
printStudent2 开始执行 age : 18
printStudent2 执行完毕 age : 20
printStudent3 开始执行 age : 20
printStudent3 执行完毕 age : 21
Press any key to continue . . .

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

minikube安装

minikube也是需要docker环境的&#xff0c;首先看一下docker 下载docker.repo源到本地 通过repo里面查找最新的docker 开始安装docker 修改docker 下载加速地址&#xff0c; systemctl deamon-reload 下载minikube minikube start | minikube curl -LO https://storage.goog…

Mybatis(二)映射文件配置与动态SQL

Mybatis&#xff08;二&#xff09;映射文件配置 1.Mybatis映射文件配置 1.入参 1.1.parameterType(了解) CRUD标签都有一个属性parameterType&#xff0c;底层的statement通过它指定接收的参数类型。入参数据有以下几种类型&#xff1a;HashMap&#xff0c;基本数据类型&a…

会计资料基础

会计资料 1.会计要素及确认与计量 1.1 会计基础 1.2 六项会计要素小结 1.3 利润的确认条件 1.3.1 利润的定义和确认条件 1.4 会计要素及确认条件 2.六项会计要素 2.1 资产的特征及其确认条件 这部分资产可以给企业带来经济收益&#xff0c;但是如果不能带来经济利益&#xff…

提升团队合作效率:企业网盘的文件管理和协作利用方法

随着信息技术的飞速发展&#xff0c;企业越来越依赖于网络和云服务来提高工作效率。在这样的背景下&#xff0c;企业网盘作为一种重要的在线存储和协作工具&#xff0c;正在被越来越多的企业所采用。本文将探讨如何利用企业网盘进行文件管理和协作&#xff0c;从而构建高效的团…

Windows快捷键常用介绍,提高工作(摸鱼)效率

一&#xff1a;背景 本文主要是讲解Windows电脑常见的快捷键&#xff0c;包括ctrl快捷键&#xff0c;win快捷键&#xff0c;不管是开发人员还是普通办公人员&#xff0c;都是很方便的。我们平时没事操作都是用鼠标去选择对应的功能&#xff0c;或者在我的电脑--控制面板寻找&a…

把matlab的m文件打包成单独的可执行文件

安装Matlab Compiler Adds-on在app里找到Application Compiler 选择要打包的文件matlab单独的运行程序的话需要把依赖的库做成runtime. 这里有两个选项. 上面那个是需要对方在联网的情况下安装, 安装包较小.下面那个是直接把runtime打包成安装程序, 大概由你的程序依赖的库的多…

谷粒商城环境搭建一:Docker容器部署

Docker容器部署 VMware虚拟机安装 参考&#xff1a;VMware虚拟机安装Linux教程 Docker安装 Linux安装Docker # 1.更新apt包索引 sudo apt-get update# 2.安装以下包以使apt可以通过HTTPS使用存储库&#xff08;repository&#xff09; sudo apt-get install -y apt-transpor…

滑动窗口介绍

1.基本概念 利用单调性&#xff0c;使用同向双指针&#xff0c;两个指针之间形成一个窗口 子串与子数组都是连续的一段子序列时不连续的 2.为什么可以用滑动窗口&#xff1f; 暴力解决时发现两个指针不需要回退&#xff08;没必要回退&#xff0c;一定不会符合结果&#xf…

什么是有效的预测性维护 ?

在现代制造业的背景下&#xff0c;设备的可靠性和生产效率成为了企业追求的关键目标。而预测性维护&#xff08;Predictive Maintenance&#xff0c;简称PdM&#xff09;作为一种先进的维护策略&#xff0c;逐渐成为了实现这些目标的重要工具。然而&#xff0c;什么是有效的预测…

2023年国赛数学建模思路 - 案例:随机森林

文章目录 1 什么是随机森林&#xff1f;2 随机深林构造流程3 随机森林的优缺点3.1 优点3.2 缺点 4 随机深林算法实现 建模资料 ## 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 什么是随机森林&#xff…

AP9235 dc-dc升压恒流电源驱动IC 2.8-30V 输出电流2A SOT23-6

概述 AP9235B 系列是一款固定振荡频率、恒流输出的升压型DC/DC转换器&#xff0c;非常适合于移动电话、PDA、数码相机等电子产品的背光驱动。输出电压可达30V &#xff0c;3.2V输入电压可以驱动六个串联LED&#xff0c; 2.5V输入电压可以驱动两路并联LED&#xff08;每路串联…

你不知道的 malloc 内幕

你不知道的 malloc 内幕 1. 引言&#xff1a;一个例子例1例2 2. 基础概念2.1 内存管理发展过程2.2 虚拟存储器2.3 内存分配机制2.4 VMA2.4.1 进程的 VMA2.4.2 vma 分析 3. 实例分析3.1 malloc 到底干了啥3.2 memset 的偷天换日3.2.1 虚拟地址转物理地址3.2.2 page fault 3.3 fr…

线程池UncaughtExceptionHandler无效?可能是使用方式不对

背景 在业务处理中&#xff0c;使用了线程池来提交任务执行&#xff0c;但是今天修改了一小段代码&#xff0c;发现任务未正确执行。而且看了相关日志&#xff0c;也并未打印结果。 源码简化版如下&#xff1a; 首先&#xff0c;自定义了一个线程池 public class NamedThrea…

iMX6ULL QT环境配置 | CMake在Linux下的交叉编译环境搭建及使用

习惯了使用cmake&#xff0c;再也不想回到手写makefile的年代了。相比手写makefile&#xff0c;使用cmake则像是实现了机动化&#xff0c;管理项目工程的编译变得很简单了。况且cmake很流行&#xff0c;linux下的很多软件源码包&#xff0c;很多也都使用了cmake的方式编译。因此…

大数据课程K4——Spark的DAGRDD依赖关系

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解Spark的DAG; ⚪ 掌握Spark的RDD的依赖关系; ⚪ 了解Spark对于DAG的Stage的划分; 一、DAG概念 1. 概述 Spark会根据用户提交的计算逻辑中的RDD的转换和动作来生成RDD之间的依赖关…

Android JNI系列详解之AS创建Native C++项目

一、前提 Android Studio版本&#xff1a;Android Studio Electric Eel | 2022.1.1 Patch 1 二、创建Native C项目 1.新建项目 2.选择新建Native C项目 3.New Project 4.选择C标准库的支持版本 5.项目自带的默认生成的代码 6.buil.gradle中也自带了CMakeList的配置&#xff08;…

详细了解G1、了解G1、G1垃圾收集器详解、G1垃圾回收器简单调优

4.详细了解G1&#xff1a; 4.1.一&#xff1a;什么是垃圾回收 4.2.了解G1 4.3.G1 Yong GC 4.4.G1 Mix GC 4.5.三色标记算法 4.6.调优实践 5.G1垃圾收集器详解 5.1.G1垃圾收集器 5.2.G1的堆内存划分 5.3.G1的运行过程 5.4.三色标记 5.4.1.漏标问题 5.5.记忆集与卡表 5.6.安全点与…

开发小技巧(逐步完善)

一、验证码 1&#xff09;将 大小写字母 和 数字 存储在字符数组中 2&#xff09;用随机数的方式生成随机码 3&#xff09;采用字符串的方式存储验证码即可 import java.util.Random;public class TEST {public static void main(String[] args) {char[] chs new char[62];//…

小程序中的全局配置以及常用的配置项(window,tabBar)

全局配置文件和常用的配置项 app.json: pages:是一个数组&#xff0c;用于记录当前小程序所有页面的存放路径&#xff0c;可以通过它来创建页面 window:全局设置小程序窗口的外观(导航栏&#xff0c;背景&#xff0c;页面的主体) tabBar:设置小程序底部的 tabBar效果 style:是否…

存储IO路径:Linux下的“快递之旅”

相信大家都有过网购的经历,当我们在电商平台上浏览心仪的商品并下单时,快递小哥会负责将物品从商家手中送至我们手中。在这个过程中,快递小哥需要经过一系列的流程才能将物品准确送达。同样,在Linux系统中,当用户下发一笔读写操作时,这些数据也需要经过一系列的流程才能最…