CRAB快速开发平台学习教程《二》:基础入门篇

上一节,我们学习了《环境搭建篇》,本篇将学习基础语法,默认所有的工具已经准备就绪中。

本文建议大家使用SublimeText 3.0,不仅界面清爽美观,而且功能强大好用。

 

一 、全世界通用的“Hello World”。

打开Demo\EX01_HelloWorld.carb,将会显示如下图一样的程序代码。

sublime

上图中的代码,各部分解释如下:

1)用 /* */包起来的,是注释部分,注释是给人看的,机器编译的时候,会忽略这部分代码

2)import system; 这是让编译器导入库文件(注:库文件也是Crab格式的源代码文件)

3)main {} 这是主程序,开发者写的程序代码,将从这里开始执行。

4)Print(‘Hello World’); 这一句,是在日志控制台上打印一句’Hello World’;

 

我们先不管代码是怎么样写的,而是先运行一下,看看效果。

打开CrabStudio。

1)点击“连接”按钮,如果连接成功,下面窗口会出现连接后的设备信息。

2)点击“打开”,选择Demo\EX01_HelloWorld.carb这个文件。

3)点击“编译”,将会出现如下图所示。

4)点击“下载”,将编译后的程序下载到开发板上。

CrabStudio
5)点击“运行”,下方窗口将会切换到“Term”页面,并显示”Hello World“

P2

这表示,我们的第一个程序,已经完美运行成功。

接下来,我们开始学习CRAB语言的语法部分。

二、基本语法

1)注释

注释是用于解释代码。编译器会忽略注释的条目。和大多数C系(C/C#/C++)语言相似,在 CRAB 程序中,多行注释以 /* 开始,并以字符 */ 终止,如下所示:

/*========================================This is a simple DEMO program, it send

 

a greeting of “Hello World” to

the computer.

 

这是一个最简单的DEMO程序,它向你发送一个

“Hello World” 的问候。

========================================*/

单行注释是用 ‘//’ 符号表示,常用于行尾。例如:

Print(‘Hello World’);  //发送“Hello World”问候。

 

2)标识符

  • 标识符是用来识别变量名、函数、类、接口或任何其它用户定义的项目。在 CRAB 中,标识符的命名必须遵循如下基本规则:
  • 标识符必须以字母开头,后面可以跟一系列的字母、数字( 0 – 9 )或下划线( _ )。标识符中的第一个字符不能是数字。
  • 标识符必须不包含任何嵌入的空格或符号,比如 ? – +! @ # % ^ & * ( ) [ ] { } . ; : ” ‘ / \。但是,可以使用下划线( _ )。
  • 标识符不区分大小写。大写字母和小写字母都认为是相同的字母。
  • 标识符可以使用中文名称,比如:名称,我是中文变量
  • 标识符不能是 CRAB 关键字。(注:请参阅文章最后的关键字表格)

 

 
保留关键字
andasbooleanbreakcasecatchclass
constcontinuecrabdefaultdebugdodouble
elseenumeventexternfalsefinallyfor
foreachhelperifimportininterfaceis
longnewnotnullobjectorout
overrideparamsprivateprotectedpublicpropertyrefer
returnrepeatsizeofstaticstringstructswitch
thisthrowtruetrytypeofuntilvar
virtualvoidwhilexor   

 

3)值类型

值类型变量可以直接分配给一个值。值类型直接包含数据。比如 int、char、float,它们分别存储数字、字母、浮点数。当您声明一个 int 类型时,系统分配内存来存储值。

下表列出了 CRAB 中可用的值类型:

类型描述范围默认值
boolean布尔值True 或 FalseFalse
byte8 位无符号整数0 到 2550
char8位 单个字符0到255‘\0’
tiny8 位有符号整数-127到1270
short16 位有符号整数类型-32,768 到 32,7670
ushort16 位无符号整数类型0 到 65,5350
int32 位有符号整数类型-2,147,483,648 到 2,147,483,6470
uint32 位无符号整数类型0 到 4,294,967,2950L
long64 位有符号整数类型-923,372,036,854,775,808 到 9,223,372,036,854,775,8070.0
ulong64 位无符号整数类型0 到 18,446,744,073,709,551,6150.0
float32 位单精度浮点型-3.4 x 1038 到 + 3.4 x 10380
double64 位双精度浮点型(+/-)5.0 x 10-324 到 (+/-)1.7 x 103080
date32位日期型从0000-00-00到9999-12-310000-00-00
time32位时间型从00:00:00.000到23:59:59.99900:00:00
datetime64位日期时间型是date型和time型的合并体0000-00-00 00:00:00

 

