arduino变量于字符串连接打印for循环变量出错?

1、IDE的安装和基本使用

  Arduino使用Arduino IDE进行开发,IDE的安装很简单, 在官方网站下载后自行安装即可

  转到Tools→Board,然后选择你的板。

  A - 用于检查是否存在任何编译错误。

  C - 用于创建新草图的快捷方式。

  D - 用于直接打开示例草图之一。

  F - 用于从板接收串行数据并将串行数据发送到板的串行监视器。

  现在,只需点击环境中的“Upload”按钮。等待几秒钟,你将看到板上的RX和TX LED灯闪烁。如果上传成功,则状态栏中将显示“Done uploading”消息。

  软件结构包括两个主要函数:

  • PURPOSE- 草图启动时会调用 setup()函数。使用它来初始化变量,引脚模式,启用库等。setup函数只能在Arduino板的每次上电或复位后运行一次。

  • PURPOSE- 在创建了用于初始化并设置初始值的setup()函数后,loop() 函数,正如它的名称所指,允许你的程序连续循环的更改和响应。可以使用它来主动控制Arduino板。

  void关键字仅用于函数声明。它表示该函数预计不会向调用它的函数返回任何信息。

  布尔值保存两个值之一,true或false。每个布尔变量占用一个字节的内存。

  一种数据类型,占用一个字节的内存,存储一个字符值。字符文字用单引号写成:\'A\',对于多个字符,字符串使用双引号:"ABC"。

  但是,字符是存储为数字。你可以在中查看特定编码。这意味着可以对使用ASCII值的字符进行算术运算。例如,\'A\'+1的值为66,因为大写字母A的ASCII值为65。

  unsigned char是一种无符号数据类型,占用一个字节的内存。unsigned char数据类型编码数字为0到255。

  一个字节存储一个8位无符号数,从0到255。

  整数(int)是数字存储的主要数据类型。int存储16位(2字节)值。这产生-32768至32767的范围(最小值为-2^15,最大值为(2^15)-1)。

  int的大小因板而异。例如,在Arduino Due中,int存储32位(4字节)值。这产生-至的范围(最小值-2^31和最大值(2^31)-1)。

  unsigned int(无符号整数)与int相同,存储2字节。然而,它们只存储正值,产生0到65535(2^16)-1的有效范围。Due存储4字节(32位)值,范围从0到(2^32-1)。

  在Uno和其他基于ATMEGA的板上,一个word存储一个16位无符号数。在Due和Zero上,它存储一个32位无符号数。

  Long变量是用于数字存储的扩展大小变量,存储32位(4字节),从-到。

  unsigned long变量是用于数字存储的扩展大小变量,并存储32位(4字节)。与标准的long不同,unsigned long不会存储负数,它们的范围为0到(2^32-1)。

  浮点数的数据类型是具有小数点的数字。浮点数通常用于近似模拟值和连续值,因为它们的分辨率高于整数。

  浮点数可以大到3.,也可以低到-3.。它们被存储为32位(4字节)信息。

  在Uno和其他基于ATMEGA的板上,双精度浮点数占用四个字节。也就是说,double实现与float完全相同,精度没有增益。在Arduino Due上,double具有8字节(64位)精度。

与其他编程语言逻辑及风格基本相同

变量按作用范围分为局部变量和全局变量,此处略去不讲

==  比较值是否相等

!=  比较值是否不等

<=  小于等于

>=  大于等于

||  逻辑或(or)

  它采用括号中的表达式,后面跟随语句或语句块。如果表达式为真,则执行语句或语句块,否则跳过这些语句。

  一个 if 语句后面可以跟随一个可选的else语句,当表达式为false时执行。

  类似于if语句, switch ... case 通过允许程序员指定应在各种条件下执行的不同代码来控制程序的流程。

  条件运算符? :是C语言中唯一的三元运算符。

  while循环将会连续、无限循环,直到括号()内的表达式变为false。必须用一些东西改变被测试的变量,否则while循环永远不会退出。

  do ... while循环类似于while循环。在while循环中,循环连续条件在循环开始时测试,然后再执行循环体。

  for循环执行语句预定的次数。循环的控制表达式在for循环括号内完全的初始化,测试和操作。

  C语言允许你在另一个循环内使用一个循环

  它是没有终止条件的循环,因此循环变为无限。

函数在循环函数之上或之下的任何其他函数之外声明。

我们可以用两种不同的方式声明函数:

第一种方法是在循环函数上面写入被称为函数原型的函数的一部分,它包括:

  • 函数参数类型,不需要写参数名称

函数原型后面必须加上分号(;)。

以下示例为使用第一种方法的函数声明的示范。

第二种方法,称为函数定义或声明,必须在循环函数的下面声明,它包括:

  • 函数参数类型,这里必须添加参数名称
  • 函数体(调用函数时执行的函数内部的语句)

以下示例演示了使用第二种方法的函数声明。

此示例将显示如何创建字符串并将其打印到串口监视器窗口。

同样的例子可以用更方便的方式编写,如下所示:

// (2) 将字符串对象转为大写 // (5) 获取字符串对象的长度

  delay()函数的工作方式非常简单。它接受单个整数(或数字)参数。此数字表示时间(以毫秒为单位)。

  delayMicroseconds()函数接受单个整数(或数字)参数。一毫秒内有一千微秒,一秒内有一百万微秒。

  此函数用于返回Arduino板开始运行当前程序时的毫秒数。

  micros()函数返回Arduino板开始运行当前程序时的微秒数。该数字在大约70分钟后溢出,即回到零。

下面以一个int数组示例来学习数组相关

}

数组是具有相同类型的连续内存位置组。 要引用数组中的特定位置或元素,我们指定数组的名称和数组中特定元素的位置编号。

下面给出的插图显示了一个名为C的整数数组,其中包含11个元素。 您可以通过在方括号([])中给出数组名称后跟特定元素的位置编号来引用这些元素中的任何一个。 位置编号更正式地称为下标或索引(此数字指定从数组开头的元素数)。 第一个元素有下标0(零),有时称为零元素。

