Java基础教程 - 5 数组

更好的阅读体验:点这里 ( www.doubibiji.com
更好的阅读体验:点这里 ( www.doubibiji.com
更好的阅读体验:点这里 ( www.doubibiji.com

5 数组

前面我们保存数据的时候,是将数据保存在变量中,如果要保存2个数据,就声明2个变量。

如果要保存100个数据呢,1000个数据…呢?

所以就需要保存数据的集合来保存批量的数据,下面介绍一下数组。

数组的主要特点:

  • 有序,顺序排列;
  • 只能存储相同类型的元素;
  • 大小在创建的时候就确定了,大小不可变;

5.1 一维数组

1 初始化

同样,数组和变量一样,在使用之前也要进行声明和初始化,数组变量是引用类型的

// 数组声明
// 声明方式1
int[] numbers1;
// 声明方式2
int numbers2[];

// 对上面声明的数组进行初始化
// 初始化方式1:动态初始化
numbers1 = new int[5];										// 表示定义了长度为5的数组,此时数组中的值都为0
// 初始化方式2:静态初始化,直接初始化各个元素的值
numbers2 = new int[]{1, 2, 3, 4, 5, 6};	  // 表示定义了长度为5的数组,内容为1,2,3,4,5
// 初始化方式3:静态初始化,直接初始化各个元素的值
int[] number3 = {1, 2, 3, 4, 5};				  // 初始化列表

// 声明并初始化
String[] names = new String[5];				// 表示定义了长度为5的数组,内容为null
String[] names2 = {"Hello", "Doubi"};

定义数组就是类型加上 [][] 可以在类型后,也可以在变量名后,Java 中推荐放在类型后面。

int[] numbers1 中,[] 表示是数组,int 表示是整形的数组,里面只能放 int 类型的数据。

2 基础操作

获取长度

使用 .length 属性可以获取到数组的长度。

int [] numbers = new int[]{1, 2, 3, 4, 5};
System.out.println("数组长度:" + numbers.length);    // 输出:5

访问元素

访问数组元素是使用下标来访问的,从0开始。

注意不要越界,下标越界会报错。

public static void main(String[] args) {
    int [] numbers = new int[]{1, 2, 3, 4, 5};

    int firstNum = numbers[0];      		// 获取第一个元素
    System.out.println(firstNum);      	// 输出:1

    int lastNum = numbers[numbers.length - 1];     // 获取最后一个元素
    System.out.println(lastNum);      						 // 输出:5

    numbers[0] = 100;        						// 修改第一个元素的值
    System.out.println(numbers[0]); 		// 100
}

因为数组的长度创建后就无法更改了,所以我们无法删除和添加更多到元素到数组中,只能访问和修改数组中的元素。

例如现在创建了一个长度为20的数组,添加学生姓名,现在发现长度不够了,像扩大数组的长度,放更多的元素,这种做法你只能想想。实际上你只能重新创建一个更大的数组,将这个数组的数据复制到更大的数组中。


访问元素的时候一定要注意,不要超越数组的长度,例如:

int [] numbers = new int[]{1, 2, 3, 4, 5};	// 数组的长度为5
int num = numbers[numbers.length];      		// 报错,数组越界

长度为 5 的数组,最后一个元素的下标 index 为 4,所以不能大于4,否则会越界报错。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


3 遍历数组

遍历就是依次访问数组中的元素。

使用 for 循环遍历

int[] numbers = new int[10];

// 遍历数组并进行赋值
for (int i = 0; i < numbers.length; i++) {
    numbers[i] = i;
}

// 遍历进行输出
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);         // 依次输出0 1 2 3 4 5 6 7 8 9
}

注意编辑结束的条件是: i < numbers.length ,是用 for 循环,可以对数据进行遍历赋值和访问。


使用 for-each 循环遍历

for-each 循环也叫 增强型 for 循环,使用起来更加简洁,但是不能使用 for-each 循环进行赋值。

int[] numbers = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

for (int num : numbers) {				// num 表示每次取出的元素	
    System.out.println(num);    // 依次输出0, 1 2 3 4 5 6 7 8 9
}

for-each 循环,冒号前面是依次取出的数组中的每个元素。

4 数组元素的默认值

动态初始化方式定义的数组,例如 new int[5] ,没有设置数组中元素的值,元素是有默认值的。对于基本数据类型,byte、short、int、long、char 类型的数组,默认值为 0,float、double 类型的数组,默认值为 0.0,boolean 类型数组,默认值为 false。对于引用类型的数组,元素的默认值都是 null

举个栗子:

int [] numbers = new int[3];
System.out.println(Arrays.toString(numbers));       // [0, 0, 0]

boolean [] bools = new boolean[3];
System.out.println(Arrays.toString(bools));         // [false, false, false]

String [] strs = new String[3];
System.out.println(Arrays.toString(strs));          // [null, null, null]

Arrays.toString() 方法可以以字符串的形式打印数组中的内容。

5 内存结构

数组是引用类型的,和普通的数据类型有一些不同。

int [] numbers = new int[]{1, 2, 3, 4, 5};

对于上面的代码,在内存中的结构是这样的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

内存中会有不同的存储数据的区域,这里使用的有,栈中存放的是局部变量,也就是方法中定义的变量,现在我们定义的变量都是在方法中的,也就是 main 方法,所以 numbers 变量是存储在栈中的,但是右边的数组值是存储在堆中的,numbers 变量中存储的是一个地址值,是数组的首地址(第一个元素的起始地址,也就是1的起始地址,上面的地址值是胡诌的)。


再看一段代码:

int [] numbers = new int[]{1, 2, 3, 4, 5};
numbers = new int[]{1, 2, 3};

上面的代码,重新将一个数组赋值给 numbers,内存结构如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

numbers 被赋值为一个新的数组,那么存储的是新的数组的首地址值,numbers 与新的数组建立关系,与原来的数组断开联系了。

5.2 二维数组

一维数组看上去只是一行或一列数据:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二维数组可以存储类似一个表格的数据:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

二维数组其实是:一维数组的每一个元素也是一个数组。

也就是一个一维数组中的每个元素,存储的都是一维数组的地址,地址指向的都是第二层一维数组,如下图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

1 初始化

// 静态初始化,数组3*4
int[][] numbers1 = new int[][]{{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};

// 静态初始化,数组的长度是3,数组中的各个数组元素的长度是不同的
int[][] numbers2 = new int[][]{{1,2,3,4}, {5,6}, {7,8,9}};

//动态初始化,长度3*2
String[][] strs1 = new String[3][2];

//动态初始化,数组的长度是3,数组中的元素是空的,但是数组中的元素只能是数组类型
int[][] number3 = new int[3][];

现在看一下上面定义二维数组的内存结构:

int[][] numbers1 = new int[][]{{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};

内存结构如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先在栈中定义了一个变量 numbers1,numbers1 存储的是第一层数组的首地址,第一层中的各个元素存储的是第二层各个数组的首地址。


int[][] numbers2 = new int[][]{{1,2,3,4}, {5,6}, {7,8,9}};

内存结构如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


String[][] strs1 = new String[3][2];

内存结构如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


int[][] number3 = new int[3][];

内存结构如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在上面第一层数组的值是空的,还没有指向第二层数组,后面可以创建第二层数组,将地址赋值给第一层数组。

2 基础操作

获取长度

也是使用 .length 属性可以获取到数组的长度。

但是数组中第二层数组元素的长度需要获取到第一层数组元素再获取长度。

int[][] numbers = new int[][]{{1,2,3,4}, {5,6}, {7,8,9}};
System.out.println(numbers.length);    // 3
System.out.println(numbers[0].length); // 4
System.out.println(numbers[1].length); // 2

String[][] strs = new String[3][];
System.out.println(strs.length);    // 3
//System.out.println(strs[0].length);    // 报错,因为strs[0]为null

访问元素

访问二维数组中的元素,需要通过两个 [] 获取,第一个表示获取到的是第一层的元素,第二个才是获取到二维数组中的元素。

int[][] numbers = new int[][]{{1,2,3,4}, {5,6}, {7,8,9}};
System.out.println(numbers[0][0]);    // 1
System.out.println(numbers[1][1]);    // 6
numbers[2][1] = 1;      									  // 修改值
numbers[1] = new int[]{1,2,3,4,5,6,7,8,9};  // 修改值

String[][] strs = new String[3][];
strs[0] = new String[]{"red", "yellow"};   // 元素就是数组
System.out.println(strs[0][1]); // yellow

不是数组的长度无法更改吗,为什么可以这样操作 numbers[1] = new int[]{1,2,3,4,5,6,7,8,9}; ,这是将第一层数组指向了一个新的第二层数组而已。


3 遍历数组

使用 for 循环遍历

遍历二维数组,需要两层 for 循环。

// 创建一个3x3的二维数组
int[][] numbers = new int[3][3];

// 赋值
for (int i = 0; i < numbers.length; i++) {
    for (int j = 0; j < numbers[i].length; j++) {
        numbers[i][j] = i * 10 + j;
    }
}

// 遍历并打印数组元素
System.out.println("二维数组的内容:");
for (int i = 0; i < numbers.length; i++) {
    for (int j = 0; j < numbers[i].length; j++) {
        System.out.print(numbers[i][j] + " ");
    }
    System.out.println(); // 换行
}

上面使用 for 循环对二维数组进行了遍历赋值和打印。

注意:第一层 for 循环取的是第一层数组的长度,第二层数组取的是第二层数组的长度。

执行结果:

二维数组的内容:
0 1 2
10 11 12
20 21 22


使用 for-each 循环遍历

// 创建一个3x3的二维数组
int[][] numbers = new int[3][3];

// 赋值
for (int i = 0; i < numbers.length; i++) {
    for (int j = 0; j < numbers[i].length; j++) {
        numbers[i][j] = i * 10 + j;
    }
}

// 遍历并打印数组元素
System.out.println("二维数组的内容:");
for (int[] nums : numbers) {
    for (int i : nums) {
        System.out.print(i + " ");
    }
    System.out.println(); // 换行
}

使用 for-each 循环看上去要简洁很多,第一层 for-each 循环获取到的每个元素其实是一维数组,然后第二层 for-each 循环遍历每个一维数组。

5.3 数组的其他操作

1 数组复制

将一个数组的值赋值给另一个数组,该如何操作。

先看下面的代码,看看能否将 numbers1 的值复制给 numbers2

int[] numbers1 = {1, 2, 3, 4, 5, 6};
int[] numbers2 = new int[6];

numbers2 = numbers1;
System.out.println(Arrays.toString(numbers2));      // [1, 2, 3, 4, 5, 6]

numbers1[0] = 8;			// 修改numbers1的元素
System.out.println(Arrays.toString(numbers2));      // [8, 2, 3, 4, 5, 6] numbers2的值也变了

很明显上面并不能将 numbers1 的值复制给 numbers2,因为后来修改 numbers1 的值, numbers2 的值也发生了变化,说明不是独立的两份数据。

其实内存结果是下面这样的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

初始化两个数组的时候, numbers1numbers2 还是独立的数据,后来 numbers2 = numbers1; 则将 number1 中存储的地址值赋给了 number2,那么 number2 也之下那个了 number1 指向的堆中的内存地址。


所以我们在复制数组的时候,需要遍历数组,一个一个元素的去复制:

int[] numbers1 = {1, 2, 3, 4, 5, 6};
int[] numbers2 = new int[6];

// 将数组numbers1的值赋值给number2,这里要注意numbers1和numbers2的长度,不要越界
for (int i = 0; i < numbers1.length; i++) {
    numbers2[i] = numbers1[i];
}
System.out.println(Arrays.toString(numbers2));      // [1, 2, 3, 4, 5, 6]

numbers1[0] = 8;		// 修改numbers1的元素
System.out.println(Arrays.toString(numbers2));      // [1, 2, 3, 4, 5, 6],不影响numbers2

Java API 给我们提供了很多可以用的类,可以帮我们完成很多功能,不用需要我们编写代码去实现。

所谓的 Java API 就是为 Java 编程语言提供的可以直接使用的类库和方法。

例如上面的数组复制功能,也可以调用 Java 提供的 API :System.arraycopy

int[] numbers1 = {1, 2, 3, 4, 5, 6};
int[] numbers2 = new int[6];

// 将numbers1的值复制给numbers2
System.arraycopy(numbers1, 0, numbers2, 0, numbers1.length);
System.out.println(Arrays.toString(numbers2));

numbers1[0] = 8;		// 修改numbers1的元素
System.out.println(Arrays.toString(numbers2));      // [1, 2, 3, 4, 5, 6],不影响numbers2

System.arraycopy 参数说明:

  • 第一个参数:源数组,数据从哪里来;
  • 第二个参数:从源数组的哪个位置开始复制;
  • 第三个参数:目标数组,数据复制给谁;
  • 第四个参数:放到目标数组哪个位置;
  • 第五个参数:要复制的数据的长度;

还有另外的API : Arrays.copyOfArrays.copyOfRange ,也可以完成数组的复制,不过是重新开辟了内存空间。

int[] numbers1 = {1, 2, 3, 4, 5, 6};
int[] numbers2 = new int[6];
numbers2 = Arrays.copyOf(numbers1, 4);
System.out.println(Arrays.toString(numbers2));      // [1, 2, 3, 4]

int[] numbers3 = Arrays.copyOfRange(numbers1, 2, 5);
System.out.println(Arrays.toString(numbers3));			// [3, 4, 5]

在上面的代码中,并没有修改原来 numbers2 的内存空间的数据,而是重新开辟了内存控制,然后将内存地址给了变量 number2

Arrays.copyOf 的第一个参数是源数组,第二个是复制的数据长度,复制是从索引0开始复制的。

Arrays.copyOfRange 的第一个参数是源数组,第二个参数是复制的起始位置(包含该位置),第三个参数是复制的结束位置(不包含该位置)。

2 冒泡排序

思考:

一个 int[] 类型的数组,其中的元素大小没有顺序,该如何实现将其中的元素由大到小排列呢?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


原理

冒泡排序是数组排序中一个非常经典的算法。

原理是:依次比较相邻的两个数,将比较小的数放在前面,比较大的数放在后面。

首先取出第一个数,依次和后面的元素比较,如果比后面的元素大,就交换,否则继续用后面的数比较。

用图示例一下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面只是第一轮的比较,会找到最大的数,排到数组末尾;第二轮需要拿4进行比较,最终找到第二大的数6,6会沉到7前面,就不用和7比较了,也就是每比较一次,在最后面就会少比较一次,因为大的都沉到底部了,后面都是排序好的,自然就不用比较了。

冒泡算法因为在排序的过程中,较大(或较小)的元素会像气泡一样从数组的一端“浮”到另一端,像冒泡一样。


Java代码实现

下面使用 Java 代码实现冒泡排序。

public static void main(String[] args) {
    int[] num = {6, 4, 7, 1, 2, 5, 3};

    // 总共比较数组长度-1次,i就是当前比较的次数
    for (int i = 0; i < num.length - 1; i++) {
        // 每一次比较,在最后面都会少比较已经比较的次数
        for (int j = 0; j < num.length - i - 1; j++) {
            // 如果当前元素大于下一个元素,则交换它们
            if (num[j] > num[j + 1]) {
                // 交换两个位置的值
                int temp = num[j];
                num[j] = num[j + 1];
                num[j + 1] = temp;
            }
        }
    }

    System.out.println(Arrays.toString(num));   // [1, 2, 3, 4, 5, 6, 7]
}

同样,在实际开发中也不需要我们手写排序算法, Java API 也提供了排序的方法,可以直接调用排序方法来对数组进行排序,只是 Java API 底层不是用冒泡排序实现的,冒泡排序的效率不是很高。

int[] num = {6, 4, 7, 1, 2, 5, 3};

// 从小到大对数组进行排序
Arrays.sort(num);
System.out.println(Arrays.toString(num));   // [1, 2, 3, 4, 5, 6, 7]

所有当我们要实现一个功能的时候,可以先查一下 Java API 有没有提供现成的功能。

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

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

相关文章

前端基础学习html(1)

1.标题标签.h1,h2...h6 2.段落标签p 换行标签br 3.加粗strong(b) /倾斜em(i) /删除 del(s) /下划线ins(u) 4.盒子&#xff1a;div //一行一个 span//一行多个 5.img :src alt title width height border 图片src引用&#xff1a;相对路径 上级/同级/中级 绝对路径&#xff…

直播话术核心逻辑,学了轻松提高销量!沈阳直播运营培训

直播话术到底该怎么说&#xff1f; 产品话术说得好&#xff0c;直播间一次就能卖出去上万件产品&#xff1b;产品话术说不好&#xff0c;直播间半个月也卖不出去10件产品。 我们上次就有跟大家说过产品话术的具体流程&#xff0c;但发现还有更多朋友居然还是不能够很好地完成一…

2024/5/6 QTday1

自由发挥应用场景&#xff0c;实现登录界面。 要求&#xff1a;尽量每行代码都有注释。 #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//窗口相关设置this->resize(350,470);this->setFixedSize(350,470);//窗口标题this-&g…

一个简单的仓库出入库管理软件的流程是什么样的?有哪些功能?

身为仓库文员&#xff0c;我深知仓库管理对于公司运营的重要性。仓库是公司物资的中转站&#xff0c;其管理的好坏直接关系到公司的运营效率和成本控制。然而&#xff0c;传统的仓库管理方式往往存在着效率低下、易出错等问题&#xff0c;为了解决这些问题&#xff0c;我们需要…

uboot图形界面配置

文章目录 一、环境安装二、配置默认项2.图形界面 三、图形配置项的来源1.mainmenu主界面 一、环境安装 &#x1f4a6;uboot 或 Linux 内核可以通过输入“make menuconfig”来打开图形化配置界面&#xff0c;menuconfig是一套图形化的配置工具&#xff0c;需要 ncurses 库支持。…

2024年电工杯数学建模竞赛A题B题思路代码分享

您的点赞收藏是我继续更新的最大动力&#xff01; 欲获取更多电工杯学习资料&#xff0c;可点击如下卡片链接 点击链接加入群聊【2024电工杯】&#xff1a;http://qm.qq.com/cgi-bin/qm/qr?_wv1027&k_PrjarulWZU8JsAOA9gnj_oHKIjFe195&authKeySbv2XM853pynlnXiv6M58…

解决github的remote rejected|git存储库的推送保护

前言 git存储库的推送保护。当你试图推送代码到GitHub仓库时&#xff0c;由于存在与主分支&#xff08;master&#xff09;相关的仓库规则违规行为&#xff0c;推送会被拒绝了。这种保护机制帮助确保只有经过授权和符合规定的代码才能被合并到主分支&#xff0c;从而保护了主分…

网络聊天室:通过Servlet和JSP,结合session和application实现(文末附源码)

目录 一.成品效果 二.代码部分 chat.jsp ChatServlet 一.成品效果 在启动成功后&#xff0c;我们就可以在任意俩个浏览器页面中相互发消息&#xff0c;如图所示左边屏幕使用的是Edge浏览器&#xff0c;右图使用的是火狐浏览器。当然笔者这里只是简单实现最基本的一些功能&…

【LeetCode刷题记录】105. 从前序与中序遍历序列构造二叉树 106. 从中序与后序遍历序列构造二叉树

105 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,7], inorder [9,3,1…

Linux--IIC驱动编程实验

对于 I2C 主机驱动&#xff0c;一旦编写完成就不需要再做修改&#xff0c;其他的 I2C 设备直接调用主机驱动提供的 API 函数完成读写操作即可。这个正好符合 Linux 的驱动分离与分层的思想&#xff0c;因此 Linux内核也将 I2C 驱动分为两部分&#xff1a; ①、 I2C 总…

盘一盘接口测试的那些痛点,你现在会解决了吗

前言 说到接口测试&#xff0c;想必大家一定不会陌生。接口测试就是测试系统组件间&#xff0c;接口对接是否顺畅的一种测试。包括测试数据能否交换、能否传递、能否正常控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系&#xff0c;等等。 由于接口测试主要是检测系统…

5月3日江苏某厂冷却塔清洗工作汇报-智渍洁

5月3日 施工人员&#xff1a;张能超&#xff0c;张伟&#xff0c;刘平&#xff0c;曾巧 施工事项&#xff1a;空冷器脱脂 今日工作进度&#xff0c;清洗6台遇到的问题&#xff0c;就是那个喷雾器不经用&#xff0c;一会儿又坏了 重庆智渍洁环保科技有限公司专注于工业清洗&…

使用ThemeRoller快速实现前端页面风格美化

使用ThemeRoller快速实现前端页面风格美化 文章目录 使用ThemeRoller快速实现前端页面风格美化一、ThemeRoller二、使用方法1.基本操作面板介绍2.直接用现成的配色风格——Gallery画廊3.自定义风格——Roll Your Own4.下载风格包并应用到页面 一、ThemeRoller ThemeRoller是jQ…

欢乐钓鱼大师脚本,游戏托管一键操作!

欢迎来到《钓鱼大师乐趣无穷》&#xff01;这里是一片充满了乐趣和挑战的钓鱼天地。不论你是刚刚入门的小白&#xff0c;还是已经成为老手的大神&#xff0c;本攻略将为你揭示如何在游戏中获得成功&#xff0c;并针对稀有鱼类的钓鱼技巧进行详细介绍。 一、初探钓鱼的乐趣 在《…

GEE错误——image.reduceRegion is not a function

简介 image.reduceRegion is not a function 这里的主要问题是我们进行地统计分析的时候&#xff0c;我们的作用对象必须是单景影像&#xff0c;而不是影像集合 错误"image.reduceRegion is not a function" 表示你正在尝试使用reduceRegion()函数来处理图像数据&…

MySQL数据库—多表设计(有这一篇够!)

▐ 数据库设计范式 • 第一范式&#xff1a;确保每列保持原子性 ( 列不可再分解 ) 例如联系方式包括&#xff1a;电话/邮箱/微信... 那么我们设计表时就需要将它具体化 • 第二范式&#xff1a;要有主键&#xff0c;通过主键可以精确的定位到某行数据. 其他字段都依赖于主…

JAVA----Thread(2

Thread 提供的属性和方法 目录 Thread 提供的属性和方法一.构造方法1.Thread() :2.Thread(Runnable target) :3.Thread(String name) :main 线程 4.Thread(Runnable target, String name) : 二.属性1.ID (getId)2.名称(getName)3.状态(getState)4.优先级 (getPriority)5.是否后…

如何用中医揿针治疗肩周炎?

点击文末领取揿针的视频教程跟直播讲解 首先我们先来了解什么是肩周炎 【中医辨证】 肩周炎中医称之为漏肩风、锁肩风、肩凝症等&#xff0c;将肩周炎的一系列症状归纳为痹证的范畴&#xff0c;故又有肩痹、肩胛周痹等病名。 在中医古典医籍《素问痹论》中有骨痹、筋痹、脉…

LangChain Agent最全教程学习

LangChain Agent的终极指南&#xff0c;本教程是您使用 Python 创建第一个agent的重要指南&#xff0c;请立即开始你的 LLM 开发之旅。 一、什么是LangChain Agent&#xff08;代理&#xff09; LangChain中代理背后的想法是利用语言模型以及要执行的一系列操作。代理正在使用…

C++常用库函数——strcmp、strchr

1、strcmp&#xff1a;比较两个字符串的值是否相等 例如 char a1[6] "AbDeG",*s1 a1;char a2[6] "AbdEg",* s2 a2;s1 2;s2 2;printf("%d \n", strcmp(s1, s2));return(0); s1指向a1&#xff0c;s2指向a2&#xff0c;strcmp表示比较s1和s…