4)引用类型

引用类型不包含存储在变量中的实际数据,但它们包含对变量的引用。换句话说,它们指的是一个内存位置。使用多个变量时,引用类型可以指向一个内存位置。如果内存位置的数据是由一个变量改变的,其他变量会自动反映这种值的变化。内置的 引用类型有:class、array 和 string。

三、变量

1)变量类型

一个变量只不过是一个供程序操作的存储区的名字。在 CRAB 中,每个变量都有一个特定的类型,类型决定了变量的内存大小和布局。范围内的值可以存储在内存中,可以对变量进行一系列操作。

我们已经讨论了各种数据类型。CRAB 中提供的基本的值类型大致可以分为以下几类:

 

类型举例
整数类型tiny、byte、short、ushort、int、uint、long、ulong
浮点型float 和 double
字符类型char
布尔类型true 或 false 值
日期时间型date, time, datetime

 

2)变量的定义

变量定义的语法:

<data_type> <variable_list>;

在这里,data_type 必须是一个有效的 CRAB 数据类型,可以是 char、int、float、double等等数据类型。variable_list 可以由一个或多个用逗号分隔的标识符名称组成。

一些有效的变量定义如下所示:

int i, j, k;char c, ch;

 

float f, salary;

double d;

您可以在变量定义时进行初始化:

int i = 100;

四、常量

1)整数常量

整数常量可以是十进制、二进制或十六进制的常量。前缀指定基数:0x 或 0X 或 $ 表示十六进制,0b或0B 表示二进制,没有前缀则表示十进制。

100     // 十进制0x20    // 十六进制

 

$0c     // 十六进制

0b0101  //二进制

十进制整数常量也可以有后缀(不分大小写)。

后缀名等值示例
K1,0001k = 1000
M1,000,0001m = 1000k
G1,000,000,0001g = 1000m
T1,000,000,000,0001t = 1000g
W10,0001w =10k
Y100,000,0001y = 10000w

 

2)浮点常量

一个浮点常量是由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。

例如:

3.14159       // 合法314159E-5    // 合法

 

510E          // 非法:不完全指数

210f          // 非法:没有小数或指数

.e55          // 非法:缺少整数或小数

3)日期时间常量

一个日期常量,前缀是”$”,接着由单引号 ‘ ‘ 或双引号 “”包括,其值由年,月和日组成,中间有分隔符 “-“,或 “/”,一般用 “-“分隔符。

例如:

$”2017-06-16″ //常用格式$”2008/08/08″ //兼容DOS格式

一个时间常量,前缀是”$”,接着由单引号 ‘ ‘ 或双引号 “”包括,其值由时,分,秒和毫秒组成,中间有分隔符 “:”和 “.”。秒和毫秒可以缺省不写。

例如:

$”20:08:16″      //常用格式$”20:08:16.250″ //包含毫秒格式

 

$”20:08″          //仅有时和分,秒缺省为0,毫秒也是为0

一个日期时间常量,它是日期常量和时间常量的合并体,中间以空格分隔,可以相互转换。

例如:

$”2017-06-16 20:08:16″      //常用格式$”2017-06-16 20:08:16.250″ //完整格式,包含毫秒格式

 

$”2017-06-16 20:08″          //仅有日期和时和分,其它缺省为0

 

4)字符与字符串

CRAB语言并不区分字符与字符串,这两者都统一识别为字符串。

字符串常量是括在单引号 ‘ ‘ 或双引号 “” 里,或是在引号外面使用转义符。字符串常量包含的字符,可以是:普通字符、转义序列。

例如:

“Hello World”         //常用格式’I am aleyn.wu’      //完整格式,包含毫秒格式

 

