一、CAPL代码块的执行逻辑
CAPL代码块的执行同高级其他语言一样,在一个代码块内,如果没有碰到流程控制语句,则从上往下依次执行。
示例如下
on start
{
write("执行第一句");
write("执行第二句");
write("执行第三句");
}
启动工程,打开Write窗口,可以看到,窗口上先打印了第一行,再打印了第二行,最后打印了第三行。
二、赋值语句
CAPL中给变量赋值,采取一个等号(=)的赋值方式
/*
赋值语法
变量+空格+等号+赋予的值;
比如,我们先定义一个整数类型变量Num,随后对其进行赋值为10
*/
on start
{
int num;
write("num的值是:%d",num);
num = 10;
write("num的值是:%d",num);
}
在上述代码中,我们先定义了一个整数num,随后使用write函数打印了num的值,而后我们使用赋值语句,为num赋予一个新值,并再次打印出num的值。
可以看到,在第一次write时,num由于还没有被赋值,所以num的值是默认值为0,
当我们使用赋值语句给num赋值为10后,打印出来的num的值即为10;
三、CAPL的变量运算及各个运算符详解
CAPL中支持的运算符如下图所示
CAPL支持的运算符与其他高级语言保持一致
1、数学、关系运算符
①、加减乘除运算符及取模运算
其中,加(+),减(-),乘(*)的运算逻辑与自然语言是一致的,就不再进行讲解。
除(/)运算,当除数和被除数都是小数时,使用除(/)运算符,可以直接得到我们常说的除法的结果,当除数和被除数中有整数时,使用此运算符,只能得到整除的结果。如10/3=3 5/2=2。
余数(%)运算,通常与除(/)运算配合使用,它的作用为,可以得到两数相除的余数。
比如,10%3 = 1 9%5 = 4 20%10 = 0
②、等于与不等于运算符
等于(==),不等于(!=)
在CAPL与大多数编程语言中,都采取了使用两个等号表示相等的语法,如
a==b 是表示a和b相等
而a = b,一个等号,则是属于赋值语句,将b的值赋予a
不等于(!=)是用来表示两个值不相等的运算符
如a != b 表示a与b不相等。
③、大于小于,大于等于,小于等于运算符
大于(>),小于(<),小于等于(<=),大于等于(>=),这四个运算符与自然语言的逻辑也保持一致。即a>3 表示的是a大于3,b<=10,表示a小于等于10;
④、自增、自减运算符
自增运算符(++),自减运算符(--)
自增和自减运算符通常有两种使用场景。
第一种为 运算符在后,第二种为运算符在前
当++在后时,含义为使用之后系统自动给变量的值增加1
当++在前时,含义为在使用变量之前,先给变量的值+1。
我们通过代码实际看下这二者的区别
on start
{
int a = 3,b = 0;//定义整形变量a并初始化为3,b并初始化为0
b = a;//将a的值赋予b
write("a的值是%d",a);
write("b的值是%d",b);
b = a++;//后置++,先使用a,使用完成后再给a的值+1
write("a的值是%d",a);
write("b的值是%d",b);
b = ++a;//前置++,先给a的值+1,再使用a(即是,使用前加一)
write("a的值是%d",a);
write("b的值是%d",b);
}
在代码中,我们首先将a初始化为3,b初始化为0
随后我们将a的值赋予了b,那么此时b的值就是3
此时打印a的值,a等于3
打印b的值,b也等于3
而后,我们执行了b = a++这行代码
由于后置++的作用是,使用完成之后再增加;
在将a++赋值给b时,由于a还未使用完成,所以b还是等于3
此时,打印a的值,可以看到,a已经变成了4
但打印出来的b的值还是3,说明a是在给b赋值完成之后,才执行的+1操作
最后,我们执行b = ++a这行代码
由于前置++的作用是,先给变量增加一,随后再使用;
在将++a赋值给b时,a还未使用,此时由于前置++,需要先给a的值+1后再使用
所以当赋值给b时,b拿到的值是a+1后的值,由于a在上一步时已经通过后置++变为了4,所以此处再+1,a的值就已经成为了5,最后再把5赋值给了b
我们通过write打印也可以看出来
此时a的值是5,b的值也是5。
以上,就是++运算符前置与后置的区别。自减(--)运算符的逻辑同自增(++),区别仅在于一个做加法,一个做减法,就不再赘述了。
⑤、加等于、减等于、乘等于、除等于和取模等于运算
加等于(+=),减等于(-=),乘等于(*=),以及除等于(/=)、取模等于(%=)的运算逻辑都是一致的,这里以加等于(+=)作为例子进行解释。
a+=1 可以认为是a=a+1的简写形式,即a+=x,就等价于 a=a+x;
即a+=1,就是让a等于a+1。
on start
{
int a = 3;
write("a的值是%d",a);
a+=1;
write("a的值是%d",a);
a+=3;
write("a的值是%d",a);
}
我首先定义了一个整数a,并赋值为3
随后打印出来,可以看到a的值是3
而后,执行a+=1,根据加等于的逻辑,这句话等同于a=a+1,即a = 3(a的值) +1 ,等于4
打印出来,看到值确实是4
最后,执行a+=3,根据逻辑,这句话等同于a=a+3,由于上一步a已经变为了4,所以这里等价于
a = 4(a的值)+3,即a=7,打印出来,看到值确实是7。
减等于,乘等于,除等于和取模等于的运算逻辑与加等于完全相同,区别仅在于是各自算法的问题,不再展开举例了。
a -= b 等价于a = a - b;
a *= b 等价于a = a * b;
a /= b 等价于a = a / b;
a %= b 等价于a = a % b;
2、逻辑运算符
注:在逻辑运算中,以大于等于1的数表示真,以0表示假
①、逻辑与运算符(&&)
逻辑与(&&)的运算规则为
真&&真 = 真;真&&假 = 假;假&&真 = 假;假&&假 = 假;
综上,可以简要口诀记忆为:逻辑与运算,全真才为真。
比如
on start
{
int a = 1, b = 1, c = 0;//定义a和b为1,即为真。c为0,即为假
int d;//定义d用于存放运算结果
d = a&&b;//让d等于a&&b,即将1和1进行逻辑与的结果给d
write("a&&b的值为%d",d);
d = a&&c;//让d等于a&&c,即将1和0进行逻辑与的结果给d
write("a&&c的值为%d",d);
}
可以看到,a和b均是真(1),c为假(0)
第一次d等于两个真进行与运算的结果,此时1&&1为1
第二次d等于一真一假进行与运算的结果,此时1&&0为0
②、逻辑或运算符(||)
逻辑或(||)的运算规则为
真||真 = 真;真||假 = 真;假||真 = 真;假||假 = 假;
综上,可以简要口诀记忆为:逻辑或运算,有真就为真。
比如
on start
{
int a = 1, b = 1, c = 0,d = 0;//定义a和b为1,即为真。c和d为0,即为假
int e;//定义e用于存放运算结果
e = a||b;//
write("a||b的值为%d",e);
e = a||c;//
write("a||c的值为%d",e);
e = c||d;//
write("c||d的值为%d",e);
}
可以看到,a、b为真,c、d为假
第一次运算,e等于真与真进行逻辑或的结果,结果为真(1)
第二次运算,e等于真与假进行逻辑或的结果,结果为真(1)
第三次运算,e等于假与假进行逻辑或的结果,结果为假(0)
③、条件运算符(?),又称三目运算符
条件运算符的运算逻辑是
条件?语句1:语句2;
解释:条件是否为真,如果条件为真,执行语句1,如果条件不为真,执行语句2
on start
{
int a = 9;
int b;
a > 10? b = 5:b = 15;
write("b的值是%d",b);
a = 11;
a > 10? b = 5:b = 15;
write("b的值是%d",b);
}
我定义了两个整形变量a和b,并为a赋值为9,b默认为0
接着使用条件运算符,判断一下a>10这个条件是否成立,如果条件成立,那么执行b=5,如果不成立,执行b=15
通过write的结果,可以看到,b的结果是15,即代码执行了不成立的那一部分(b=15)
随后,我通过赋值语句修改了a的值为11,并再次执行这串代码
可以看到,此时b的值变为了5,这是因为,a(11)大于10,条件为真,执行了语句1(b=5)
④、逻辑非运算符(!)
逻辑非的运算逻辑非常简单,非1的结果为0,非0的结果就为1
on start
{
int a = 0;
int b;
b = !a;
write("b的值是%d",b);
a = 1;
b = !a;
write("b的值是%d",b);
}
首先定义了a=0(即a为假)
随后让b等于非a,即b等于非假
打印,看到b的值变为了真(1)
随后,我修改了a的值为真(1)
再次执行b等于非a,即b等于非真
打印,看到b的值变为了假(0)
3、位运算符
在讲解位运算符之前,我们首先需要知道,位运算是按照二进制的方式进行计算的。
我们首先需要先了解2进制(bin)、8进制(oct)、10进制(dec)和16进制(hex)
①、进制间的转换
学习进制转换涉及的知识较多,光是二进制与十进制的互相转换,都分成了正整数、负整数和小数部分,较为复杂,负数部分还涉及到计算机原码、反码与补码的知识,这里就不再展开讲了,有兴趣的读者可以自己百度搜索这部分知识,本篇仅进行简要描述,说明正整数间是如何转换的
二进制转十进制(权值法)
二进制数字,无特殊约束时,一般规定从左往右依次是高位到低位
如 二进制数字(1100 1011),从左往右,高位在左,低位在右。
从最低位开始,即从最右侧开始,最低位(以下称为第0位)
第0位的权值为2^0(2的0次幂),即1
第1位的权值为2^1(2的1次幂),即2
第2位的权值为2^2(2的2次幂),即4
第3位的权值为2^3(2的3次幂),即8
到此就不再继续展开了,细心的朋友应该能够发现,我们将每一位的序号用x来记录,那么每一位的权值,就是2的x次幂。
每一位的这个数字,我称之为这一位的系数。
如第0位的系数是1,第1位的系数是1,第二位的系数是0...
那么,这个二进制数字的十进制结果就为(每一位的系数*每一位的权值,再相加得到总和)
例如,上述数字(1100 1011)的十进制算法为
第0位系数 1 乘以0位的权值1,得1
第1位系数 1 乘以1位的权值2,得2
第2位的系数 0 乘以2位的权值4,得0
第3位的系数 1 乘以3位的权值8,得8
第4位的系数 0 乘以4位的权值16,得0
第5位的系数 0 乘以5位的权值32,得0
第6位的系数 1 乘以6位的权值64,得64
第7位的系数 1 乘以7位的权值128,得128
再将上述的结果相加,1+2+8+64+128 = 203,即这个二进制数字的十进制表示为203
打开计算器,查看结果,验证无误。
十进制转二进制(整除取余法)
十进制转二进制,不断地对2进行整除,记录余数
直到最后整除的结果为0时,停止运算(整除的结果为0,非余数为0)
我们以十进制数字167为例,用以说明十进制转二进制的方法
167 / 2 = 83...1 (83余1)
83 / 2 = 41...1
41 / 2 = 20 ...1
20 / 2 = 10 ...0
10 / 2 = 5...0
5 / 2 = 2...1
2 / 2 = 1...0
1 / 2 = 0...1
我们从下往上依次将每一步的余数取出
得到1010 0111,这串数字即是167的二进制
二进制转八进制
直接说原理,八进制本质上是由每三位二进制表示一位八进制数字来组成的数字
例如
二进制数字
11010101,我们将这个数字,从低位开始,向高位,每3位2进制数字,单独分开,不够分的在前面添0
比如,从后往前挨个取三位
后三位得 101
中间三位得010
前面只剩两位了,不够数,往前添0,得011
我们按照刚刚十进制的权值法,把这三个位置依次计算
得到,后三位为1*2^2 = 4,0*2^1 = 0,1*2^0 = 1,相加得5
中间三位为 0*2^2 = 0,1*2^1 = 2, 0*2^0 = 0,相加得2
前三位为 0*2^2 = 0,1*2^1 = 2,1*2^0 = 1,相加得3
则,这个二进制数字(11010101)的八进制为(325)oct
打开计算器,看到OCT处为325,计算无误
八进制转二进制
八进制转二进制,将8进制数字的每一个位置提出
比如八进制数字(365)oct,转换为二进制
提出低位5, 5= 1+0+4,按照权值法,1 = 1*2^0, 0 = 0*2^1, 4 = 1*2^2,所以2等于(101)bin
提出中位6, 6 = 0+2+4,按照权值法,0 = 0*2^0, 2 = 1*2^1, 4 = 1*2^2,所以6等于(110)bin
提出高位3, 3 = 1+2+0,按照权值法,1 = 1*2^0, 2 = 1*2^1, 0 = 0*2^2,所以6等于(011)bin
将以上数字按照低位到高位放置拼接后,得到
(011 110 101)bin,高位是空的0,可以省略,即(1111 0101)
二进制转十六进制
二进制转十六进制的算法与二进制转八进制是相同的,区别仅在于,八进制是以三位二进制表示一个八进制,十六进制以四位二进制表示一个十六进制 (注,16进制的表示范围是0 1 2 3 4 5 6 7 8 9 A B C D E F)
以二进制(10 1011 0110)为例,转换十六进制
从低位开始,将每四位提出,不够的在前面添0
低四位 0110 按照权值法,依次计算。这里等于0+4+2+0 = 6
中间四位 1011 这里等于8+0+2+1 = 11,十六进制使用B表示11,这里为B
高位不足,在前方添两个0, 0010 这里等于0+0+2+0 = 2
即,这个二进制数字的十六进制为2B6,计算机查看无误
十六进制转二进制
采用的方法同八进制转二进制,不再深入演示了。不懂的读者可以多次阅读上述算法或者查阅其他资料或者评论区联系我。
十六进制数0xFA 转换为二进制
F = 15 = 8+4+2+1 = 1111(bin)
A = 10 = 8 +0 +2 +0 = 1010(bin)
即 0xFA的二进制为(1111 1010)bin,打开计算器查看无误
十进制、八进制、十六进制的转换
采取先转换为二进制再根据规律转换为所需要的进制的办法。
当我们对这四种进制的转换关系较为熟悉之后,完全可以做到看到一个数字就能说出他的其他进制的能力,各位读者可以多加练习。嫌麻烦的读者也可以使用计算器直接进行转换。
②、按位取反运算(~)
前面进制讲解铺垫了那么久,终于可以到达位运算的逻辑了。
按位取反运算非常简单,首先一个数字,我们先将其转换为2进制的表示
比如 十进制的36,转换为二进制是0010 0100
我们对其按位取反,其实就是在每一个位上都对这个数字取非
即,0010 0100按位取反就de
1101 1011 这个数字为十进制的219,这就是按位取反后的结果
③、按位与(&),按位异或(^),按位或(|)
基于所有的位运算都需要以二进制形式展现,以下就以二进制进行举例了。
二进制数字A(1100 0110)与二进制数字B(1011 0111)进行按位与
就是将每一位上的数字都按照逻辑与的形式进行计算,最后再将结果列出来
1100 0110
&
1011 0111
=
1000 0110
即A和B进行按位与的结果就是1000 0110
按位异或(^)
异或运算符的运算规则是,相同为0,不同为1
1100 0110
^
1011 0111
=
0111 0001
即A和B进行按位异或的结果是0111 0001
按位或(|)
跟按位与相同,就是按照每一位的值进行逻辑或运算
1100 0110
|
1011 0111
=
1111 0111
即A和B进行按位异或的结果是1111 0111
④、左移(<<)、右移(>>)运算符
左移和右移运算,是将二进制数字整体向左或向右移动的运算,右移时,移动后给高位添0,左移时,移动后给低位添0。被移出的部分直接丢弃。
举例:
二进制数字(1101 0111)进行左移2位
1101 0111 左移2位 就是整体往左移动两个位置,前面的1101的11直接移出去了,丢弃,后面的0111移动后空出来了两个位置,往后添两个0
按照上述逻辑,
1101 0111
<<2
=
0101 1100
右移同样,整体往右移动两个位置,末尾0111的11,直接移出去了,丢弃。前面的1101移动后前面空出来两个位置,往前添2个0
1101 0111
>>2
=
0011 0101
⑤、左移后赋值(<<=),右移后赋值(>>=)
此运算符的逻辑同上面讲的加等于、减等于那些运算符,区别仅在算法不同。
例如
a <<= 2 的意思就是
a = a << 2
b >>= 5就是
b = b >> 5
⑥、按位与后赋值(&=),按位或后赋值(|=),按位异或后赋值(^=)
此运算符的逻辑同上面讲的加等于、减等于那些运算符,区别仅在算法不同。
a &= 2 的意思就是
a = a & 2
b ^= 5就是
b = b ^ 5
c |= 3就是
c = c ^3;