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

一篇文章学懂C++和指针与链表

指针

目录

指针

C++的指针学习

指针的基本概念

指针变量的定义和使用

指针的所占的内存空间

空指针和野指针

const修饰指针

指针和数组

指针和函数

指针、数组、函数


 接下来让我们开始进入学习吧!

C++的指针学习

指针的基本概念

指针的作用:可以通过指针间接访问内存

  1. 内存编号是从0开始记录的,一般用十六进制数字表示

  2. 可以利用指针变量保存地址

这个概念和C语言是一模一样的,只要记住指针就是地址

指针变量的定义和使用

#include<iostream>
using namespace std;
int main()
{int a = 10;int *pa = &a;cout << a << endl;cout << pa << endl;cout << &a << endl;cout << *pa << endl;//可以通过解引用的方式来找到指针指向的内存*pa = 20;//通过指针来改变a的值cout << a << endl;cout << *pa << endl;return 0;
}
输出结果:
10
0x61fe14
0x61fe14
10
20
20

指针的所占的内存空间

指针也是一种数据类型,所以也会占内存空间。

#include<iostream>
using namespace std;
int main()
{int* pa;char* pb;short* pc;long* pd;float* pe;double* pf;cout << sizeof(pa) << endl;cout << sizeof(pb) << endl;cout << sizeof(pc) << endl;cout << sizeof(pd) << endl;cout << sizeof(pe) << endl;cout << sizeof(pf) << endl;return 0;
}
8
8
8
8
8
8

在32位的操作系统中,指针都是占4个字节的空间的。

在64位的操作系统中,指针则都是占8个字节的空间的。

所以看题目或者写代码的时候一定要清楚自己机器的大小和型号。

空指针和野指针

空指针:指针变量指向内存中编号为0的空间

用途:初始化针变量

注意:空指针指向的内存是不可以访间的

示例1:空指针

#include<iostream>
using namespace std;
int main()
{//空指针//空指针用于给指针变量进行初始化int* p = NULL;//2.空指针是不可以进行访问的,//0~255内存编号是系统占用的,使用会错误,因此不可访问cout << *p <<endl;return 0;
}

野指针:指针变量指向非法的内存空间

示例2:野指针

#include<iostream>
using namespace std;
int main()
{int* p = (int*)0x1100;cout << *p << endl;//这里还是无法输出,指向的是非法内存空间int arr[2] = { 1,2 };p = arr[2];//越界访问cout << *p <<endl;return 0;
}

总结:空指针和野指针都不是我们自己申请的空间,因此不要访问。

const修饰指针

const修饰指针的三种情况:

  1. const修饰指针——常量指针

  2. const修饰常量——指针常量

  3. const既修饰指针,又修饰常量

示例:

#include<iostream>
using namespace std;
int main()
{int a = 10;int b = 20;//常量变量//特点:指针的指向可以修改,但是指针指向的值不可以改const int* p1 = &a;a = 0;//*p1也会相应改变p1 = &b;//可以实现*p1 = 0;//不允许//指针常量//特点:指针的指向不可以修改,但是指针指向的值可以改int* const p2 = &a;*p2 = 10;p1 = &b;//不允许*p1 = 0;//可以实现//既修饰指针,又修饰常量//特点:指针的指向不可以修改,但是指针指向的值也不可以改const int* const p3 = &a;p3 = &b;//不允许*p3 = 0;//不允许return 0;
}

指针和数组

作用:利用指针访问数组中元素

一维数组

#include<iostream>
using namespace std;
int main()
{int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };int * p = arr;for(int i = 0;i < 10; i++){cout << *p + i << endl;//用p[i]也可以做到}return 0;
}

二维数组

#include<iostream>
using namespace std;
int main()
{int arr[2][3] = { { 0,1,2 },{ 3,4,5} };int (* parr)[3] = arr;for(int i = 0;i < 2; i++){for(int j = 0;j < 3; j++){cout << (*parr[i]+j)<<endl;}}return 0;
}
 

指针和函数

作用:利用指针作函数参数,可以修改实参的值