“I’m programer”      //当需要某个引号的时候,可以用另外的引号包括

“Want return”\r\n   //在引号外连接转义符和转义序列

 

5)特殊常量

以下三个常量,属于系统原生自带的:

类型举例
true布尔值,字面意思是:真,是
false布尔值,字面意思是:假,否
null空值,仅用于引用类型变量,或判断。

 

6)常量的定义

常量是使用 const 关键字来定义的 。定义一个常量的语法如下:

const <constant_name> = value;

常量的定义不需要指定常量类型,系统会自动识别常量类型。常量定义之后,也不占用内存,而且仅仅在编译期间有效。常量在定义的时候也可以使用常量表达式,也就是所有的未知数都必须是常量。

例如:

const  PI             = 3.14159;const  LED_ON        = 1;

 

const  KEY_PRESS     = 0x01000000;

const  KEY_PRESS_F1  = KEY_PRESS + 0x11;

 

五、 运算符

运算符是一种告诉编译器执行特定的数学或逻辑操作的符号。CRAB 有丰富的内置运算符,分类如下:

1)算术运算符

下表显示了 CRAB 支持的所有算术运算符。假设变量 A 的值为 10,变量 B 的值为 20,则:

运算符描述实例
+把两个操作数相加A + B 将得到 30
从第一个操作数中减去第二个操作数A – B 将得到 -10
*把两个操作数相乘A * B 将得到 200
/分子除以分母B / A 将得到 2
%取模运算符,整除后的余数B % A 将得到 0
++自增运算符,整数值增加 1A++ 将得到 11
自减运算符,整数值减少 1A– 将得到 9
#字符串连接符,专用于字符串操作“A:” # A将得到 “A:10”

 

2)关系运算符

下表显示了 C# 支持的所有关系运算符。假设变量 A 的值为 10,变量 B 的值为 20,则:

运算符描述实例
==检查两个操作数的值是否相等,如果相等则条件为真。(A == B) 为假。
!=<>检查两个操作数的值是否相等,如果不相等则条件为真。<> 与 != 相同的功能,主要是兼容其它语言格式(A != B) 为真。(A <> B) 为真。
>检查左操作数的值是否大于右操作数的值,如果是则条件为真。(A > B) 为假。
<检查左操作数的值是否小于右操作数的值,如果是则条件为真。(A < B) 为真。
>=检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。(A >= B) 为假。
<=检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。(A <= B) 为真。

3)逻辑运算符

下表显示了 CRAB 支持的所有逻辑运算符。假设变量 A 为布尔值 true,变量 B 为布尔值 false,则:

运算符描述实例
&&and称为逻辑与运算符。如果两个操作数都非零,则条件为真。and 和 $$ 是相同的功能,建议用 and 运算符,更直观。(A && B) 为false(A and B) 为false
||or称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。or 和 || 是相同的功能,建议用 or 运算符,更直观。(A || B) 为true(A or B) 为true
!not称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。not 和 ! 是相同的功能,建议用 not 运算符,更直观。!B 为truenot B 为true
^^xor称为逻辑异或运算符。如果两个操作数中其中一个为真,另一个为假,则条件为真。xor 和 ^^ 是相同的功能,建议用 xor 运算符,更直观。(A ^^ B) 为true(A xor B) 为true

 

4)位运算符

位运算符作用于位,并逐位执行操作。

下表列出了 CRAB 支持的位运算符。假设变量 A 的值为 60,变量 B 的值为 13,则:

运算符描述实例
&如果同时存在于两个操作数中,二进制 AND 运算符复制一位到结果中。(A & B) 将得到 12,即为 0000 1100
|如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。(A | B) 将得到 61,即为 0011 1101
^如果存在于其中一个操作数中但不同时存在于两个操作数中,二进制异或运算符复制一位到结果中。(A ^ B) 将得到 49,即为 0011 0001
~二进制补码运算符是一元运算符,具有”翻转”位效果,即0变成1,1变成0。(~A ) 将得到 -61,即为 1100 0011,一个有符号二进制数的补码形式。
<<二进制左移运算符。左操作数的值向左移动右操作数指定的位数。A << 2 将得到 240,即为 1111 0000
>>二进制右移运算符。左操作数的值向右移动右操作数指定的位数。A >> 2 将得到 15,即为 0000 1111