因此,数组C的元素是C [0](发音为“C sub zero”),C [1],C [2]等。 数组C中的最高下标是10,比数组(11)中的元素数少1。 数组名称遵循与其他变量名称相同的约定。

下标必须是整数或整数表达式(使用任何整数类型)。 如果程序使用表达式作为下标,则程序将计算表达式以确定下标。 例如,如果我们假设变量a等于5并且变量b等于6,则该语句将2添加到数组元素C [11]。

下标数组名称是左值,它可以在赋值的左侧使用,就像非数组变量名一样。

要打印数组C的前三个元素中包含的值的总和,我们会写 -

要将C [6]的值除以2并将结果赋值给变量x,我们会写 -

数组在内存中占用空间。 要指定元素的类型和数组所需的元素数,请使用表单的声明 -

编译器保留适当的内存量。 (回想一下,保留内存的声明更准确地称为定义)。 arraySize必须是大于零的整数常量。 例如,要告诉编译器为整数数组C保留11个元素,请使用声明 -

可以声明数组包含任何非引用数据类型的值。 例如,类型字符串数组可用于存储字符串。

本节提供了许多演示如何声明,初始化和操作数组的示例。

示例1:声明一个数组并使用循环初始化数组的元素

该程序声明了一个10元素的整数数组n 。 a-b行使用For语句将数组元素初始化为零。 与其他自动变量一样,自动数组不会隐式初始化为零。 第一个输出语句(第c行)显示在后续for语句中打印的列的列标题(第d-e行),它以表格格式打印数组。

示例2:使用初始化列表初始化声明中的数组

数组的元素也可以在数组声明中初始化,方法是在数组名称后面加上等号和大括号分隔的逗号分隔的初始化列表。 该程序使用初始化列表初始化具有10个值的整数数组(行a),并以表格格式(行b-c)打印该数组。

示例3:对数组元素求和

通常,数组的元素表示要在计算中使用的一系列值。 例如,如果数组的元素代表考试成绩,教授可能希望总计数组的元素并使用该总和来计算考试的课程平均值。 程序对10元素整数数组a包含的值求和。

数组对Arduino很重要,需要更多关注。 Arduino应该清楚以下与数组相关的重要概念 -

要将数组参数传递给函数,请指定不带任何括号的数组名称。

具有两个维度(即,下标)的数组通常表示由以行和列排列的信息组成的值表。

}

MATLAB(矩阵实验室)是第四代高级编程语言和交互式环境,用于数值计算,可视化和编程。

它允许矩阵操作; 绘制功能和数据; 算法的实现; 创建用户界面; 与用其他语言编写的程序连接,包括C,C ++,Java和FORTRAN; 分析数据; 开发算法; 并创建模型和应用程序。

它具有许多内置命令和数学函数,可帮助您进行数学计算,生成绘图和执行数值方法。

MATLAB的计算数学的力量

MATLAB用于计算数学的各个方面。 以下是一些常用的数学计算,它最常用 -

  • 它是数值计算,可视化和应用程序开发的高级语言。

  • 它还为迭代探索,设计和解决问题提供了交互式环境。

  • 它为线性代数,统计,傅立叶分析,滤波,优化,数值积分和求解常微分方程提供了大量的数学函数库。

  • 它提供了内置图形,用于可视化数据和工具,用于创建自定义图。

  • MATLAB的编程接口提供了用于提高代码质量可维护性和最大化性能的开发工具。

  • 它提供了使用自定义图形界面构建应用程序的工具

  • 它提供了将基于MATLAB的算法与外部应用程序和语言(如C,Java,.NET和Microsoft Excel)集成的功能。

MATLAB被广泛用作科学和工程中的计算工具,包括物理,化学,数学和所有工程流。 它用于一系列应用,包括 -

设置MATLAB环境只需点击几下。 安装程序可以从下载。

MathWorks还提供许可产品,试用版和学生版。 您需要登录该站点并等待一点他们的批准。

下载安装程序后,只需点击几下即可安装软件。

可以从桌面上创建的图标启动MATLAB开发IDE。 MATLAB中的主要工作窗口称为桌面。 启动MATLAB时,桌面将以默认布局显示 -

  • Command Window - 这是可以在命令行输入命令的主要区域。 它由命令提示符(“”)表示。

  • Workspace - 工作空间显示从文件创建和/或导入的所有变量。

如果您愿意在您的机器上使用Octave(Linux,BSD,OS X或Windows),请从下载最新版本。 您可以查看机器的给定安装说明。

MATLAB环境就像一个超级复杂的计算器。 您可以在>>命令提示符下输入命令。

MATLAB是一个解释环境。 换句话说,你给出一个命令,MATLAB立即执行它。

输入有效的表达式,例如,

单击“执行”按钮或键入Ctrl + E时,MATLAB立即执行它,返回的结果为 -

让我们再举几个例子 -

单击“执行”按钮或键入Ctrl + E时,MATLAB立即执行它,返回的结果为 -

单击“执行”按钮或键入Ctrl + E时,MATLAB立即执行它,返回的结果为 -

单击“执行”按钮或键入Ctrl + E时,MATLAB立即执行它,返回的结果为 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

访问单元格数组中的数据

有两种方法可以引用单元格数组的元素 -

  • 将索引括在第一个括号()中,以引用单元格集
  • 将索引括在大括号{}中,以引用单个单元格中的数据

将索引括在第一个括号中时,它指的是一组单元格。

平滑括号中的单元阵列索引指的是单元组。

MATLAB将执行上述语句并返回以下结果 -

您还可以通过使用花括号索引来访问单元格的内容。

MATLAB将执行上述语句并返回以下结果 -

如果你想创建一个包含1到10整数的行向量,你可以写 -

