on key 'a'{
int i = 0;
i++;
write("i = %d",i);
write("----------------");
}
on key 'b'{
int i ;
i = 0;
i++;
write("i = %d",i);
write("----------------");
}
对于局部变量,在按a触发事件中在定义时对局部变量进行了显式的初始化,而在按b触发事件中除了在定义时对局部变量进行了显式的初始化,还额外用指令进行了显式的初始化。
在主函数中先对a事件调用三次,后对b事件触发2次,下图即为打印结果。
观测结果显然,在第二次触发按a触发事件时,其局部变量i的初值并不是0,而是上一次调用退出时的值1,可见具有标准C静态变量的特性。因此建议在编写程序时,建议定义局部变量之后,再单独进行显示的初始化。
(2)对于全局变量
variables
{
int i = 0;
}
on key 'a'{
write("i的第一次值 = %d",i);
i++;
write("i = %d",i);
write("----------------");
}
on key 'b'{
i=0;
write("i的第一次值 = %d",i);
i++;
write("i = %d",i);
write("----------------");
}
对于全局变量,在按a触发事件中并未做显示的初始化,只做了运算;而在按b触发事件中用指令进行了显式的初始化。
在主函数中第一次触发按a触发事件,第二次触发按b触发事件,然后对a事件和b事件交替触发。下图即为打印结果。
观测结果显然,在第二次触发按a触发事件时,其局部变量i的初值并不是0,而是上一次调用退出时的值1,可见具有标准C静态变量的特性。因此建议在编写程序时,建议定义局部变量之后,再单独进行显示的初始化。
------------------------------------------------------验证完毕----------------------------------------------------------
二、简单变量 1.整型整数就是没有小数部分的数字,如3、201、-3412和0。根据数值的大小不同,CAPL提供了以下几种整型,如下图所示。
2.字符CAPL未将char类型(长度1B)归类至整型中,这 是因为在CANoe中提供了byte类型。如果数据是具体数值则应使用 byte,而对于字符,则应用char(字符串使用char数组)。char类型 和byte类型之间可以直接转换,例如:
on key 'a'{
byte data1 = 100;
char ch1 = 'd';
ch1 = 0x62;
data1 = 's';
write("ch1 = %d",ch1);
write("data1 = %d",data1);
}
三、复合类型
1.结构
CAPL中可以简单地按照C语言的方法来声明结构(struct),但结构名在程序中必须是唯一的。
用户可以在类型定义时直接声明结构类型的变量,在这种情况下,类型的名称可以省略,也可以直接使用结构的名字来引用类型。
on key 'a'{
struct {
int Ma;
int English;
int His;
}sunbo;
sunbo.English =100;
sunbo.Ma = 99;
sunbo.His = 98;
write("Math = %d English = %d History = %d",sunbo.Ma,sunbo.English,sunbo.His);
}
on key 'b'{
struct Sc {
int Ma;
int English;
int His;
};
struct Sc sunbo ={ 100, 99, 98 };
write("Math = %d English = %d History = %d",sunbo.Ma,sunbo.English,sunbo.His);
}
使 用 “.” 操 作 符 可 以 访 问 结 构 中 的 成 员 ,例 如 , myScores.Chinese = 100。另外,结构可以作为参数传给函数,但不能作为函数的返回值。
2.枚举
枚举(enum)类型的声明也与C语言中的语法完全一致,但需要 注意的是,枚举的成员名必须唯一,否则将有可能代替隐藏数据库中同名的报文和信号。
声明枚举的同时对成员进行赋值
on key 'b'{
enum colors { red = 1,green = 2,Blue = 3 };
write("Red = %d green = %d blue = %d",red,green,Blue);
}
输出结果:
如果没有在声明枚举的同时对成员进行赋值,编译器将按照成员声明的顺序对成员进行初始化。即第一个成员被初始化为0,往后依次加1。
on key 'a'{
enum { Apple,Peer,Banana} fruit = Apple;
write("a = %d b = %d c = %d",Apple,Peer,Banana);
}
输出结果:
3.数组CAPL支持直接用字符串初始化字符数组的行为。
on key 'a'{
int a[3] = {1,2,3};
char b[13] = "Hello Word!";//"Hello Word"为字符串形式,此行验证了用字符串初始化字符数组
long c[] = {777,888,999};//无效,在CAPL中必须显示定义数组的长度,
}
可 以 通 过 内 建 函 数elCount(数组名)来获得数组成员的个数。如果数组的索引超出范
围,即小于零或大于等于数组长度,CAPL将会在数组下标前提示错误。
on key 'b'{
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int b[3] = {1,2,3} ;
int c = elcount(a) ;//c = 3
int d = a[4]; //超过边界范围错误
}
四、特殊类型
1.报文
使用关键字message来声明一个报文变量,当使用message声明报文变量时,默认变量为CAN报文变量。当有数据库支撑的时候,一个完整的声明应该包括message ID或者message name。结合database的例子,使用ID 0xA或者报文名来声明一条数据库中的EngineData报文。
以标识符“x”结尾的ID表示这是一个扩展帧ID,例如,100x。而“*”则表明这条报文在声明时还不含有CAN ID。
切记,使用这种方式声明报文时,一定要指定ID后才能将msg发送出去。CAPL提供了一系列的选择器(Selector)以保证用户能够按照自己的意图去修改CAN message的属性,下图列出了CAN报文属性及相关信息。
2.定时器CAPL 提 供 了 两 种 定 时 器 变 量 : timer 基 于 秒 的 时 间 单 位 ; msTimer基于毫秒的时间单位
Timer CLK1;//建立名称为CKL1的以秒为单位计时器 msTimer CLK2;//建立名称为CLK2的以毫秒为单位的计时器四、常见运算 五、流程控制 1.if格式、if与else格式
variables
{
int a;
}
on start{
a=0;
if (a<50){
a++;
write("a = %d",a);}
else
{a--;
write("a = %d",a);}
}
2.switch语句
执行switch语句时,将变量逐个与case后的常量进行比较,若与其中一个相等,则执行该常量下的语句,若不与任何一个常量相等, 则执行default后面的语句。
on start {
int a,b=10;
a=10;
switch (a) {
case(2):
a++;
write("a1 = %d",a);
break;
case(10):
a--;
write("a2 = %d",a);
break;
case(3):
a--;
write("a3 = %d",a);
break;
default:
a++;
write("a4 = %d",a);
break;
}
}
以上case内必须加入“break;”否则switch将执行正确条件下的所有语句,不再判断。