5)赋值运算符

下表列出了 CRAB 支持的赋值运算符:

运算符描述实例
=简单的赋值运算符,把右边操作数的值赋给左边操作数C = A + B 将把 A + B 的值赋给 C
+=加且赋值运算符,把右边操作数加上左边操作数的结果赋值给左边操作数C += A 相当于 C = C + A
-=减且赋值运算符,把左边操作数减去右边操作数的结果赋值给左边操作数C -= A 相当于 C = C – A
*=乘且赋值运算符,把右边操作数乘以左边操作数的结果赋值给左边操作数C *= A 相当于 C = C * A
/=除且赋值运算符,把左边操作数除以右边操作数的结果赋值给左边操作数C /= A 相当于 C = C / A
%=求模且赋值运算符,求两个操作数的模赋值给左边操作数C %= A 相当于 C = C % A
<<=左移且赋值运算符C <<= 2 等同于 C = C << 2
>>=右移且赋值运算符C >>= 2 等同于 C = C >> 2
&=按位与且赋值运算符C &= 2 等同于 C = C & 2
^=按位异或且赋值运算符C ^= 2 等同于 C = C ^ 2
|=按位或且赋值运算符C |= 2 等同于 C = C | 2
#=字符串连接且赋值运算符C #= A 相当于 C = C # A

 

6)其他运算符

下表列出了 C# 支持的其他一些重要的运算符。

运算符描述实例
sizeof()返回数据类型的大小。sizeof(int),将返回 4.
typeof()返回 class 的类型。typeof(StreamReader);
? :条件表达式如果条件为true ? 则为 X : 否则为 Y
Is判断对象是否为某一类型。If( Ford is Car) // 检查 Ford 是否是 Car 类的一个对象。
in判断变量是否在一个列表里If (I in [1,2,3]) //检查I 是否为1,2,3中任意一个

 

六、条件判断

判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。

1)if语句

一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。语法如下:

if (boolean_expression){

 

/* 如果布尔表达式为true将执行的语句 */

}

2)if…else…语句

一个 if 语句 后可跟一个可选的 else 语句,else 语句在布尔表达式为假时执行。

if (boolean_expression){

 

/* 如果布尔表达式为true将执行的语句 */

}

else

{

/* 如果布尔表达式为false将执行的语句 */

}

3)if语句嵌套

if语句可以嵌套使用,格式如下:

if (boolean_expression1){

 

}

else if (boolean_expression2)

{

}

else if …

{

}

else

{

}

3)if (.. in..) 语句

if..in..语句,相当于把几个类似的情况,都集中一起判断,既能方便直观,又能节省代码空间。

此语句仅可单独使用,不可以嵌套使用,也不可以使用else语句。语法如下:

if (var_name in [case list]){

 

/* 如果布尔表达式为true将执行的语句 */

}

范例:

if (I in [1, 2, 3..5]){

 

/* 如果布尔表达式为true将执行的语句 */

}

以上语句相当以下语句的效果

if ((I == 1) || (I == 2) || ((I>=3) && (I <=5))){

 

/* 如果布尔表达式为true将执行的语句 */

}

 

4)switch语句

一个 switch 语句允许测试一个变量等于多个值时的情况。语法如下:

switch(expression){

 

//单值的情况

case constant-expression1 :

{

statement(s);

break;  //可选项

}

//多值的情况

case constant-expression2, constant-expression3 :

{

statement(s);

break;  //可选项

}

//范围的情况

case constant-expression4..constant-expression6 :

{

statement(s);

break;  //可选项

}

 

/* 您可以有任意数量的 case 语句 */

 

default : //可选项

{

statement(s);

break;  //可选项

}

}

 

  • switch 语句中的 expression 必须是一个值类型或枚举类型。
  • 一个 switch 中可以有任意数量的 case 语句。
  • case 的 constant-expression 必须与 switch 中的变量具有相同的数据类型,且必须是常量类型。
  • case 可以是这三种情况:单值, 多值, 范围, 但这三种情况可以任何组合。
  • 当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 break 语句为止,或是遇到下一个case开头为止。
  • break不是必须的,当前的case情况结束的时候,将会自动跳转到switch结束位置。
  • 如果在case情况里任意位置加入break,则运行到此位置的时候,会立刻跳转到结束位置。
  • default是以上case情况都不符合的时候才会运行的。它不是必须的。
  • CRAB 不支持从一个 case 标签显式贯穿到另一个 case 标签。

