|
在前面的章节中接触过很多操作符的内容。但原手册上在此处的章节名称虽然叫”操作符“,但内容并不以操作符为主。我们需要明确,编程行业中”操作符“一词是专业术语,又叫”运算符“,指的是用来对变量、常量、表达式结果执行特定运算、访问、赋值等操作的专用符号。就像上一章介绍运算优先顺序的那些,都是操作符,或者运算符。我们之前说过的”表达式“,就是数据加操作符组成。顾名思义,操作或者运算,一定会有个结果,所以表达式一定会有一个具体的返回值。 在我们之前学”返回值“这个概念时,特别提到,并不是所有的函数都有返回值。没有返回值的函数一定会有某种”副作用“,这所谓的”副作用“可能是增删改查了某个值,也可能是产生了其他效果。那么能够产生这些”副作用“的东西,就是本章所要介绍的东西。它的学名应该叫”语法执行单元“。 所谓语法执行单元,就是编程语言里有一定语法组装规则,运行时能独立完成一个完整动作、产生实际效果的语法单位。这里的”单元“指的是独立起作用的特性,而不是指它是语法的基础组成。实际上,语法执行单元理解起来也分层级。 最基层的语法单元就是由数据和运算符组成的表达式;表达式可以独立获得一个运算结果,比如访问数据,声明变量,赋值,数值计算等等,这也是它的完整动作和实际效果。由表达式和分号,以及一些属于系统关键字,比如if else for return等等功能语法单元,组成的语句是中级语法单元,一个语句就相当于代码运行的”一步“。最高层次的语法单元是”语块“,又叫复合语句,就是由花括号{}括起来的整体,最常见的就是函数的主体部分,它的作用是限制语句代码的作用域,把多条语句划分在一起执行,而不受其他位置的代码影响。 所以千万不要按照原手册上”操作符“的概念去理解这一章的内容。下面我一条一条的捋一下这些语法执行单元。 一、复合/块语句 Compound operator {} 特别提示:Compound operator直译是复合操作符的意思,这两个单词并不是语法内容,后面那个花括号{}才是真正的”复合操作符“,也就是复合语句的特征。 定 义:复合语句(也叫代码块,Block)是一段被大括号 {} 包裹起来的代码区域;它的内部可以包含一条或多条任意类型的可执行语句,其中每条表达式语句都以分号 ; 结尾。 注 意:花括号{}本身就是复合语句的开头和结尾符号,所以写函数或者其他块语句时,结束花括号}后面永远不用加分号;我们的声明函数时,只需要写函数名字和用小括号扩起来的函数参数,不需要写函数的主体,也就是没有花括号括起来的内容,但小括号没有结束语句的作用,所以在小括号后面必须加一个分号,告诉系统,这句写完了。在写函数的实现过程时,函数的小括号后面紧接着就是花括号,不能加分号,系统就知道函数名字、小括号、花括号这三者是一个整体;有个例外情况,结构体、类、枚举用来放成员的部分也是用花括号括起来的,但它们的成员只是一个一个的数据,不是可执行的语句,虽然有花括号的形式,本质上却跟声明变量的语句是一样的,所以末尾花括号后也要加一个分号,告诉系统,我的声明到此结束。 应 用:符合块语句的应用很广泛,比如if /else 条件分支语句、switch 多分支选择语句、for 循环语句、while 循环语句、do-while 循环语句以及函数主体部分,都要用到符合块语句的花括号;另外如果想要某段代码只在局部起作用,避免变量名字起冲突,用来做一些临时的计算,也可以把这些语句直接用花括号抱起来做成”独立作用域块“。 二、表达式语句 Expression operator (;) 特别提示:Expression operator直译是表达操作符的意思,这两个单词同样不是语法内容,后面小括号里面的分号”;“才是真正的”表达操作符“,也就是表达式语句的特征。 定 义:表达式语句,就是一个表达式加上分号,构成最基础的可执行指令,用来完成单次计算、赋值、函数调用等动作;表达式是语句执行的最基础的一步。 注 意:分号是语句的结束标记,不是运算符;表达式加上分号后,它的返回值会被丢弃,只保留执行的副作用(比如赋值、函数调用的效果)。 三、函数调用表达式语句 Function_name (argument1,..., argumentN); 特别提示:Function_name意思是函数名,argument意思是函数的参数,N表示该函数有多个参数。我们在上一章讲运算符优先级的时候,优先级最高的第一个就是小括号(),也就是函数调用操作符/运算符,函数名字加小括号和它里面的参数再加上末尾的分号,就是完整的函数调用表达式语句。 核心作用:说白了,`()` 就是用来 “启动函数” 的运算符,把函数名当成操作数(操作对象),括号里放参数,就能触发函数执行并拿到返回结果。 规 则: (1)函数调用必须选择实参匹配。之前聊过”形参“和”实参“的概念。简单来说,函数声明和函数定义里,小括号里面的参数是”形参“,也就是形式参数,特征是写明了数据类型,本身是一种变量声明。函数定义就相当于设计了一台加工机器,它规定了原材料和出产品的数量、类型,但没有实际的原材料和产品。而函数调用相当于让系统把这台机器搬过来,加工几个实际数据。所以在函数调用时,小括号里必须写”实参“也就是实际的数据,但这实际的数据一定要符合函数声明和定义里要求的参数类型、数量、顺序一一对应,否则这台机器就会报故障,说原材料不符合要求,不能正常工作。需要特别提醒的是,我们用加工机器来比喻函数,但函数的参数并不是完全指加工原料,函数的输入和输出都是它的参数,新手需要着重理解,等讲函数时再细说。 (2)实参可以是任意有具体返回值的表达式。所谓返回值,并不仅限于数字值,而是任何一个可以用我们之前学的”数据类型“来划分的数据单元,它可以是布尔值、字符串、枚举、结构体等任意数据类型,无论如何,它首先得是个数据。像int a这种,是一个变量声明语句,不是一个数据,所以你的函数实参可以是变量a,但绝不能是int a。单独的一个变量a,本身就是一个表达式。表达式可以有一个返回值,但表达式语句没有返回值,所以函数的实参可以是a+b这种表达式,但不能是a+b;这种表达式语句。同样,有返回值的函数也可以做函数的参数,但无返回值的函数就不可以。 (3)函数也有没参数的。需要调用无参数的函数是,小括号也不能省略,直接写空括号就可以。 注 意:MQL5语言中存在很多同型不同意的符号。这个小括号只有跟在函数名子后面,才是”函数调用符“,其他情况下有其他的用途。 四、空语句 ; 空语句说白了就只有一个分号; ,它相当于是表达式为空的表达式语句,不产生任何计算、赋值、调用动作,什么也不做。 编程语言的语法规则非常严格:凡是要求「必须写一条语句」的位置,就不能什么都不写。当逻辑上不需要执行任何操作,但语法上必须有一条语句时,就用空语句来占位,满足语法要求。 手册上举的例子是,带条件检测的流程控制语句(if、while、for)—— 这些语句的结构要求后面必须跟一条语句,当不需要执行实际代码时,就用空语句。 比如我们写一个for循环语句,for(循环起点,循环重点,计数器){} ,花括号里要写它的具体循环过程,但我们需要写一个空循环体,比如要跳过一些k线,这里的循环就只需要计数,不需要实际操作,也就没了花括号,但for循环不写花括号是语法错误,就把花括号改成分号,告诉系统,这个for循环的主体是空语句。 这里有点像我们之前说的函数声明的小括号后面写一个分号,直接结束该语句,告诉系统,这个函数没有主体,本语句到此结束。在形式上完全一致。只不过那里叫语句结束符。 空语句了解即可,真写EA时千万别用它,会搞乱自己的思路。 |