两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解

马肤

温馨提示:这篇文章已超过449天没有更新,请注意相关的内容是否还可用!

本文为初学者介绍了CAPL语法基础,内容详尽,涵盖了两万字的知识要点。文章旨在帮助初学者快速入门,掌握CAPL语言的基本语法结构。通过阅读本文,读者可以了解到CAPL的基本概念、语法规则、语句结构以及常见应用。本文简洁明了,易于理解,是初学者学习CAPL语言的优质参考资料。
  • 🍅 我是蚂蚁小兵,专注于车载诊断领域,尤其擅长于对CANoe工具的使用


  • 🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】


  • 🍅 玩转CANoe,博客目录大全,点击跳转👉

    📘前言

    • 🍅 本章内容,面向CAPL初学者,超过两万字,超全超详细。

    • 🍅 本节内容大量引用,翻译下面的Vector 官方文档:capl_programming ,资料我放在下方公众号网盘了,有需自取!


      两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第1张

      目录

      • 📘前言
      • 📙1 CAPL 简介
      • 📙2 CAPL 语法基础
        • 🍅2.1 CAPL和C语言的主要不同点
        • 🍅2.1 CAPL和C语言中等价的函数
        • 🍅2.2 注释
        • 🍅2.3 变量的命名规范
        • 🍅2.4 区分大小写
        • 🍅2.5 CAPL 关键字
        • 🍅2.6 CAPL 支持的数据类型
        • 🍅2.7 变量声明
        • 🍅2.8 数据类型转换
        • 🍅2.9 常量
          • 整形
          • 浮点数
          • 字符
          • 字符串
          • 宏定义
          • 🍅 2.10 数组
          • 🍅 2.11 枚举类型
          • 🍅 2.12 结构体数据类型
          • 🍅 2.13 message
          • 🍅 2.14 定时器
          • 🍅 2.15 运算符
            • 2.15.1 算数运算
            • 2.15.2 赋值运算符
            • 2.15.3 布尔运算符
            • 2.15.4 比较运算符
            • 2.15.5 位运算符
            • 2.15.6 三目运算符
            • 2.15.7 其它运算符
            • 2.15.8 不支持运算符
            • 2.15.9 运算符优先级
            • 🍅 2.16 控制语句
              • 2.16.1 if 语句
              • 2.16.2 if else 语句
              • 2.16.3 Switch 语句
              • 2.16.4 While 循环语句
              • 2.16.5 do...while 循环语句
              • 2.16.6 for 循环语句
              • 2.16.7 break 语句
              • 2.16.8 continue 语句
              • 2.16.9 return 语句
              • 🍅 2.17 函数
                • 2.17.1 函数重载
                • 2.17.2 函数传参
                • 2.17.3 函数返回值
                • 🍅 2.18 test case
                • 🍅 2.19 CAPL 文件类型
                  • 2.19.1 根据文件后缀分为.can 和 .cin
                  • 2.19.2 创建不同的节点类型,就会有不同类型的.can/.cin文件
                  • 🍅 2.20 CAPL 文件的编码方式
                  • 🍅 2.21 CAPL 的事件结构
                    • 2.21.1 sytem ,系统事件
                    • 2.21.2 值(信号/变量)变化事件
                    • 2.21.3 报文接收事件
                    • 2.21.4 事件中的this 关键字
                    • 🍅 2.22 CAPL Browser 的设置
                      • 2.22.1 配色方案:
                      • 2.22.2 必须的工具栏:
                      • 🌎总结

                        两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第2张


                        📙1 CAPL 简介

                        • CAPL(发音为“kapple”),是 Communication Access Programming Language 的缩写。CAPL是基于C语言开发的,专门用于CANalyzer和CANoe工具环境,但是CAPL简化了C语言,移除了复杂的指针概念,和一些不常用的关键字等,也融入了一些C++的概念,比如函数重载等。就学习难度而言 CAPL

                        • CANalyzer或CANoe工具本身无需CAPL程序,就足以执行简单的测量和分析。采用CAPL程序,大大扩展了CAN通信的测量和分析。

                          如果没有CAPL,该工具无法执行的是涉及计时的分析。CAPL可以使分析更加高效

                        • CAPL 脚本是基于事件驱动的,和常规语言不同,CAPL没有 main()函数,没有程序入口,任何事件都有可能触发CAPL脚本的执行,比如,按键事件,定时器事件,执行测试等;如果没有事件发生,那么CAPL程序是“闲置的”。

                          两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第3张

                        • 任何语言都需要编译之后才能运行,我们编写CAPL 的IDE叫做 CAPL Browser ,是CNAoe 整个开发环境的一部分组件;因为CAPL Browser的整体结构基于事件的概念,并且是专门组织的围绕不同的事件类,软件开发过程比传统的组织要简单得多C程序。关于CAPL的事件结构更详细的解读,参考后面章节博客内容。

                          两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第4张


                          📙2 CAPL 语法基础

                          🍅2.1 CAPL和C语言的主要不同点

                          • 下图可以看出,C语言支持很多概念,CAPL都舍弃掉了,或者只取其一小部分支持,让CAPL语言更加简便和易懂
                          • 比如CAPL是基础事件驱动的,所以不需要main()函数入口
                          • 持指针操作,宏定义,头文件都不在支持
                          • 下图有点老,博主基于CANoe 11版本,枚举和结构体类型都是支持的。
                          • 在c语言中,使用函数之前,必须要进行声明,而CAPL是不需要的。

                            两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第5张


                            Note:

                            1,在CAPL中,默认所有的局部变量都是静态的,在C语言中,需要用关键字static 修饰的变量才是静态的。这一点新手在写脚本要特别注意 点击,了解 CAPL脚本中关于 局部变量 容易忽略的一点

                            2,void 在CAPL中只支持函数返回值类型,表示函数没有返回值

                            3,CAPL中使用了一些标准的C函数。这些函数通常是数学函数或字符串函数(例如,abs(),strncpy())已经在CAPL内部预定义了。

                            4,CAPL没有完整的ANSI C标准库,但它有CAPL特有的库,称为CAPL dll。dll编程需要有一定的编程经验

                            5,字符串数据类型在CAPL中不支持;但是,您可以使用字符数组(例如,char temp[6]= " Hello "😉。


                            🍅2.1 CAPL和C语言中等价的函数

                            • 对于C程序员来说,了解一些等价的函数是很有帮助的。下面是一个类似的简明列表函数,但有关CAPL函数如何使用的更多详细信息,请参阅CAPL函数参考手册。

                              两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第6张


                              🍅2.2 注释

                              • CAPL 的注释方式和大多数语言都一样,都是通过 // 或者 /**/ 来实现的,下面四种注释方法都是合法的。
                              • CAPL Brower中注释代码的默认快捷键 选中你要注释的代码,先按住组合键 Ctrl + K ,然后在按组合键Ctrl +C ; 解除注释是 先按住组合键 Ctrl + K ,然后在按组合键Ctrl +U ;
                                1. /* This is a comment.*/ 
                                2. /* This comment is spread 
                                 over two lines.*/
                                3. /* 
                                 You can do this, too. 
                                 */ 
                                4. // CAPL also accepts the C++ comment.
                                

                                🍅2.3 变量的命名规范

                                • 变量名、函数名和数组名可以由字母和数字和下划线组成,但是首字母不能是数字

                                • 下面的命名都是合法的:

                                  sum

                                  number_of_units

                                  J5x7

                                  _sysflag

                                • 下面的命名都是不合法的:

                                  int // because it is a reserved keyword

                                  sum$value // the $ is not a recognized character

                                  3Times // because a variable name cannot begin with a number

                                  number of units // because spaces are not allowed


                                  🍅2.4 区分大小写

                                  • 在使用CAPL编写时,一定要记住,对于用户定义的变量,小写字母和大写字母是不同的变量

                                  • 下面三个变量是三个不同的变量

                                    input_1

                                    Input_1

                                    INPUT_1

                                  • 但是CAPL支持的关键字是不区分大小写的,比如 INT a; 和int a;是一样的。


                                    🍅2.5 CAPL 关键字

                                    • 关键字不能用来命名变量或函数。CAPL使用C编程中保留的关键字语言。但是,CAPL不支持一些常见的C关键字。

                                      下面是保留关键字的列表,包括CAPL支持的和不支持的关键字

                                    • 本图较老,emum和struct现在是支持的。

                                      两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第7张


                                      🍅2.6 CAPL 支持的数据类型

                                      • 下表列出了支持的部分数据类型,不全,不过足以介绍CAPL支持的基本数据类型,以及所占的字节数,还有是是有符号数等等。message 和timer等是CAPL独有的数据类型,这里不描述

                                        两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第8张


                                        🍅2.7 变量声明

                                        • CAPL 变量有局部变量和全局变量,在CAPL 中Variables中定义的是全局变量

                                          两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第9张

                                        • 数据类型float和double都是占8个字节,它们指定符合IEEE的64位浮点数标准,它们彼此兼容。
                                        • 变量的初始化在声明期间是可选的,定义的时候如果没有初始化,

                                          整形数据则默认是0;

                                          char 型默认是null ;

                                          message 类型默认的数据段是0;

                                          定时器timer ,不需要初始化

                                        • 下面的变量声明是合法的
                                          char letter_a = “a”; 
                                          int number_days_in_year = 365; 
                                          message wake-up xxx; // 后面再说
                                          timer one_second; // 定时器必须全局变量 后面再说
                                          int j, k = 2; // 如果变量不初始化,默认j = 0 
                                          double x = 33.7; 
                                          char p;
                                          

                                          🍅2.8 数据类型转换

                                          • CAPL支持类型转换,隐形和显性都可以

                                            -下面 第一个赋值语句使用隐形转换,即将1.6和1.7添加到结果3.3,但是sum是整形,所以自动截断,结果就是3

                                            -下面 第二个赋值语句使用显性转换,即1+1 =2 ,最后结果就是2

                                            int sum; 
                                            sum = 1.6 + 1.7; 
                                            sum = (int) 1.6 + (int) 1.7;
                                            

                                            🍅2.9 常量

                                            • 初始化一个变量意味着给它赋一个初始值或开始值。在CAPL中,这可以在同一行中完成变量声明。当值在声明期间赋值时,它们被视为常量

                                              整形

                                              • 整形可以是十进制和十六进制
                                                int value = 20; 
                                                int value2 = 0x14; 
                                                

                                                浮点数

                                                • 浮点数可以是十进制数,或者科学计数法,以下都是合法的
                                                  float value = 0.23; 
                                                  float value2 = 23E-2;
                                                  2.1 
                                                  2.1e0 
                                                  3.1415 
                                                  0.00034 
                                                  22e+3 
                                                  1E-6
                                                  

                                                  字符

                                                  • 字符常量 是用单引号,括起来的一个字符
                                                    char value = ‘B’; 
                                                    char value2 = ‘8’; 
                                                    char value3 = ‘?’;
                                                    
                                                    • CAPL支持使用ASCII字符集。上面的三个字符赋值可以用十六进制分别
                                                      char value = 0x42; 
                                                      char value2 = 0x38; 
                                                      char value3 = 0x3F;
                                                      

                                                      字符串

                                                      • 字符串常量由一系列由双引号括起来的一个或多个连续字符组成。
                                                      • 字符串存储在char类型的数据元素数组中。最后一个元素包含空字符
                                                        char value[30] = “Here’s a string in C and CAPL”; 
                                                        char value2[19] = “spaces are allowed”; 
                                                        char value3[31] = “with a tab escape sequence \t”;
                                                        
                                                        ,即用于指示字符串的结束。
                                                      • 要确保字符串数组定义时的大小总是字符串长度 + 1,因为结束符\0也占用一个字符
                                                        char value3[31] ;
                                                        value3 = “with a tab escape sequence ”;
                                                        
                                                        • 如果已经定义过了一个字符串数组,不可以直接给它赋值的,下面代码时不允许的
                                                          char value3[31] ;
                                                          strncpy(value3,  “with a tab escape sequence ”, elcount(value3)); 
                                                          
                                                          • 可行的一种方法,是通过CAPL自带的字符串操作函数实现

                                                            宏定义

                                                            #define TRUE 1 
                                                            #define FALSE 0
                                                            
                                                            • 在C语言中,下面代码是合法的,但是在CAPL中是不可以的。

                                                              🍅 2.10 数组


                                                              2.16.2 if else 语句

                                                              • 数组时同一种数据类型的集合,元素必须小于等于指定的大小

                                                              • 下面时26个字母,但是我们必须定义27个大小,因为数据类型时char , 结束符\0要占一个字节

                                                                char alphabet[27] = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;

                                                                我们通过下表索引可以获取数组中的数值,比如 alphabet[0] 就是 ‘A’

                                                              • 整形或者浮点型数组,大小可以和声明的元素数量一致,比如

                                                                int sample_data[4] = { 100, 300, 500, 600 };

                                                              • 如果,定义时,数组没有完全舒适化,其余的用默认值0填充

                                                                int sample_data[10] = { 100, 300, 500, 600 };

                                                              • 也可以定义二维数组

                                                                int M[4][5] = {

                                                                { 10, 5, -3, 17, 82 },

                                                                { 9, 0, 0, 8, -7 },

                                                                { 32, 20, 1, 0, 14 },

                                                                { 0, 0, 8, 7, 6 }

                                                                };

                                                              • 要确定数组中元素的数量,可以使用elCount()函数,如下面的例子所示:

                                                                nt i, j;

                                                                for ( j = 0; j

                                                                for ( i = 0; i Red, Green, Blue }; // 默认 从 0开始,每个元素+1 enum State { State_Off = -1, State_On = 1 }; //可以指定值 enum Colors { Red, Green, Blue }; // 默认 从 0开始,每个元素+1 write("Colors red : %d",Red); write("Colors Green : %d",Green); } //输出结果 Program / Model Colors red : 0 Program / Model Colors Green : 1 enum Colors { Red, Green, Blue }; // 默认 从 0开始,每个元素+1 enum Colors color; //定义枚举变量 color = Green; # color = (enum Colors)1;//也可以通过 强制类型转换,将整形数据转为枚举类型赋值 write("colors is %s and value is : %d",color.Name(),color); //输出结果 Program / Model colors is Green and value is : 1 } struct Data { int age; long hight; char name[50]; }; struct Data data = {12,150,"张三"}; //结构体定义时,初始化 write("姓名:%s ; 年龄:%d ; 身高:%d",data.name,data.age,data.hight); //输出结果 姓名:张三 ; 年龄:12 ; 身高:150 } struct Data { int age; long hight; char name[50]; }; struct Data data; data.age = 15; data.hight = 150; strncpy(data.name,"张三",elcount(data.name)); write("姓名:%s ; 年龄:%d ; 身高:%d",data.name,data.age,data.hight); //输出结果 姓名:张三 ; 年龄:15 ; 身高:150 } message 100 msg; msg.DLC = 1; msg.BYTE(0) = 0xff; output(msg); } msTimer myTimer; // creates a millisecond timer message 100 msg; // creates message 100 } on key ‘a’ // when the ‘a’ key is pressed { setTimer(myTimer,20); // set myTimer to 20 ms } on timer myTimer // when myTimer expires (after 20 ms) { output(msg); // output the message } message 0x555 msg1 = {dlc = 1}; mstimer timer1; // define timer1 } on start { setTimer(timer1, 100); // initialize timer to run for 100 msec } on timer timer1 { msg1.byte(0) = msg1.byte(0) + 1; // increment the data output(msg1); // output message setTimer(timer1, 100); // reset the timer } ulli如果定时器还没被触发,你可以通过setTimer() 函数,重置该定时器/lili如果定时器还没被触发,你也可以通过cancelTimer() 函数来取消该定时器 hr / h3🍅 2.15 运算符/h3 ulliCAPL的运算符大多数和C都一样,也进行了一些删减/liliCAPL的运算符包括下面几大类/pp算数运算/pp赋值运算/pp关系运算/pp布尔运算/pp位运算/pp混合运算 h42.15.1 算数运算/h4 ulli p下图是CAPL支持的算数运算符,包括加减乘除,取模等,完全和C语言一样/ppimg src="https://img-blog.csdnimg.cn/0ce75d0b3c0a48099d903bbd11e89e26.png" alt="在这里插入图片描述" //p /lili p下面一些算数运算符的使用/p pre class="brush:python;toolbar:false"int x,y,z; y = 8; z = 4; x = y + z; // Addition. Result = 12 x = y - z; // Subtraction. Result = 4 x = y * z; // Multiplication. Result = 32 x = y / z; // Division. Result = 2 x = z % y; // Modulo. Result = 4 x = y++; // Increment. Result = 9 x = z--; // Decrement. Result = 3 /pre h42.15.2 赋值运算符/h4 ulli下图是CAPL支持的赋值运算符,完全和C语言一样。 pimg src="https://img-blog.csdnimg.cn/1401335741a441cf9b0657ae507e3096.png" alt="在这里插入图片描述" //p ulli下面一些赋值运算符的简单使用 pre class="brush:python;toolbar:false"int y, z; y = 8; z = 4; // each statement below is independent from the others y += z; // Addition. Result: y = 12 y -= z; // Subtraction. Result: y = 4 y *= z; // Multiplication. Result: y = 32 y /= z; // Division. Result: y = 2 y %= z; // Modulo. Result: y = 0 y = 1; // Left-shift. Result: y = 16 y &= z; // AND. Result: y = 0 (binary arithmetic) y |= z; // OR. Result: y = 12 (binary arithmetic) y ^= z; // XOR. Result: y = 12 (binary arithmetic) /pre h42.15.3 布尔运算符/h4 ulli下图是CAPL支持的布尔运算符,完全和C语言一样。 pimg src="https://img-blog.csdnimg.cn/0cf68cc258394f53b28db660562590d2.png" alt="在这里插入图片描述" //p ulli下面一些布尔运算符的简单使用 pre class="brush:python;toolbar:false"byte y, z; y = 0x00; z = 0x01; if (!y) // test result is TRUE if (!z) // test result is FALSE if (y == 0 && z == 1) // test result is TRUE if (y == 1 || z == 1) // test result is TRUE /pre h42.15.4 比较运算符/h4 ulli p下图是CAPL支持的比较运算符,完全和C语言一样。/ppimg src="https://img-blog.csdnimg.cn/cd980960160b4d9498794a625607ba99.png" alt="在这里插入图片描述" //p /lili p下面一些比较运算符的简单使用/p pre class="brush:python;toolbar:false"int y,z; y = 8; z = 4; if (y == z) // test result is FALSE if (y != z) // test result is TRUE if (y = z) // test result is FALSE if (y = z) // test result is TRUE /pre h42.15.5 位运算符/h4 ulli下图是CAPL支持的位运算符,完全和C语言一样。 pimg src="https://img-blog.csdnimg.cn/a1f2b6f21f10449eb09d98985a8a0a10.png" alt="在这里插入图片描述" //p ulli下面一些位运算符的简单使用 pre class="brush:python;toolbar:false"byte x, y, z; y = 0x0AA; // y = 1010 1010 z = 0x05A; // z = 0101 1010 x = y & z; // AND result = 0000 1010 x = y | z; // OR result = 1111 1010 x = y ^ z; // XOR result = 1111 0000 x = y 60) { //花括号内的语句都会执行 write("line 1"); write("line 2"); }

                                                                  int speed ;
                                                                  speed = 40;
                                                                  if (speed > 60)
                                                                  {
                                                                    write("line 1");
                                                                  }
                                                                  else if(speed > 80)
                                                                  {
                                                                    write("line 2");
                                                                  }
                                                                  else
                                                                  {
                                                                    write("line 3");
                                                                  }
                                                                
                                                                • 如果下面表达式为真或者非0,则执行语句块1,否则执行语句块2

                                                                  if (expression) statement_1

                                                                  else statement_2

                                                                • if else 的典型用法

                                                                  2.16.3 Switch 语句

                                                                  switch (expression) 
                                                                  { 
                                                                   case value1: statement1; statement2; … break; 
                                                                   case value2: statement1; statement2; … break; 
                                                                   . . . 
                                                                   default: statement1; statement2; … break; 
                                                                  }
                                                                  
                                                                  • 下面是switch 语句的伪代码表示:
                                                                  • switch (expression) 中的 expression应该是个 整形变量或者字符变量或者枚举类型变量
                                                                    • case value1: 每个case分支中的value应该是个 整形或者字符常量,注意case value后面有个冒号
                                                                    • default ,当所有分支都不能匹配的时候,会执行default内的代码
                                                                    • 当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。
                                                                    • float value1, value2, result; 
                                                                      char operator; 
                                                                      ... 
                                                                      switch ( operator ) 
                                                                      { 
                                                                       case ‘+’: result = value1 + value2; 
                                                                       break; 
                                                                       case ‘-’: result = value1 – value2; 
                                                                       break;
                                                                       case ‘*’: result = value1 * value2; 
                                                                       break; 
                                                                       case ‘/’: if ( value2 == 0) write (“Division by zero!”); 
                                                                       else result = value1 / value2; 
                                                                       break; 
                                                                       default: write (“Unknown operator.”); 
                                                                       break; 
                                                                      } 
                                                                      
                                                                    • 不是每一个 case 都需要包含 break。如果 case 语句不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。

                                                                      2.16.4 While 循环语句

                                                                      while(condition)
                                                                      {
                                                                         statement(s);
                                                                      }
                                                                      
                                                                      • Capl 语言中 while 循环的语法:
                                                                      • 在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。
                                                                        • 2.16.5 do…while 循环语句

                                                                        • condition 可以是任意的表达式,当为任意非零值时都为 true。当条件为 true 时执行循环。 当条件为 false 时,退出循环.
                                                                             int a = 10;
                                                                             /* while 循环执行 */
                                                                             while( a  
                                                                          
                                                                          do
                                                                          {
                                                                             statement(s);
                                                                          }while( condition );
                                                                          
                                                                          • Capl 语言中 do…while 循环的语法:
                                                                          • 在这里,statement(s) 可以是一个单独的语句,也可以是几个语句组成的代码块。
                                                                            • condition 可以是任意的表达式,当为任意非零值时都为 true。当条件为 true 时执行循环。 当条件为 false 时,退出循环.
                                                                            • 不像 for 和 while 循环,它们是在循环头部测试循环条件。在 C 语言中,do…while 循环是在循环的尾部检查它的条件。
                                                                            • do…while 循环与 while 循环类似,但是 do…while 循环会确保至少执行一次循环。
                                                                            • 2.16.6 for 循环语句

                                                                            • 还要注意while 表达式最后是分号结尾的
                                                                                 int a = 10;
                                                                                 /* do 循环执行,在条件被测试之前至少执行一次 */
                                                                                 do
                                                                                 {
                                                                                     write("a 的值: %d\n", a);
                                                                                     a = a + 1;
                                                                                 }while( a  
                                                                              
                                                                              for ( init; condition; increment )
                                                                              {
                                                                                 statement(s);
                                                                              }
                                                                              
                                                                              • Capl 语言中 for 循环的语法:

                                                                                2.16.7 break 语句

                                                                                • 下面是 for 循环的控制流:

                                                                                  1,init 会首先被执行,且只会执行一次。您也可以不在这里写任何语句,只要有一个分号出现即可。CAPL语句不允许在这个位置定义新的变量,而C语言是可以的

                                                                                  2,接下来,会判断 condition。如果为真,则执行循环主体。如果为假,则不执行循环主体,且控制流会跳转到紧接着 for 循环的下一条语句。切记不要让condition永远为真,否则会是个死循环的

                                                                                  3,在执行完 for 循环主体后,控制流会跳回上面的 increment 语句。该语句允许您更新循环控制变量。该语句可以留空,只要在条件后有一个分号出现即可。

                                                                                  4,条件再次被判断。如果为真,则执行循环,这个过程会不断重复(循环主体,然后增加步值,再然后重新判断条件)。在条件变为假时,for 循环终止。

                                                                                • 下面三个代码都是可以的

                                                                                     int a ;
                                                                                     /* for 循环执行 */
                                                                                     for(  a = 10; a  
                                                                                  
                                                                                     int a ;
                                                                                  	a =10;
                                                                                     /* for 循环执行 */
                                                                                     for(  ; a  
                                                                                  
                                                                                     int a ;
                                                                                  	a =10;
                                                                                     /* for 循环执行 */
                                                                                     for(  ; a  
                                                                                  
                                                                                     int a = 10;
                                                                                     /* while 循环执行 */
                                                                                     while( a  15)
                                                                                        {
                                                                                           /* 使用 break 语句终止循环 */
                                                                                            break;
                                                                                        }
                                                                                     }
                                                                                  
                                                                                  • Capl 语言中 break 语句有以下两种用法:

                                                                                    当 break 语句出现在一个循环内时,循环会立即终止,且程序流将继续执行紧接着循环的下一条语句。

                                                                                    它可用于终止 switch 语句中的一个 case。

                                                                                  • 如果您使用的是嵌套循环(即一个循环内嵌套另一个循环),break 语句会停止执行最内层的循环,然后开始执行该块之后的下一行代码。

                                                                                  • 下图是break语句在循环语句中的使用,和退出循环的过程

                                                                                    两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第10张

                                                                                    2.16.8 continue 语句

                                                                                    2.16.9 return 语句

                                                                                    • continue 语句有点像 break 语句。但它不是强制终止,continue 会跳过当前循环中的代码,强迫开始下一次循环。

                                                                                    • 对于 for 循环,continue 语句执行后自增语句仍然会执行。对于 while 和 do…while 循环,continue 语句重新执行条件判断语句

                                                                                    • -下图是continue 语句在循环语句中的使用

                                                                                      两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第11张

                                                                                         int a = 10;
                                                                                         /* do 循环执行 */
                                                                                         do
                                                                                         {
                                                                                            if( a == 15)
                                                                                            {
                                                                                               /* 跳过迭代 */
                                                                                               a = a + 1;
                                                                                               continue;
                                                                                            }
                                                                                            write("a 的值: %d\n", a);
                                                                                            a++;
                                                                                           
                                                                                         }while( a  
                                                                                      
                                                                                      on key 'c'
                                                                                      {
                                                                                         int a = 10;
                                                                                         /* while 循环执行 */
                                                                                         while( a  15)
                                                                                            {
                                                                                               /* 使用 break 语句终止循环 */
                                                                                                return;
                                                                                            }
                                                                                         }
                                                                                      }
                                                                                      
                                                                                      • CAPL脚本中,不带参数的return也可以退出循环语句
                                                                                      • 但是更多的使用return,是用来在函数中,返回一个值或者值的表达式
                                                                                        • long Power(int x, int y) 
                                                                                          { 
                                                                                           int i; 
                                                                                           long result; 
                                                                                           result = 1; 
                                                                                           for (i = 1; i 
                                                                                            printme(5.7);
                                                                                            printme(3, "Feet"); 
                                                                                          }
                                                                                          void printme (double num) 
                                                                                          { 
                                                                                           write("Floating point %f", num); 
                                                                                          } 
                                                                                          void printme (int num, char units[]) 
                                                                                          { 
                                                                                           write("%d %s", num, units); 
                                                                                          }
                                                                                          
                                                                                            int a = 10 ,b =20 ;
                                                                                            write("a=%d ; b=%d",a,b);
                                                                                            swip_1(a,b);
                                                                                            write("a=%d ; b=%d",a,b);
                                                                                          }
                                                                                          void swip_1(int a, int b)
                                                                                          {
                                                                                          	int temp;
                                                                                            temp = a;
                                                                                          	a = b;
                                                                                          	b = temp;
                                                                                            write("inter>>>a=%d ; b=%d",a,b);
                                                                                          }
                                                                                          
                                                                                        • 注意:CAPL中所有的事件处理都不返回值
                                                                                          on key 'b'
                                                                                          {
                                                                                            int a = 10 ,b =20 ;
                                                                                             write("a=%d ; b=%d",a,b);
                                                                                            swip_2(a,b);
                                                                                             write("a=%d ; b=%d",a,b);
                                                                                          }
                                                                                          void swip_2(int& a, int& b)
                                                                                          {
                                                                                          	int temp;
                                                                                            temp = a;
                                                                                          	a = b;
                                                                                          	b = temp;
                                                                                             write("inter>>>>a=%d ; b=%d",a,b);
                                                                                          }
                                                                                          

                                                                                          输出结果:

                                                                                          a=10 ; b=20

                                                                                          inter>>>>a=20 ; b=10

                                                                                          a=10 ; b=20


                                                                                          • 引用传参:将变量的引用传入函数,效果和指针相同,在函数内更改,也会对函数外的参数进行更改
                                                                                            void  test_2(char para2[])
                                                                                            {
                                                                                               snprintf(para2,elCount(para2),"hello Vector!");
                                                                                            }
                                                                                            On key 'c' 
                                                                                            {  
                                                                                              char input[100] = "hello world!";
                                                                                              write("***********%s",input); 
                                                                                              test_2(input);    
                                                                                              write("***********%s",input); 
                                                                                            }
                                                                                            

                                                                                            输出结果:

                                                                                            a=10 ; b=20

                                                                                            inter>>>>a=20 ; b=10

                                                                                            a=20 ; b=10


                                                                                            • 数组/结构体传参 : 数组/结构体等连续内存的变量传参都是 地址传参,函数内部的操作都会对函数外产生影响。

                                                                                              2.17.3 函数返回值

                                                                                              输出结果:

                                                                                              ***********hello world!

                                                                                              ***********hello Vector!


                                                                                              long  test_1(long para1,long para2)
                                                                                              {  
                                                                                                return para1 + para2 ;
                                                                                              }
                                                                                              On key 'a' 
                                                                                              {
                                                                                                write("***********%d",test_1(3,5)); 
                                                                                              }
                                                                                              

                                                                                              原则上来说,CAPL 的函数只支持 数值类型 的返回值

                                                                                              有同学问,数组和结构体类型可以作为返回值吗?答案是不可以的,如果你想把函数中的数组传出去,请给它传参传入一个数组,上面也说了函数内对数组的更改是会影响要函数外的,这样就把函数 “return” 出去了

                                                                                              🍅 2.18 test case


                                                                                              testcase NewTestCase()
                                                                                              {
                                                                                               // 测试方法的代码块
                                                                                              }
                                                                                              
                                                                                              
                                                                                              		
                                                                                              		
                                                                                              			TC_10449595
                                                                                              			0x245
                                                                                              			
                                                                                              
                                                                                              

                                                                                              testcase 是CAPL语法独有的一种语法模块,有点像函数,可以传递各种参数,也是需要有程序调用它才会执行

                                                                                              常见的调用testcase 的方法有两种 ,一种是XML TestModule ,另一种是CAPL TestModule

                                                                                              从零开始学习CANoe(七)—— XML 测试节点

                                                                                              从零开始学习CANoe(六)—— CAPL 测试节点

                                                                                              • 下面是XML TestModule 方式,由xml文件调用testcase ,xml编程进一步的学习可以参考:Capl编程xml标签语法

                                                                                                test.xml 部分代码,测试启动时,会依次调用CAPL中的 testcase

                                                                                                testcase test_1()
                                                                                                {
                                                                                                  write("test_1 running");
                                                                                                }
                                                                                                testcase test_2(char case_id[],int message_id)
                                                                                                {
                                                                                                  write("test_2 running ,case_id : %s",case_id);
                                                                                                }
                                                                                                

                                                                                                test.can 中的 testcase,负责测试方法的具体实现。

                                                                                                🍅 2.19 CAPL 文件类型

                                                                                                • CAPL TestModule 类型中的 testcase 是通过 MainTest 来调用的。

                                                                                                  两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第12张


                                                                                                  2.19.1 根据文件后缀分为.can 和 .cin

                                                                                                  2.19.2 创建不同的节点类型,就会有不同类型的.can/.cin文件

                                                                                                  类似于C语言的.c和.h文件 ,一般情况我们在.can文件写 test case,在 .cin 文件写函数和定义变量,然后在.can的includes 模块中把.cin文件引用进来。

                                                                                                  两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第13张

                                                                                                  特别说明:

                                                                                                  其实 .can 和.cin文件 的内部结构基本一致,都可以定义变量,事件,函数等,功能基本一样

                                                                                                  和C语言不同的是 在.can和.cin文件中,使用函数,不需要提前声明,任何地方都可以定义,任何地方都可以使用,注意我说的任何

                                                                                                  比如:在.cin 文件中定义的函数和变量,在.can文件中可以直接使用,这好理解,因为是.can文件 include了 .cin文件 ;但是 在.can 文件中定义的函数和变量,在cin文件中也是可以直接使用的。

                                                                                                  🍅 2.20 CAPL 文件的编码方式

                                                                                                  • 如下图,虽然都是.can文件,但是 一个节点类型是 Test node ,一个节点类型是Simulation node,节点类型不同

                                                                                                    两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第14张

                                                                                                    文件的类型不同,在创建节点类型的时候就决定了,虽然都是.can文件 ,但是支持的CAPL语法也会有所差别。

                                                                                                    Test node:侧重于测试测量,CAPL内置了很多的测试函数,可以在Test node类型的.can文件中使用,但是不可以在simulation node 类型的can文件中使用,函数中包含testxxxx的都是如此 ,比如常见的testwaitfortimeout()是最常见的延时等待函数,但是它不能在 simulation node 类型的can文件中使用。

                                                                                                    两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第15张


                                                                                                    @!Encoding:936

                                                                                                    .can/cin文件的编码方式,这在很多编程语言中都有,在CAPL中开头部分定义

                                                                                                    /

                                                                                                    🍅 2.21 CAPL 的事件结构

                                                                                                    / : 支持中文字符串,比如write(“调用顺序 —— 1”)

                                                                                                    /*@!Encoding:ASCII/ :不支持中文,老外写代码用的都是这个

                                                                                                    其它的暂时没用到,就不说了,有兴趣自己gg吧

                                                                                                    两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第16张


                                                                                                  • testcase,是由其它功能模块调用而执行的,如上边所说xml test module
                                                                                                  • 这里再次强调下,CAPL脚本是基于事件驱动的,也就是说CAPL脚本中每一行代码都是某个对应的事件发生了才去执行的。

                                                                                                    • Functions :函数也肯定是被调用才被执行的
                                                                                                    • Test Function ,这个本文我没说,也是被xml/.net 文件调用而执行的,和testcse同一类的
                                                                                                    • includes : 非事件,引用.cin和dll文件的功能块
                                                                                                    • 2.21.1 sytem ,系统事件

                                                                                                    • Variables: 非事件,定义全局变量,注意是相对本文件的全局变量,非CANoe环境的全局变量,在CANoe中使用全局变量有系统变量和环境变量

                                                                                                      两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第17张

                                                                                                      在这里插入代码片
                                                                                                      

                                                                                                      on timer 和 on key 就不再赘述了,前面也已经写过了,圈起来的是几个测量事件,启动和停止CANoe 软件的时候会分别调用

                                                                                                      CAPL 脚本中 定时器 ,按键触发事件的使用

                                                                                                    • 执行顺序如下:
                                                                                                    • 两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第18张

                                                                                                      • on preStart过程仅用于初始化变量、在Write Window中显示消息以及从文件中读取数据
                                                                                                      • on preStart
                                                                                                        {
                                                                                                          write("调用顺序 —— 1");
                                                                                                        }
                                                                                                        on Start
                                                                                                        {
                                                                                                          write("调用顺序 —— 2");
                                                                                                        }
                                                                                                        on preStop
                                                                                                        {
                                                                                                           write("调用顺序 —— 3");
                                                                                                        }
                                                                                                        on stopMeasurement
                                                                                                        {
                                                                                                          write("调用顺序 —— 4");
                                                                                                        }
                                                                                                        
                                                                                                      • on preStop函数可用于执行一些在测量停止实际生效之前必须执行的最终操作。
                                                                                                      • on start 和 on stopMeasurement 事件不能在 test node 类型的.can文件中使用
                                                                                                      • 两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第19张

                                                                                                        注意:

                                                                                                        • 可以使用 on preStart ,但是不能用来对变量赋值等操作
                                                                                                        • 如果测量测试已经完成,那么 on preStop 中的代码也不会被执行。
                                                                                                        • 2.21.2 值(信号/变量)变化事件

                                                                                                        • 所以 系统的测数量事件相关代码最好集中在simulated node .can文件中完成

                                                                                                          两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第20张

                                                                                                          2.21.3 报文接收事件

                                                                                                          比如信号值,系统变量,环境变量 ,这些元素值发生变化,会触发这些事件

                                                                                                          CAPL 脚本中对信号,系统变量,环境变量的 事件响应

                                                                                                          两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第21张

                                                                                                          On message CAN1.0x4c
                                                                                                          {
                                                                                                            write("***0x%x",this.id);
                                                                                                          }
                                                                                                          

                                                                                                          总线上收到指定的报文后,会触发 on message 事件,同时message 是一个object 对象,它由很多属性,可以通过 this .xxx获取和设置

                                                                                                          CAPL脚本 对CAN 报文的事件响应

                                                                                                          2.21.4 事件中的this 关键字

                                                                                                          两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第22张


                                                                                                          on message 100 {
                                                                                                          byte byte_0;
                                                                                                          byte_0 = this.byte(0);
                                                                                                          ...
                                                                                                          }
                                                                                                          

                                                                                                          1)在接收CAN对象或环境变量的事件过程中,对象的数据结构由关键字this指定。例如,您可以通过以下方式访问刚刚接收到的消息100的第一个数据字节

                                                                                                          on envVar Switch {
                                                                                                          int val;
                                                                                                          val = getvalue(this);
                                                                                                          ...
                                                                                                          }
                                                                                                          

                                                                                                          2):类似地,您可以通过以下方法读取刚刚更改过的整数环境变量Switch的新值

                                                                                                          On key 'a'
                                                                                                          {
                                                                                                            write("pressed %c",this);
                                                                                                          }
                                                                                                          

                                                                                                          3):类似地,键盘按键事件

                                                                                                          🍅 2.22 CAPL Browser 的设置


                                                                                                          2.22.1 配色方案:

                                                                                                          2.22.2 必须的工具栏:

                                                                                                          两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第23张

                                                                                                          两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第24张

                                                                                                        • Output :开发的时候,编译可以实时发现脚本的错误信息
                                                                                                        • 在使用CAPL 写脚本时,我认为这三个工具栏应该要打开的,可以便捷你的开发速度

                                                                                                          • Symbols: 在CANoe中加载的DBC,CDD文件的元素,定义的系统变量等都可以直接这里找的到,随用随查看
                                                                                                          • 🌎总结

                                                                                                          • CALP Functions: C语言在使用库函数时,需要在文件开头include相应的库文件,但是CAPL不需要那么麻烦,它内置了很多自己专用的函数,也吸收了一些C/C++的函数,但是不需要include任何文件,可以在CAPL中直接使用。有时候记不全函数的名称,可以直接搜索查看。

                                                                                                            两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第25张

                                                                                                            两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第26张

                                                                                                            两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第27张

                                                                                                            两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第28张

                                                                                                            • 🚩要有最朴素的生活,最遥远的梦想,即使明天天寒地冻,路遥马亡!


                                                                                                            • 🚩如果这篇博客对你有帮助,请 “点赞” “评论”“收藏”一键三连 哦!码字不易,大家的支持就是我坚持下去的动力。

                                                                                                              两万字的CAPL语法基础,一篇文章带你入门,CAPL语法入门指南,两万字基础详解 第29张


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码