范例:

switch(I){

 

//单值的情况

case 1 :

{

statement(s);

}

//多值的情况

case 2, 3, 4 :

{

statement(s);

}

//范围的情况

case 5..8 :

{

statement(s);

}

//多种情况混合使用

case 9, 10, 12, 20..30 :

{

statement(s);

}

default :

{

statement(s);

}

}

七、循环控制

1)for语句

一个 for 循环是一个允许您编写一个执行特定次数的循环的重复控制结构。语法如下:

for ( init; condition; increment ){

 

statement(s);

}

下面是 for 循环的控制流:

  • init 会首先被执行,且只会执行一次。这一步允许您声明并初始化任何循环控制变量。您也可以不在这里写任何语句,只要有一个分号出现即可。
  • 接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。
  • 在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。
  • 条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,for 循环终止。

 

范例:

for ( I = 0; I < 10; I++ ){

 

print(I);

}

2)while语句

只要给定的条件为真,while 循环语句会重复执行一个目标语句。语法如下:

while(condition){

 

statement(s);

}

condition 必须是布尔表达式。当条件为真时执行循环。当条件为假时,程序流将继续执行紧接着循环的下一条语句。所以在这里,while 循环的关键点是循环可能一次都不会执行。当条件被测试且结果为假时,会跳过循环主体,直接执行紧接着 while 循环的下一条语句。

范例:

I = 0;while(I < 10)  //当 I<10时,继续上面的循环

 

{

statement(s);

I++;

}

3)do..while语句

do…while 语句与 while 语句类似,不同的地方在于,while语句是在循环头部测试循环条件,而do…while 语句在循环的尾部检查它的条件。语法如下:

do{

 

statement(s);

}

while(condition);

do…while 语句会确保里面的语块至少会执行一次循环。

范例:

I = 0;do

 

{

statement(s);

I++;

}

while(I < 10);  //当 I<10时,继续上面的循环

4)repeat..until语句

repeat..until语句与 do..while 语句类似, 不同的地方在于,do..while语句是在测试循环条件为true时继续循环,而repeat..until 语句在测试循环条件为true时结束循环。语法如下:

repeat{

 

statement(s);

}

until(condition);

同样的,repeat..until 语句也会确保里面的语块至少会执行一次循环。

范例:

repeat{

 

dosomething();

}

until error; //当error为true时,结束循环,否则继续上面的循环。

 

5)循环控制语句

循环控制语句将会更改执行的正常序列。CRAB 提供了break和continue两个控制语句:

break 语句有以下两种用法:

  • 当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。
  • 它可用于终止 switch 语句中的一个 case。
  • 如果您使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会停止执行最内层的循环,然后开始执行该块之后的下一行代码。

 

continue 语句

  • continue 会跳过当前循环中的代码,强迫开始下一次循环。
  • 对于 for 循环,continue 语句会导致执行条件测试和循环增量部分。
  • 对于 while和..while和repeat..until 循环,continue 语句会导致程序控制回到条件测试上。

 

 

八、函数

1)常规函数

常规函数是指用户自己定义的,把一些相关的语句组织在一起,用来执行一个任务的语句块。

一个常规函数通常包括函数名称,参数,返回值,任务语句块,这四个定义内容。

2)事件函数

事件函数与普通函数很相似,不同的地方在于,一是事件函数不可以有参数,二是事件函数必须有事件标识ID,三是事件函数仅提供给系统调用,用户不能直接调用。详情请参阅事件部分。

3)属性读写函数