MATLAB执行该语句并返回一个包含从1到10的整数的行向量 -

如果要指定除1之外的增量值,例如 -

MATLAB执行该语句并返回以下结果 -

让我们再看一个例子 -

MATLAB执行该语句并返回以下结果 -

您可以使用冒号运算符创建索引向量,以选择数组的行,列或元素。

下表描述了它的用途(让我们有一个矩阵A) -

是等效的二维数组。 对于矩阵,这与A相同。
是三维数组A的第k页。
是四维阵列A中的矢量。矢量包括A(i,j,k,1),A(i,j,k,2),A(i,j,k,3)等。
是A的所有元素,被视为单列。 在赋值语句的左侧,A(:)填充A,保留其之前的形状。 在这种情况下,右侧必须包含与A相同数量的元素。

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

MATLAB支持各种数字类,包括有符号和无符号整数以及单精度和双精度浮点数。 默认情况下,MATLAB将所有数值存储为双精度浮点数。

您可以选择将任意数字或数字数组存储为整数或单精度数字。

所有数字类型都支持基本数组操作和数学运算。

转换为各种数字数据类型

MATLAB提供以下函数来转换为各种数字数据类型 -

转换为16位有符号整数
转换为32位有符号整数
转换为64位有符号整数
转换为16位无符号整数
转换为32位无符号整数
转换为64位无符号整数

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

让我们再扩展前面的例子。 创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

函数intmax()intmin()返回可以用所有类型的整数表示的最大值和最小值。

这两个函数都将整数数据类型作为参数,例如,intmax(int8)或intmin(int64),并返回可以用整数数据类型表示的最大值和最小值。

以下示例说明如何获取最小和最大的整数值。 创建一个脚本文件并在其中编写以下代码 -

运行该文件时,它显示以下结果 -

函数realmax()realmin()返回可以用浮点数表示的最大值和最小值。

使用参数“single”调用时,这两个函数都返回可以用单精度数据类型表示的最大值和最小值,当使用参数“double”调用时,返回可以表示的最大值和最小值双精度数据类型。

以下示例说明如何获取最小和最大浮点数。 创建一个脚本文件并在其中编写以下代码 -

运行该文件时,它显示以下结果 -

在MATLAB中创建字符串非常简单。 事实上,我们已多次使用它。 例如,在命令提示符下键入以下内容 -

MATLAB将执行上述语句并返回以下结果 -

MATLAB将所有变量视为数组,字符串被视为字符数组。 让我们使用whos命令检查上面创建的变量 -

MATLAB将执行上述语句并返回以下结果 -