#include<iostream>
using namespace std;
void Swap(int* x,int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
int main()
{//实现a,b交换int a,b;cin >> a >> b;Swap(&a,&b);cout << "a = " << a << endl;cout << "b = " << b << endl;return 0;
}

指针、数组、函数

案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序 如数组:int arr[10]={4,3,6,9,1,2,10,8,7,5}

#include<iostream>
using namespace std;
​
void bubbleSort(int *p,int sz)
{for(int i = 0;i < sz - 1; i++){for(int j = 0; j < sz - i - 1; j++){//如果j>j+1的数据就要交换if(*(p + j) > *(p + j + 1)){int tmp = *(p + j);*(p + j) = *(p + j + 1);*(p + j + 1) = tmp;}}}
}
​
//打印数组
void printArray(int * p,int sz)
{for(int i = 0;i < sz; i++){cout << *p + i << " ";}
}
int main()
{//1.创建数组int arr[10];for(int i = 0;i < 10; i++){cin >> arr[i];}//数组长度int sz = sizeof(arr) / sizeof(arr[0]);//2.创建函数bubbleSort(arr,sz);
​//3.打印排序后的数组printArray(arr,sz);return 0;
}

链表

学习C++链表

链表的基本概念avi_

数据域1+next地址 ——> 数据域2+next地址 ——> 数据域3+next地址 ——> 数据域4+next地址 ——> 数据域5+next地址 ——> NULL(空)

链表是一种物理存储单元上非连续非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。链表可以在多种编程语言中实现。像Lisp和Scheme这样的语言的内建数据类型中就包含了链表的存取和操作。程序语言或面向对象语言,如C,C++和Java依靠易变工具来生成链表。

链表在指定位置插入和删除不需要移动元素,只需要修改指针即可。

查找效率低于数组

链表相对于数组而言,多了指针域空间开销

链表种类:

静态链表 动态链表 单向链表 双向链表 循环链表 单向循环链表 双向循环链表

拿到链表的第一个节点,就相当于拿到整个链表

头节点不保存任何数据

静态链表

 

静态链表:分配一整片连续的内存空间,各个结点集中安置,逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成的链表称为静态链表。也就是说静态链表是用数组来实现链式存储结构,静态链表实际上就是一个结构体数组

实现一个链表

#define _CRT_SECURE_NO_WARNING
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
​
//链表节点类型定义
struct LinkNode
{int data;struct LinkNode *next;
};
​
void test()
{struct LinkNode node1 = { 10, NULL };struct LinkNode node2 = { 20, NULL };struct LinkNode node3 = { 30, NULL };struct LinkNode node4 = { 40, NULL };struct LinkNode node5 = { 50, NULL };struct LinkNode node6 = { 60, NULL };node1.next = &node2;node2.next = &node3;node3.next = &node4;node4.next = &node5;node5.next = &node6;//连成链表//如何遍历这个链表struct LinkNode *pCurrent = &node1;while(pCurrent != NULL){printf("%d ",pCurrent->data);//指针移动到下一个元素的首地址pCurrent = pCurrent->next;}
}
​
int main()
{test();return 0;
}

如何遍历这个链表 需要一个pCurrent指针能够指向下一个链表的地址

pCurrent = pCurrent->next

动态链表

这种链表在初始时不一定分配足够的空间, 但是在后续插入的时候需要动态申请存储空间,并且存储空间不一定连续, 在进行插入和删除时则不需要移动元素, 修改指针域即可,所以仍然具有链表的主要优点,链表结构可以是动态地分配存储的,即在需要时才开辟结点的存储空间,实现动态链接

链表的实现

LinkList.h

#define _CRT_SECURE_NO_WARNINGS
​
#pragma once
​
#include<stdio.h>
#include<stdnool.h>
#include<stdlib.h>
​
#iddef __cplusplus
#endif//定义节点数据类型struct LinkNode{int data;struct LinkNode *next;}
​//初始化链表struct LinkNode * Init_LinkList();//在值为oldval的后面插入一个新的数据newvalvoid InsertByValue_LinkList(struct LinkNode *header,int oldval,int newval);//删除值为val的节点void RemoveByValue_LinkList(struct LinkNode *header,int delValue);//遍历void Foreach_LinkList(struct LinkNode *header);//销毁void Destroy_LinkList(struct LinkNode *header);//清空void Clear_LinkList(struct LinkNode *header);#ifdef __cplusplus
#endif

LinkList.c

#include "LinkList.h"
//初始化链表
struct LinkNode * Init_LinkList()
{//创建头节点struct LinkNode *header = malloc(sizeof(struct LinkNode));header->data = -1;header->next = NULL;//尾部指针struct LinkNode *pRear = header;int val = -1;while(true){printf("输入插入的数据:\n");scanf("%d",&val);if(val == -1){break;}//先创建新节点struct LinkNode *newnode = malloc(sizeof(struct LinkNode));newnode->data = val;newnode->next = NULL;//新节点插入到链表中pRear->next = newnode;//更新尾部指针指向pRear = newnode;}return header;
}
​//在值为oldval的位置插入一个新的数据newvalvoid InsertByValue_LinkList(struct LinkNode *header,int oldval,int newval){if(NULL == header){return;}//两个辅助指针变量struct LinkNode *pPrev = header;struct LinkNode *pCurrent = pPrev->next;while(*pCurrent != NULL){if(pCurrent->data == oldval){break;}pPrev = pCurrent;pCurrent = pCurrent->next;}//pCurrent为空那就说明链表中不存在职位oldval的节点if(pCurrent == NULL){return;}//先创建新节点struct LinkNode *newnode = malloc(sizeof(struct LinkNode));newnode->data = newval;newnode->next = NULL;//新节点插入到链表中pPrev->next = newnode;newnode->next = pCurrent;//删除值为val的节点void RemoveByValue_LinkList(struct LinkNode *header,int delValue){if(NULL == header){return;}//两个辅助指针变量struct LinkNode *pRrev = header;struct LinkNode *pCurrent = pRrev->next;//while(pCurrent != NULL){if(pCurrent->data == delValue){break;}//移动两个辅助指针pPrev = pCurrent;pCurrent = pCurrent->next;}if(pCurrent == NULL){return;}//重新建立待删除节点的前驱和后继节点关系pPrev->next = pCurrent->next;free(pCurrent);pCurrent == NULL;}
​//遍历void Foreach_LinkList(struct LinkNode *header){if(NULL == header){return;}//辅助指针变量struct LinkNode *pCurrent = header->next;while(pCurrent != Null){printf("%d ",pCurrent->data);pCurrent = pCurrent->next;}}
​//销毁void Destroy_LinkList(struct LinkNode *header){if(NULL == header){return;}//辅助指针变量struct LinkNode *pCurrent = header;while(pCurrent != NULL){//先保存当前节点的下一个节点地址struct LinkNode *pNext = pCurrent->next;//释放当前节点内存free(pCurrent);//指针向后移动pCurrent = pNext;}}//清空void Clear_LinkList(struct LinkNode *header){if(NULL == header){return;}//辅助指针变量struct LinkNode *pCurrent = header->next;while(pCurrent != NULL){//先保存当前节点的下一个节点位置struct LinkNode *pNext = pCurrent->next;//释放当前节点内存free(pCurrent);//pCurrent指向下一个节点pCurrent = pNext;}header->next = NULL;}

TestLinkList.c

相关文章:

一篇文章学懂C++和指针与链表

指针 目录 指针 C的指针学习 指针的基本概念 指针变量的定义和使用 指针的所占的内存空间 空指针和野指针 const修饰指针 指针和数组 指针和函数 指针、数组、函数 接下来让我们开始进入学习吧&#xff01; C的指针学习 指针的基本概念 指针的作用&#xff1a;可…...

TPGS-cisplatin顺铂修饰维生素E聚乙二醇1000琥珀酸酯

TPGS-cisplatin顺铂修饰维生素E聚乙二醇1000琥珀酸酯(TPGS)溶于大部分有机溶剂,和水有很好的溶解性。 长期保存需要在-20℃,避光,干燥条件下存放&#xff0c;注意取用一定要干燥,避免频繁的溶解和冻干。 维生素E聚乙二醇琥珀酸酯(简称TPGS)是维生素E的水溶性衍生物,由维生素E…...

【20230206-0209】哈希表小结

哈希表一般哈希表都是用来快速判断一个元素是否出现在集合里。哈希函数哈希碰撞--解决方法&#xff1a;拉链法和线性探测法。拉链法&#xff1a;冲突的元素都被存储在链表中线性探测法&#xff1a;一定要保证tableSize大于dataSize&#xff0c;利用哈希表中的空位解决碰撞问题。…...

c++11 标准模板(STL)(std::multimap)(一)

定义于头文件 <map> template< class Key, class T, class Compare std::less<Key>, class Allocator std::allocator<std::pair<const Key, T> > > class multimap;(1)namespace pmr { template <class Key, class T…...

python进阶——自动驾驶寻找车道

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…...

男,26岁,做了一年多的自动化测试,最近在纠结要不要转行,求指点。?

最近一个粉丝在后台问我&#xff0c;啊大佬我现在26了&#xff0c;做了做了一年多的自动化测试&#xff0c;最近在纠结要不要转行&#xff0c;求指点。首选做IT这条路&#xff0c;就是很普通的技术蓝领。对于大部分来说干一辈子问题不大&#xff0c;但是发不了什么财。如果你在…...

源码级别的讲解JAVA 中的CAS

没有CAS之前实现线程安全 多线程环境不使用原子类保证线程安全&#xff08;基本数据类型&#xff09; public class T3 {volatile int number 0;//读取public int getNumber(){return number;}//写入加锁保证原子性public synchronized void setNumber(){number;} }多线程环…...

JUC锁与AQS技术【我的Android开发技术】

JUC锁与AQS技术【我的Android开发技术】 AQS原理 AQS就是一个同步器&#xff0c;要做的事情就相当于一个锁&#xff0c;所以就会有两个动作&#xff1a;一个是获取&#xff0c;一个是释放。获取释放的时候该有一个东西来记住他是被用还是没被用&#xff0c;这个东西就是一个状…...

【问题代码】顺序点的深入理解(汇编剖析+手画图解)

这好像是一个哲学问题。 目录 前言 一、顺序点是什么&#xff1f; 二、发生有关顺序点的问题代码 vs中&#xff1a; gcc中&#xff1a; 三、细读汇编 1.vs汇编如下&#xff08;示例&#xff09;&#xff1a; 2.gcc汇编如下&#xff08;示例&#xff09;&#xff1a; 四…...

BinaryAI全新代码匹配模型BAI-2.0上线,“大模型”时代的安全实践

导语BinaryAI&#xff08;https://www.binaryai.net&#xff09;科恩实验室在2021年8月首次发布二进制安全智能分析平台—BinaryAI&#xff0c;BinaryAI可精准高效识别二进制文件的第三方组件及其版本号&#xff0c;旨在推动SCA&#xff08;Software Composition Analysis&…...

nvidia设置wifi和接口

tx-nx设置wifi和接口前言基础知识点1.创建和删除一个wifi连接2. 启动连接和关闭连接代码和调试1. 代码展示2. 调试写到最后前言 针对嵌入式开发&#xff0c;有时候通过QT或PAD跨网络对设备设置WIFI&#xff0c;在此记录下&#xff0c;方便后续的查阅。 基础知识点 1.创建和删…...

PostgreSQL 变化数据捕捉(CDC)

PostgreSQL 变化数据捕捉&#xff08;CDC&#xff09;基于CDC&#xff08;变更数据捕捉&#xff09;的增量数据集成总体步骤&#xff1a;1.捕获源数据库中的更改数据2.将变更的数据转换为您的消费者可以接受的格式3.将数据发布到消费者或目标数据库PostgreSQL支持触发器&#x…...

Spring 事务【隔离级别与传播机制】

Spring 事务【隔离级别与传播机制】&#x1f34e;一.事务隔离级别&#x1f352;1.1 事务特性回顾&#x1f352;1.2 事务的隔离级别(5种)&#x1f352;1.3 事务隔离级别的设置&#x1f34e;二.Spring 事务传播机制&#x1f352;2.1 Spring 事务传播机制的作用&#x1f352;2.2 事…...

HTTP和HTTPS协议

HTTP协议 HTTP协议是一种应用层的协议&#xff0c;全称为超文本传输协议。 URL URL值统一资源定位标志&#xff0c;也就是俗称的网址。 协议方案名 http://表示的就是协议方案名&#xff0c;常用的协议有HTTP协议、HTTPS协议、FTP协议等。HTTPS协议是以HTTP协议为基础&#…...

day3——有关java运算符的笔记

今天主要学习的内容有java的运算符 赋值运算符算数运算符关系运算符逻辑运算符位运算符&#xff08;专门写一篇笔记&#xff09;条件运算符运算符的优先级流程控制 赋值运算符 赋值运算符&#xff08;&#xff09;主要用于给变量赋值&#xff0c;可以跟算数运算符相结合&…...

Git多人协同远程开发

1. 李四&#xff08;项目负责人&#xff09;操作步骤 在github中创建远程版本库testgit将基础代码上传⾄testgit远程库远程库中基于main分⽀创建dev分⽀将 githubleaflife/testgit 共享给组员李四继续在基础代码上添加⾃⼰负责的模块内容 2. 张三、王五&#xff08;组员&…...

Chapter4:机器人仿真

ROS1{\rm ROS1}ROS1的基础及应用&#xff0c;基于古月的课&#xff0c;各位可以去看&#xff0c;基于hawkbot{\rm hawkbot}hawkbot机器人进行实际操作。 ROS{\rm ROS}ROS版本&#xff1a;ROS1{\rm ROS1}ROS1的Melodic{\rm Melodic}Melodic&#xff1b;实际机器人&#xff1a;Ha…...

python(14)--集合

前言 本篇文章学习的是 python 中集合的基础知识。 集合元素的内容是不可变的&#xff0c;常见的元素有整数、浮点数、字符串、元组等。至于可变内容列表、字典、集合等不可以是集合元素。虽然集合不可以是集合的元素&#xff0c;但是集合本身是可变的&#xff0c;可以去增加或…...

【Spark分布式内存计算框架——Spark Core】4. RDD函数(中)Transformation函数、Action函数

3.2 Transformation函数 在Spark中Transformation操作表示将一个RDD通过一系列操作变为另一个RDD的过程&#xff0c;这个操作可能是简单的加减操作&#xff0c;也可能是某个函数或某一系列函数。值得注意的是Transformation操作并不会触发真正的计算&#xff0c;只会建立RDD间…...

Mysql 数据类型

1、数值数据类型 1.1 整数类型(精确值) INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT MySQL支持SQL标准的整数类型INTEGER (或INT)和SMALLINT。作为标准的扩展&#xff0c;MySQL还支持整数类型TINYINT、MEDIUMINT和BIGINT。下表显示了每种整数类型所需的存储和范围。…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...