属性读写函数是附加在属性上用于对应读和写的特殊函数。属性读写函数的名称是固定的,其中,属性读函数为get,写函数为set。当用户对属性进行读或写的时候,将会触发和调用相对应的读或写函数。详情请参阅属性部分。

4)接口函数

接口函数的定义部分与普通函数差不多,但前面需要加上extern指示符,而且函数头后面不可以有执行的任何语句块。接口函数是用来与宿主程序交互与沟通的特殊函数。详情请参阅接口部分。

5)类成员函数

类成员函数与普通函数一样,都有函数头,参数,任务语句块,等等。不同的地方在于,类成员函数在类结构定义里面,在调用的时候,同样需要与类实例一起配套使用。详情请参阅类部分。

6)内嵌函数

CRAB语言有四个内嵌函数,分别是TypeOf,SizeOf,OpenEvent和CloseEvent函数。

  • TypeOf函数用于检测变量类型。
  • SizeOf函数用于检测变量大小。
  • OpenEvent函数用于打开全局事件驱动。
  • CloseEvent函数用于关闭全局事件驱动。

7)特殊函数

CRAB语言有两个特殊函数,分别是main函数与setup函数。

  • main函数是应用程序的主入口,它不可缺失。
  • main函数没有任何参数,也不能返回任何类型的参数。
  • 当main函数结束的时候,或是遇到return语句的时候,应用程序将结束它的生命周期。
  • setup函数是应用程序初始化函数,一般是由IDE自动生成,开发者不应自己编辑setup函数。
  • setup函数是可选项。如果有setup函数存在,则应用程序会先执行setup函数,然后再执行main函数。
  • setup函数和main函数一样,没有任何参数,也不能返回任何类型的参数。

九、常规函数

1)常规函数也是全局函数,只要定义了,后面任何地方都可以调用。语法如下:

<Access Specifier> <Return Type> <Method Name>(Parameter List){

 

Method Body

}

  • Access Specifier:访问修饰符,对于常规函数,此修饰符无效,所以可以忽略不写。
  • Return type:返回类型,一个函数可以返回一个值。返回类型是函数返回的值的数据类型。如果函数不返回任何值,则返回类型为 void。
  • Method name:函数名称,是一个唯一的标识符,大小写不敏感的。它不能与声明的其他标识符相同。
  • Parameter list:参数列表,使用圆括号括起来,该参数是用来传递和接收函数的数据。参数列表是指函数的参数类型、顺序和数量。参数是可选的,也就是说,一个函数可能不包含参数。
  • Method body:函数主体,包含了完成任务所需的指令集。

范例:

void MyFunc(int P1, int P2)  //这个位置,继续定义,并写函数主体。{

 

Method Body

}

2)常规函数可以先预定义,然后在后面的任意地方再继续写函数主体。

函数的预定义一般用于函数之间的相互调用,如果没有预定义,那前面定义的函数调用者,将无法找到后面才定义的另一个函数。

范例:

void MyFunc(int P1, int P2);  //函数的预定义必须在函数头的位置以;结束 

 

…  //这里可以是任意代码

 

void MyFunc(int P1, int P2)  //这个位置,继续定义,并写函数主体。

{

Method Body

}

3)参数的定义

常规函数可以有任意个参数,也可以没有参数。

参数的完整定义方式和变量的定义方式差不多,惟一不同的地方就是,参数可以指定为输出方式。

<out> <data_type> <param_name>
  • out是可选项,它指示在函数结束时,需要把该参数的值输出给函数调用者。
  • data_type 必须是一个有效的数据类型,可以是 char、int、float、double等等数据类型。
  • param_name是一个唯一的标识符,大小写不敏感的。它不能与它的函数名称相同,也不能与其它已声明的参数名称相同。
  • 参数与参数之间,需要用逗号来分隔。

范例:

void MyFunc(int P1, int P2, out int P3){

 

Method Body

}

4)返回类型与返回方式

一个函数可以返回一个值,返回的类型是函数返回的值的数据类型。如果函数不返回任何值,则返回类型为 void。

函数的返回方式,可以使用return 语句,后面带表达式,该表达式的运算结果必须与返回类型相同。