有趣的是,您可以使用数字转换函数(如uint8uint16将字符串中的字符转换为其数字代码。 char函数将整数向量转换回字符 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

到目前为止我们讨论过的字符串是一维字符数组; 但是,我们需要存储更多。 我们需要在程序中存储更多的文本数据。 这是通过创建矩形字符数组来实现的。

创建矩形字符数组的最简单方法是通过根据需要垂直或水平连接两个或多个一维字符数组。

您可以通过以下任一方式垂直组合字符串 -

  • 使用MATLAB连接运算符[]并用分号(;)分隔每一行。 请注意,在此方法中,每行必须包含相同数量的字符。 对于具有不同长度的字符串,您应根据需要填充空格字符。

  • 使用char函数。 如果字符串具有不同的长度,则char将较短的字符串填充为尾随空白,以便每行具有相同的字符数。

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

您可以通过以下任一方式水平组合字符串 -

  • 使用MATLAB连接运算符[]并用逗号或空格分隔输入字符串。 此方法保留输入数组中的任何尾随空格。

  • 使用字符串连接函数strcat 。 此方法删除输入中的尾随空格。

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

将字符串组合成单元阵列

从我们之前的讨论中可以清楚地看出,组合不同长度的字符串可能会很麻烦,因为数组中的所有字符串都必须具有相同的长度。 我们在字符串的末尾使用了空格来均衡它们的长度。

但是,组合字符串的更有效方法是将结果数组转换为单元数组。

MATLAB单元阵列可以在阵列中保存不同大小和类型的数据。 单元阵列提供了一种更灵活的方式来存储不同长度的字符串。

cellstr函数将字符数组转换为字符串的单元格数组。

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

MATLAB中的字符串函数

MATLAB提供了许多字符串函数,用于创建,组合,解析,比较和操作字符串。

下表提供了MATLAB中字符串函数的简要说明 -

用于在字符数组中存储文本,组合字符数组等的函数。
从字符数组创建字符串的单元格数组
转换为字符数组(字符串)
确定输入是否是字符串的单元格数组
将单元格数组中的字符串加入单个字符串
用于识别字符串部分,查找和替换子字符串的函数
确定字符串是否为指定的类别
从字符串中读取格式化数据
在指定的分隔符处拆分字符串
检查文本字符串的有效性
确定表达式中的符号变量
匹配正则表达式(区分大小写)
匹配正则表达式(不区分大小写)
使用正则表达式替换字符串
将字符串转换为正则表达式
比较字符串(区分大小写)
比较字符串(不区分大小写)
比较字符串的前n个字符(区分大小写)
比较字符串的前n个字符(不区分大小写)
用于将字符串更改为大写或小写,创建或删除空格的函数
从字符串末尾剥去尾随空格
从字符串中删除前导和尾随空格

以下示例说明了上述一些字符串函数 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

函数是一组一起执行任务的语句。 在MATLAB中,函数在单独的文件中定义。 文件和函数的名称应该相同。

函数可以接受多个输入参数,并且可以返回多个输出参数。

以下名为mymax函数应该写在名为mymax.m的文件中。 它需要五个数字作为参数并返回数字的最大值。

创建一个名为mymax.m的函数文件,并在其中键入以下代码 -

函数的第一行以关键字function开头。 它给出了函数的名称和参数的顺序。 在我们的示例中, mymax函数有五个输入参数和一个输出参数。

函数语句后面的注释行提供帮助文本。 键入时会打印这些行 -

MATLAB将执行上述语句并返回以下结果 -

您可以将该功能称为 -

MATLAB将执行上述语句并返回以下结果 -

匿名函数就像传统编程语言中的内联函数,在单个MATLAB语句中定义。 它由单个MATLAB表达式和任意数量的输入和输出参数组成。

您可以在MATLAB命令行或函数或脚本中定义匿名函数。

这样您就可以创建简单的函数,而无需为它们创建文件。

从表达式创建匿名函数的语法是

在这个例子中,我们将编写一个名为power的匿名函数,它将两个数字作为输入,并将第一个数字返回到第二个数字的幂。

创建一个脚本文件并在其中键入以下代码 -

当您运行该文件时,它显示 -

必须在文件中定义除匿名函数之外的任何函数。 每个函数文件都包含一个首先出现的必需主函数和任何数量的可选子函数,它们位于主函数之后并由它使用。

可以从命令行或其他函数从定义它们的文件外部调用主函数,但不能从函数文件外部的命令行或其他函数调用子函数。

子函数仅对主函数和定义它们的函数文件中的其他子函数可见。

让我们编写一个名为二次的函数来计算二次方程的根。 该函数将采用三个输入,二次系数,线性系数和常数项。 它会回归根源。

创建一个函数文件quadratic.m并在其中键入以下代码 -

您可以从命令提示符调用上述函数 -

MATLAB将执行上述语句并返回以下结果 -

您可以在另一个函数的主体内定义函数。 这些被称为嵌套函数。 嵌套函数包含任何其他函数的任何或所有组件。

嵌套函数在另一个函数的范围内定义,并且它们共享对包含函数工作空间的访问。

嵌套函数遵循以下语法 -

让我们从前面的例子中重写quadratic函数,但是,这次盘函数将是一个嵌套函数。

创建一个函数文件quadratic2.m并在其中键入以下代码 -

您可以从命令提示符调用上述函数 -

MATLAB将执行上述语句并返回以下结果 -

私有函数是主要功能,仅对有限的一组其他函数可见。 如果您不想公开函数的实现,可以将它们创建为私有函数。

它们仅对父文件夹中的函数可见。

让我们重写quadratic函数。 然而,这次计算判别式的disc函数将是私有函数。

在工作目录中创建一个名为private的子文件夹。 将以下功能文件disc.m在其中 -

在工作目录中创建一个函数quadratic3.m并在其中键入以下代码 -

您可以从命令提示符调用上述函数 -

MATLAB将执行上述语句并返回以下结果 -

全局变量可以由多个函数共享。 为此,您需要在所有函数中将变量声明为全局变量。

如果要从基础工作空间访问该变量,请在命令行声明该变量。

全局声明必须在变量实际用于函数之前发生。 最好使用大写字母表示全局变量的名称,以便将它们与其他变量区分开来。

让我们创建一个名为average.m的函数文件,并在其中键入以下代码 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它将显示以下结果 -

在MATLAB中导入数据意味着从外部文件加载数据。 importdata函数允许加载不同格式的各种数据文件。 它有以下五种形式 -

从系统剪贴板而不是从文件加载数据。

delimiterIn解释为ASCII文件,文件名或剪贴板数据中的列分隔符。 您可以将delimiterIn与上述语法中的任何输入参数一起使用。

从ASCII文件,文件名或剪贴板加载数据,从行headerlinesIn+1开始读取数字数据。

默认情况下,Octave不支持importdata()函数,因此您必须搜索并安装此软件包,以使以下示例与您的Octave安装一起使用。

让我们加载并显示图像文件。 创建一个脚本文件并在其中键入以下代码 -

运行该文件时,MATLAB显示图像文件。 但是,您必须将其存储在当前目录中。

在此示例中,我们导入文本文件并指定分隔符和列标题。 让我们创建一个带有列标题的空格分隔的ASCII文件,名为weeklydata.txt

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

在此示例中,让我们从剪贴板导入数据。

将以下行复制到剪贴板 -

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

importdata函数是一个高级函数。 MATLAB中的低级文件I/O函数允许最大程度地控制对文件的读取或写入数据。 但是,这些功能需要有关您的文件的更详细信息才能有效工作。

MATLAB为字节或字符级别的读写操作提供以下功能 -

关闭一个或所有打开的文件
有关文件I/O错误的信息
从文件中读取行,删除换行符
从文件中读取行,保留换行符
打开文件,或获取有关打开文件的信息
从二进制文件中读取数据
将文件位置指示器移动到打开文件的开头
移动到文件中的指定位置

使用低级I/O导入文本数据文件

MATLAB为文本数据文件的低级导入提供以下功能 -

  • fscanf函数以文本或ASCII文件读取格式化数据。

  • fgetlfgets函数一次读取一行文件,其中换行符分隔每一行。

  • fread函数以字节或位级别读取数据流。

我们在工作目录中保存了一个文本数据文件'myfile.txt'。 该文件存储了三个月的降雨量数据; 2012年6月,7月和8月。

myfile.txt中的数据包含五个地方的重复时间,月份和降雨量测量集。 标题数据存储月数M; 所以我们有M组测量。

该文件看起来像这样 -

我们将从此文件导入数据并显示此数据。 采取以下步骤 -

  • 使用fopen函数打开文件并获取文件标识符。

  • 要跳过文件中的文字字符,请将它们包含在格式说明中。 要跳过数据字段,请在说明符中使用星号('*')。

    例如,要读取标题并返回M的单个值,我们写 -

  • 默认情况下, fscanf根据我们的格式描述读取数据,直到找不到数据的任何匹配,或者它到达文件的末尾。 这里我们将使用for循环来读取3组数据,每次读取7行和5列。

  • 我们将在工作空间中创建一个名为mydata的结构,以存储从文件中读取的数据。 此结构有三个字段 - timemonthraindata数组。

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

MATLAB中的数据导出(或输出)意味着写入文件。 MATLAB允许您在另一个读取ASCII文件的应用程序中使用您的数据。 为此,MATLAB提供了几种数据导出选项。

您可以创建以下类型的文件 -

  • 来自数组的矩形,分隔的ASCII数据文件。

  • 击键日记(或日志)文件以及生成的文本输出。

  • 使用fprintf等低级函数的专用ASCII文件。

  • MEX文件,用于访问写入特定文本文件格式的C/C ++或Fortran例程。

除此之外,您还可以将数据导出到电子表格。

有两种方法可以将数值数组导出为分隔的ASCII数据文件 -

使用保存功能的语法是 -

以下示例演示了该概念。 创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

请注意,save -ascii命令和dlmwrite函数不能用于单元格数组作为输入。 要从单元格数组的内容创建分隔的ASCII文件,您可以

  • 或者,使用cell2mat函数将单元格数组转换为矩阵

  • 或者使用低级文件I/O函数导出单元阵列。

如果使用save函数将字符数组写入ASCII文件,则会将ASCII等效字符写入文件。

例如,让我们将“hello”一词写入文件 -

MATLAB执行上述语句并显示以下结果。 这是8位ASCII格式的字符串'hello'的字符。

日记文件是MATLAB会话的活动日志。 日记功能在磁盘文件中创建会话的精确副本,不包括图形。

要打开日记功能,请键入 -

或者,您可以提供日志文件的名称,例如 -

您可以在文本编辑器中打开日记文件。

使用低级I/O将数据导出到文本数据文件

到目前为止,我们已经导出了数字数组。 但是,您可能需要创建其他文本文件,包括数字和字符数据的组合,非矩形输出文件或具有非ASCII编码方案的文件。 出于这些目的,MATLAB提供了低级fprintf函数。

与低级I/O文件活动一样,在导出之前,您需要使用fopen函数打开或创建文件并获取文件标识符。 默认情况下,fopen打开一个文件以进行只读访问。 您应该指定写入或附加的权限,例如“w”或“a”。

处理完文件后,需要使用fclose(fid)函数关闭它。

以下示例演示了该概念 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

要绘制函数的图形,您需要执行以下步骤 -

以下示例将演示该概念。 让我们绘制简单函数y = xy = x的值范围从0到100,增量为5。

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB显示以下图表 -

让我们再举一个例子来绘制函数y = x 2 。 在这个例子中,我们将绘制两个具有相同功能的图形,但在第二次,我们将减少增量的值。 请注意,随着我们减少增量,图表变得更加平滑。

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB显示以下图表 -

稍微更改代码文件,将增量减少到5 -

在图表上添加标题,标签,网格线和缩放

MATLAB允许您添加标题,沿x轴和y轴的标签,网格线以及调整轴以使图形更加丰富。

  • title命令允许您在图表上添加标题。

  • grid on命令允许您将网格线放在图形上。

  • axis equal命令允许生成具有相同比例因子和两个轴上的空间的图。

创建一个脚本文件并键入以下代码 -

在同一图上绘制多个函数

您可以在同一个绘图上绘制多个图形。 以下示例演示了该概念 -

创建一个脚本文件并键入以下代码 -

MATLAB为绘制图形提供了八种基本颜色选项。 下表显示了颜色及其代码 -

让我们绘制两个多项式的图

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB会生成以下图表 -

axis命令允许您设置轴刻度。 您可以使用axis命令以下列方式为x和y轴提供最小值和最大值 -

以下示例显示了这一点 -

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB会生成以下图表 -

在同一图中创建绘图数组时,每个绘图都称为子绘图。 subplot命令用于创建子图。

其中, mn是绘图数组的行数和列数, p指定放置特定绘图的位置。

使用subplot命令创建的每个绘图都可以具有自己的特征。 以下示例演示了这一概念 -

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB会生成以下图表 -

本章将继续探索MATLAB的绘图和图形功能。 我们将讨论 -

bar命令绘制二维条形图。 让我们举一个例子来证明这个想法。

让我们有一个有10名学生的虚构教室。 我们知道这些学生获得的分数百分比是75,58,90,87,50,85,92,75,60和95.我们将绘制这些数据的条形图。

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB显示以下条形图 -

两个变量的函数的等高线是曲线,函数具有恒定值。 轮廓线用于通过连接高于给定水平的相等高度的点(例如平均海平面)来创建等高线图。

MATLAB提供了用于绘制等高线图的contour功能。

让我们生成一个等高线图,显示给定函数g = f(x,y)的等高线。 这个函数有两个变量。 因此,我们必须生成两个独立变量,即两个数据集x和y。 这是通过调用meshgrid命令完成的。

meshgrid命令用于生成元素矩阵,该矩阵给出x和y上的范围以及每种情况下的增量规范。

让我们绘制函数g = f(x,y),其中-5≤x≤5,-3≤y≤3。让我们对这两个值取0.1的增量。 变量设置为 -

最后,我们需要分配功能。 让我们的函数为:x 2 + y 2

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB显示以下等高线图 -

让我们稍微修改一下代码以修饰地图

运行该文件时,MATLAB显示以下等高线图 -

三维图基本上显示由两个变量中的函数定义的表面,g = f(x,y)。

和以前一样,为了定义g,我们首先使用meshgrid命令在函数域上创建一组(x,y)点。 接下来,我们分配函数本身。 最后,我们使用surf命令创建表面图。

以下示例演示了该概念 -

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB显示以下三维地图 -

您还可以使用mesh命令生成三维曲面。 但是, surf命令以颜色显示连接线和曲面的面,而mesh命令创建一个线框曲面,其中彩色线连接定义点。

到目前为止,我们已经看到所有示例都在MATLAB以及GNU中工作,或者称为Octave。 但是对于求解基本代数方程,MATLAB和Octave都没什么不同,所以我们将尝试在单独的部分中介绍MATLAB和Octave。

我们还将讨论代数表达式的分解和简化。

在MATLAB中求解基本代数方程

solve函数用于求解代数方程。 在最简单的形式中,solve函数将引号括起来的等式作为参数。

例如,让我们在等式x-5 = 0中求解x

MATLAB将执行上述语句并返回以下结果 -

您也可以将求解函数称为 -

MATLAB将执行上述语句并返回以下结果 -

您甚至可能不包括等式的右侧 -

MATLAB将执行上述语句并返回以下结果 -

如果方程涉及多个符号,那么默认情况下MATLAB假设您正在求x,但是,求解函数有另一种形式 -

在哪里,你还可以提到变量。

例如,让我们解决方程v - u - 3t 2 = 0,对于v。在这种情况下,我们应该写 -

MATLAB将执行上述语句并返回以下结果 -

求解Octave中的基本代数方程

roots函数用于求解Octave中的代数方程式,您可以按照以下方式编写上述示例 -

例如,让我们在等式x-5 = 0中求解x

Octave将执行上述声明并返回以下结果 -

您也可以将求解函数称为 -

Octave将执行上述声明并返回以下结果 -

在MATLAB中求解二次方程

solve函数也可以求解高阶方程。 它通常用于求解二次方程。 该函数返回数组中方程的根。

以下示例解决了二次方程式x 2 -7x +12 = 0.创建脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

以下示例在Octave中求解二次方程x 2 -7x +12 = 0。 创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

在MATLAB中求解高阶方程

solve函数也可以求解高阶方程。 例如,让我们求解三次方程为(x-3) 2 (x-7)= 0

MATLAB将执行上述语句并返回以下结果 -

在高阶方程的情况下,根很长,包含许多项。 您可以通过将它们转换为double来获得此类根的数值。 以下示例解决了四阶方程x 4 - 7x 3 + 3x 2 - 5x + 9 = 0。

创建一个脚本文件并键入以下代码 -

运行该文件时,它返回以下结果 -

请注意,最后两个根是复数。

求解Octave中的高阶方程

创建一个脚本文件并键入以下代码 -

运行该文件时,它返回以下结果 -

solve函数还可用于生成涉及多于一个变量的方程组的解。 让我们举一个简单的例子来证明这种用法。

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

同样,您可以解决更大的线性系统。 考虑以下方程组 -

Octave中方程组的求解

我们有一个不同的方法来解决'n'未知数的'n'线性方程组。 让我们举一个简单的例子来证明这种用法。

这样的线性方程组可以写成单矩阵方程Ax = b,其中A是系数矩阵,b是包含线性方程右边的列向量,x是表示解是如下程序所示 -

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

同样,您可以解决更大的线性系统,如下所示 -

在MATLAB中扩展和收集方程

expandcollect功能分别扩展和收集方程。 以下示例演示了这些概念 -

使用许多符号函数时,应声明变量是符号的。

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

Octave中的方程扩展和收集

你需要有symbolic包,它提供expandcollect功能,分别扩展和收集方程。 以下示例演示了这些概念 -

当您使用许多符号函数时,您应该声明您的变量是符号的,但Octave有不同的方法来定义符号变量。 注意SinCos的使用,它们也在符号包中定义。

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

代数表达式的因式分解与简化

factor函数是表达式的factorsimplify函数简化了表达式。 以下示例演示了该概念 -

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

MATLAB提供了解决微分和积分微积分问题的各种方法,解决了任意度数的微分方程和极限的计算。 最重要的是,您可以通过求解原始函数及其导数,轻松绘制复杂函数的图形并检查图形上的最大值,最小值和其他文具点。

本章将讨论微积分问题。 在本章中,我们将讨论预演算概念,即计算函数的极限和验证极限的性质。

在下一章“ Differential ,我们将计算表达式的导数并在图形上找到局部最大值和最小值。 我们还将讨论求解微分方程。

最后,在Integration一章中,我们将讨论积分计算。

MATLAB提供了计算限制的limit功能。 在最基本的形式中, limit函数将表达式作为参数,并在独立变量变为零时查找表达式的限制。

例如,让我们计算函数f(x)=(x 3 + 5)/(x 4 + 7)的极限 ,因为x趋于零。

MATLAB将执行上述语句并返回以下结果 -

限制函数属于符号计算领域; 你需要使用syms函数告诉MATLAB你正在使用哪些符号变量。 您还可以计算函数的限制,因为变量趋向于除零之外的某个数字。 要计算lim x-“a (f(x)),我们使用带有参数的limit命令。 第一个是表达式,第二个是数字, x接近,这里是a

例如,让我们计算函数f(x)=(x-3)/(x-1)的极限,因为x趋于1。

MATLAB将执行上述语句并返回以下结果 -

MATLAB将执行上述语句并返回以下结果 -

以下是使用symbolic包的上述示例的Octave版本,尝试执行并比较结果 -

Octave将执行上述声明并返回以下结果 -

代数极限定理提供了极限的一些基本属性。 这些如下 -

让我们考虑两个功能 -

让我们计算两个函数中x趋于5的函数的极限,并使用这两个函数和MATLAB验证极限的基本属性。

创建一个脚本文件并在其中键入以下代码 -

当您运行该文件时,它显示 -

0

用Octave验证极限的基本性质

以下是使用symbolic包的上述示例的Octave版本,尝试执行并比较结果 -

Octave将执行上述声明并返回以下结果 -

当函数对某个特定的变量值具有不连续性时,该点上不存在该限制。 换句话说,函数f(x)的极限在x = a时具有不连续性,当x从左侧接近x时,极限值不等于x从右侧接近时的极限值。

这导致左手和右手限制的概念。 对于x a,从左边开始,即x接近a。 对于x> a的值,右手限制被定义为x - > a,从右边开始,即x接近a。 当左手限制和右手限制不相等时,限制不存在。

让我们考虑一个功能 -

我们将证明lim x-“3 f(x)不存在。 MATLAB帮助我们以两种方式建立这一事实 -

  • 通过绘制函数图并显示不连续性。
  • 通过计算限制并显示两者都不同。

通过将字符串“left”和“right”作为最后一个参数传递给limit命令来计算左手和右手限制。

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,MATLAB绘制以下图表

MATLAB提供了用于计算符号导数的diff命令。 在最简单的形式中,您将要区分为diff命令的函数作为参数传递。

创建一个脚本文件并在其中键入以下代码 -

编译并执行上述代码时,会产生以下结果 -

以下是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

让我们简要说明用于区分函数的各种方程或规则并验证这些规则。 为此,我们将f'(x)表示为一阶导数,f“(x)表示二阶导数。

以下是差异化的规则 -

对于任何函数f和g以及任何实数a和b是函数的导数 -

sum规则表明如果f和g是两个函数,f'和g'分别是它们的导数,那么,

product规则规定如果f和g是两个函数,f'和g'分别是它们的导数,那么,

quotient规则指出如果f和g是两个函数,f'和g'分别是它们的导数,那么,

该规则的直接结果是任何常数的导数为零,即,如果y = k ,则任何常数

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,MATLAB显示以下结果 -

以下是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

指数,对数和三角函数的导数

下表提供了常用指数函数,对数函数和三角函数的导数 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,MATLAB显示以下结果 -

以下是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

为了计算函数f的更高导数,我们使用语法diff(f,n)

MATLAB执行代码并返回以下结果 -

以下是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

以下是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

找到曲线的最大值和最小值

如果我们正在搜索图的局部最大值和最小值,我们基本上是在特定位置的函数图上寻找最高点或最低点,或者是符号变量的特定值范围。

为了找到我们区分的函数的平稳点,我们需要将导数设置为零并求解方程。

MATLAB执行代码并返回以下图表 -

以下是上述示例的Octave等效代码 -

MATLAB执行代码并返回以下图表 -

以下是上述示例的Octave等效代码 -

MATLAB执行代码并返回以下结果 -

这是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

MATLAB执行代码并返回以下结果 -

以下是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

MATLAB执行代码并返回以下结果 -

以下是Octave相当于上面的计算 -

MATLAB提供了用于象征性地求解微分方程的dsolve命令。

用于查找单个方程的解的dsolve命令的最基本形式是

其中eqn是用于输入eqn的文本字符串。

它返回一个符号解决方案,其中包含一组MATLAB标记C1,C2等的任意常量。

您还可以指定问题的初始条件和边界条件,如下所示,以逗号分隔的列表为 -

通过D导数的顺序表示更高的导数。

让我们举一个简单的一阶微分方程的例子:y'= 5y。

MATLAB执行代码并返回以下结果 -

让我们将二阶微分方程的另一个例子作为:y“ - y = 0,y(0)= -1,y'(0)= 2。

MATLAB执行代码并返回以下结果 -

集成处理两种本质上不同类型的问题。

  • 在第一种类型中,给出了函数的导数,我们想要找到函数。 因此,我们基本上扭转了分化的过程。 这种逆过程被称为反微分,或找到原始函数,或找到indefinite integral

  • 第二类问题涉及累加非常大量的非常小的数量,然后随着数量的大小接近零而采取限制,而术语的数量倾向于无穷大。 这个过程导致了definite integral的定义。

定义积分用于寻找面积,体积,重心,转动惯量,由力完成的工作以及许多其他应用。

使用MATLAB查找不定积分

根据定义,如果函数f(x)的导数是f'(x),那么我们说f'(x)相对于x的不定积分是f(x)。 例如,由于x 2的导数(相对于x)是2x,我们可以说2x的不定积分是x 2

不定积分不是唯一的,因为对于任何常数c的值,x 2 + c的导数也将是2x。

其中,c称为“任意常数”。

MATLAB提供了一个用于计算表达式积分的int命令。 为了得到一个函数的不定积分的表达式,我们写 -

例如,从我们之前的例子 -

MATLAB执行上述语句并返回以下结果 -

在这个例子中,让我们找到一些常用表达式的积分。 创建一个脚本文件并在其中键入以下代码 -

运行该文件时,它显示以下结果 -

创建一个脚本文件并在其中键入以下代码 -

请注意, pretty函数以更易读的格式返回表达式。

运行该文件时,它显示以下结果 -

使用MATLAB查找定积分

根据定义,定积分基本上是总和的极限。 我们使用定积分来找到诸如曲线和x轴之间的区域以及两条曲线之间的区域之类的区域。 定义积分也可用于其他情况,其中所需数量可表示为总和的极限。

通过传递要计算积分的限制, int函数可用于定积分。

例如,要计算值 我们写 -

MATLAB执行上述语句并返回以下结果 -

以下是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

可以使用Octave提供的quad()函数给出替代解决方案,如下所示 -

Octave执行代码并返回以下结果 -

所需面积由 - 给出 -

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

以下是Octave相当于上面的计算 -

Octave执行代码并返回以下结果 -

可以使用Octave提供的quad()函数给出替代解决方案,如下所示 -

Octave执行代码并返回以下结果 -

创建一个脚本文件并编写以下代码 -

运行该文件时,MATLAB绘制图形 -

以下是Octave相当于上面的计算 -

MATLAB将多项式表示为包含按降序幂排序的系数的行向量。 例如,等式P(x)= x 4 + 7x 3 - 5x + 9可表示为 -

polyval函数用于评估指定值的多项式。 例如,要评估我们先前的多项式p ,在x = 4时,键入 -

MATLAB执行上述语句并返回以下结果 -

MATLAB还提供了用于评估矩阵多项式的polyvalm函数。 矩阵多项式是以矩阵为变量的polynomial

例如,让我们创建一个方矩阵X并在X处计算多项式p -

MATLAB执行上述语句并返回以下结果 -

roots函数计算多项式的根。 例如,要计算多项式p的根,请键入 -

MATLAB执行上述语句并返回以下结果 -

函数poly是根函数的反函数并返回多项式系数。 例如 -

MATLAB执行上述语句并返回以下结果 -

polyfit函数找到以最小二乘意义拟合一组数据的多项式的系数。 如果x和y是包含要拟合为n次多项式的x和y数据的两个向量,那么我们通过写入得到拟合数据的多项式 -

创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB显示以下结果 -

MATLAB提供了使用变换的命令,例如拉普拉斯和傅里叶变换。 变换在科学和工程中用作简化分析和从另一个角度查看数据的工具。

例如,傅立叶变换允许我们将表示为时间函数的信号转换为频率函数。 拉普拉斯变换允许我们将微分方程转换为代数方程。

MATLAB提供laplacefourierfft命令,用于拉普拉斯,傅立叶和快速傅里叶变换。

时间f(t)函数的拉普拉斯变换由以下积分给出 -

拉普拉斯变换也表示为f(t)到F(s)的变换。 您可以看到此变换或积分过程将f(t)(符号变量t的函数)转换为另一个函数F(s),另一个变量为s。

拉普拉斯变换将微分方程转化为代数方程。 为了计算函数f(t)的拉普拉斯变换,写 -

在这个例子中,我们将计算一些常用函数的拉普拉斯变换。

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

MATLAB允许我们使用命令ilaplace计算逆拉普拉斯变换。

MATLAB将执行上述语句并显示结果 -

创建一个脚本文件并键入以下代码 -

运行该文件时,它显示以下结果 -

傅立叶变换通常将时间f(t)的数学函数变换为新函数,有时用F或F表示,其参数是频率,单位为周期/秒(赫兹)或每秒弧度。 然后,新函数被称为傅里叶变换和/或函数f的频谱。

创建一个脚本文件并在其中键入以下代码 -

运行该文件时,MATLAB绘制以下图表 -

将傅立叶变换绘制为 -

MATLAB提供了用于计算函数的逆傅立叶变换的ifourier命令。 例如,

MATLAB将执行上述语句并显示结果 -

GNU Octave是一种高级编程语言,如MATLAB,它主要与MATLAB兼容。 它也用于数值计算。

  • 它内置了对复杂数字的支持
  • 它有内置的数学函数和库

GNU Octave也是可自由再发行的软件。 您可以根据自由软件基金会发布的GNU通用公共许可证(GPL)的条款重新分发和/或修改它。

大多数MATLAB程序在Octave中运行,但是一些Octave程序可能无法在MATLAB中运行,因为Octave允许一些MATLAB没有的语法。

例如,MATLAB仅支持单引号,但Octave支持用于定义字符串的单引号和双引号。 如果您正在寻找关于Octave的教程,那么请从头开始阅读本教程,其中包括MATLAB和Octave。

本教程中涉及的几乎所有示例都与MATLAB以及Octave兼容。 让我们在MATLAB和Octave中尝试以下示例,它可以产生相同的结果而无需任何语法更改 -

此示例为函数g = xe - (x 2 + y 2创建3D曲面图。 创建一个脚本文件并键入以下代码 -

运行该文件时,MATLAB显示以下三维地图 -

虽然MATLAB的所有核心功能都可以在Octave中使用,但是有一些功能,例如差分和积分微积分,它们在两种语言中都不完全匹配。 本教程试图给出两种语法不同的示例。

考虑以下示例,其中MATLAB和Octave使用不同的函数来获得曲线的面积:f(x)= x 2 cos(x)对于-4≤x≤9。以下是MATLAB版本的代码 -

运行该文件时,MATLAB绘制图形 -

但是要在Octave中给出相同曲线的区域,你必须使用symbolic包如下 -

Simulink是一个基于仿真和模型的动态和嵌入式系统设计环境,与MATLAB集成。 Simulink也是由MathWorks开发的,是一种用于建模,模拟和分析多域动态系统的数据流图形编程语言工具。 它基本上是一个图形化的框图工具,带有可自定义的块库集。

它允许您将MATLAB算法合并到模型中,并将仿真结果导出到MATLAB中以进行进一步分析。

  • 嵌入式系统的测试和验证

MathWorks提供了其他一些附加产品以及可与Simulink一起使用的第三方硬件和软件产品。

以下列表简要介绍了其中一些 -

  • Stateflow允许开发状态机和流程图。

  • Simulink Coder允许自动生成C源代码以实时实现系统。

  • SimEvents提供了一个用于对排队系统进行建模的图形构建块库。

Simulink能够通过建模样式检查,需求可追溯性和模型覆盖分析对系统进行系统验证和验证。

Simulink Design Verifier允许您识别设计错误并生成用于模型检查的测试用例场景。

在左侧窗格中,您将找到基于各种系统分类的多个库,单击每个库将在右侧窗格中显示设计块。

要创建新模型,请单击“库浏览器”工具栏上的“ New按钮。 这将打开一个新的无标题模型窗口。

通过从库浏览器中选择适当的元素并将它们拖到“模型”窗口中,可以添加模型元素。

或者,您可以复制模型元素并将其粘贴到模型窗口中。

从Simulink库中拖放项目以创建项目。

出于此示例的目的,将使用两个块进行模拟 - Source (信号)和Sink (范围)。 信号发生器(信号源)产生模拟信号,然后由示波器(接收器)以图形方式显示。

首先将所需的块从库拖动到项目窗口。 然后,将块连接在一起,这可以通过将连接器从一个块上的连接点拖动到另一个块上的连接点来完成。

让我们将“正弦波”块拖入模型中。

从库中选择“Sinks”并将“Scope”块拖到模型中。

将信号线从正弦波块的输出拖动到Scope块的输入。

按“ Run ”按钮运行模拟,保持所有参数默认(您可以从“模拟”菜单更改它们)

您应该从范围获得以下图表。

}

我要回帖

更多关于 arduino变量于字符串连接 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信