还可以使用result变量,每一个函数,都有一个默认自带的与返回类型相同的变量result,我们叫它返回值变量。在函数的任何地方,都可以使用result变量,而不会产生让函数立刻返回的效果。如果使用result变量,则在需要函数返回的时候,可以直接使用return语句,而不需要带一个表达式。

范例:

int Func1(int P1, int P2){

 

return P1 + P2;  //直接使用return语句返回计算值

}

int Func2(int P1, int P2)

{

result = P1 + P2;  //任何时候,都可以使用这个result变量

return ; //效果相当于 return result;

}

 

5)函数的调用

函数的调用是对指暂停和保存当前的任务位置,跳转到被调用的函数的位置,当执行完被调用的函数任务后,返回到当前任务的位置继续执行。函数调用的方式如下:

<Object Name Path><Call Method Name>(Parameter List);
  • Object Name Path是可选项,如果被调用的函数是接口函数或类成员函数,则在函数名前面需要加个接口名称或类名称或类实例名称。
  • Call Method Name 被调用的函数名称。该名称必须是前面已定义的函数。
  • Parameter List 需要传递给被调用的函数的参数列表,如果被调用的函数没有任何参数,则这里也不需要任何参数传入。
  • 如果对应的参数有out指示符,则传入的参数也必须加上out指示符,而且该参数必须是变量,不可以是表达式或是属性。
  • 如果被调用的函数有返回值,则它可以做为表达式的一份子,但它的返回值必须与表达式的类型相融合或兼容。
  • 如果被调用的函数有返回值,但调用者并没有相对应的方式去保存它的返回值,则返回值将会被遗弃。

范例:

MyFunc(1,2);       //调用MyFunc 

 

int OutVar;

MyFuncWithOut( 1, 2, out OutVar); //调用MyFuncWithOut,有输出参数

 

var R1;

R1 = Func1(1, 2);  //调用Func1,并获得函数返回值

R1 = 1 + Func2(3, 4) * 5; //调用Func2,并将返回值当做表达式一部分

 

Func1(1, 2); //调用Func1,并遗弃它的返回值。

 

//以下是错误行为。

R1 = MyFunc(1, 2); //MyFunc函数并没有返回值,此调用将会失败。

十、数组

1)声明数组

数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。

声明数组变量并不是声明 number0、number1、…、number99 一个个单独的变量,而是声明一个就像 numbers 这样的变量,然后使用 numbers[0]、numbers[1]、…、numbers[99] 来表示一个个单独的变量。数组中某个指定的元素是通过索引来访问的。

所有的数组都是由连续的内存位置组成的。最低的地址对应第一个元素,最高的地址对应最后一个元素。

在 CRAB 中声明一个数组,您可以使用下面的语法:

datatype[] arrayName;
  • datatype 用于指定被存储在数组中的元素的类型。
  • [ ] 指定数组的大小(或长度)。如果数组有多个维度,则此处可以相应的增加,CRAB语言最多支持3个维度的数组。
  • arrayName 指定数组的名称。与变量的定义一样,它是一个唯一的标识符,大小写不敏感的,但不可以与其它已定义的标识符相同名称。

范例:

int[]     MyArray;  //声明一个1维数组int[][]  MyRects;  //声明一个2维数组

 

2)初始化数组

声明一个数组不会在内存中初始化数组。当初始化数组变量时,您可以赋值给数组。

数组是一个引用类型,所以您需要使用 new 关键字来创建数组的实例。

范例:

int[]     MyArray;        //声明一个1维数组MyArray = new int[10];  //初始化数组,并为之申请10个元素

 

 

int[]     MyArray2 = new int[20];  //声明数组,同时初始化数组。

int[][]  MyArray3 = new int[20][30] //声明一个2维数组并初始化。

3)数组的访问与赋值

数组赋值需要通过使用索引号(数组下标)赋值给一个单独的数组元素。数组的索引号从0开始,最大值为初始化数组时所申请的元素个数。

范例:

int[]     MyArray;        //声明一个1维数组MyArray = new int[10];  //初始化数组,并为之申请10个元素

 

 

MyArray[0] = 123; //给数组的第一个元素(索引号为0)赋值。

 

int I;

for (I=0; I < 10; I++)

{

MyArray[I] = I * 100;  //利用循环来给数组的每一个元素赋值

}

数组的访问规则与赋值类似。不仅如此,数组的访问还可以通过foreach语句来逐项访问。

范例:

int[]     MyArray;        //声明一个1维数组MyArray = new int[10];  //初始化数组,并为之申请10个元素

 

 

int Item;

foreach (Item in MyArray)

{

Print(Item);  //逐项打印数组的每一个元素赋值

 

//注意,不可以改变Item的值,因为Item的改变,并不会改变MyArray的内容。

Item = 10; //错误

}

未初始化的数组,它的内存类型为null

范例:

int[]     MyArray;  //声明一个1维数组 

 

if (MyArray == null) { Print(“MyArray is null”); }

4)动态数组

数组也可以采用动态初始化的方式。

范例:

int[][]   MyArray;  //声明一个2维数组 

 

//初始化数组,其中第2维组申请3个元素组,第1维不固定。

MyArray = new int[3][];

 

//为第2维的每一个元素组单独申请1维元素,每一组个数各自不同。

MyArray[0] = new int[20];

MyArray[1] = new int[30];

MyArray[2] = new int[40];

 

//同样采用索引号方式访问,多维数组索引号顺序为,高维数在前,低维数在后。

MyArray[0][1]   = 1;

MyArray[1][12]  = 50;

MyArray[2][20]  = 100;

 

5)多维数组的另一种索引号访问方式

范例:

MyArray[0, 1]   = 1;    // 相当于MyArray[0][1]MyArray[1, 12]  = 50;  // 相当于MyArray[1][12]

 

MyArray[2, 20]  = 100; // 相当于MyArray[2][20]

 

 

6)函数的数组参数

在函数的参数定义里,数组参数仅需要声明数组类型和维数即可。

范例:

void MyArrayFunc(int[] ArrayParam){

 

int Sum = ArrayParam[0] + ArrayParam[1]; //直接使用数组参数。

Print(“Sum = ” # Sum);

}

十一、字符串

字符串是一个特殊的类,它在变量声明之后,无需申请内存即可直接使用。

字符串的最大长度是255个字符,最小长度是0。

1)字符串变量声明

范例:

string MyStr;  //声明一个字符串变量string MyStr2 = “Hello”; //声明一个字符串变量,并赋初值

 

2)字符串赋值

字符串在声明之后,还没赋值之前,他的值类型是null。

可以使用任何明文的方式给字符串赋值,也可以使用字符串表达式,或转义序列。

范例:

string MyStr;  //声明一个字符串变量 

 

MyStr = “Hello”; //明文字符串赋值方式。

MyStr = 10 + 20; //将普通的值类型表达式的结果赋值给字符串。

MyStr = ‘GoodBye’\r\n;  //在字符串后面加上转义序列。

 

3)字符串的连接

字符串可以通过 # 运算符来连接。任何值类型的变量或表达式,只要通过 # 连接符连接到字符串表达式,那将会自动转化为字符串表达式。

范例:

string MyStr;  //声明一个字符串变量。 

 

int R1 = 10 + 20;

MyStr = “Result = ” # R1; //通过字符串连接符来连接字符串。

 

date D1 = $”2017-06-20″

MyStr = “Today is ” # D1 # \r\n; //通过连接符来加入日期和转义序列。

3)函数定义里的字符串参数

如果函数参数里有字符串参数,则该参数将接受任何值类型参数和字符串,系统会自己根据类型自动转换。

范例:

void ShowStr(string Text);{

 

Print(Text);

}

 

string MyStr;  //声明一个字符串变量

MyStr = “Hello”; //明文字符串赋值方式。

 

ShowStr(MyStr);  //传入一个正规字符串参数

ShowStr(10+20);  //传入一个整型运算表达式

ShowStr(true);   //传入一个非字符串值

 

download.png 大脚蟹快速开发平台学习教程[二]基础入门篇(564.25 KB)

转载于:https://my.oschina.net/aleyn/blog/1551422

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值