wincc的c语言基础

更新时间:2024-01-05 10:29:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第二章 WinCC C语言基础

要使对象动态化,在WinCC中有多种不同的选项可用。其中包括变量连接.动态对话框和直接连接。通过它们可以实现复杂的动态。然而,随着要求的增加它们会有限制。对于用户来说,组态C动作、项目函数或动作可以有更广的范围。它们在WinCC 脚本语言C中创建。对于许多应用来说,不必具备非常全面的C语言知识。它足以为现有函数提供参数。然而,为了使用WinCC脚本语言C的全部功能,需要具备有关这种编辑语言的基本知识。本课程可以为用户提供这些知识。

本课程用来为不熟悉C语言的人员提供有关编辑语言C的常规应用的基本知识。具备C语言编辑经验的编程员可以学习C语言应用于WinCC时的特性。

2.1 C脚本的开发环境

对于C脚本的创建,WinCC提供两个不同的编辑器。一个是图形编辑器中的动作编辑器,用于在对象处创建C动作;另一个是全局脚本编辑器,用于创建项目函数和全局动作。脚本语言的语法与采用ANSI的标准C语言相一致。

在WinCC中编辑语言C的另一个应用领域是关于动态向导的创建。为此,可以使用一个单独的编辑器。

2.1.1 图形编辑器的动作编辑器

在图形编辑器中,可以通过C动作使对象属性动作化。同样,也可以使用C动作来响应对象事件。

1.动作编辑器

对于C动作的组态,可以使用动作编辑器。此编辑器可以在对象属性对话框中通过以下方法打开,即点击鼠标右键期望的属性或事件,然后从显示的弹出式菜单中选择C动作。已经存在的C动作在属性或事件处用绿色箭头标记。

在动作编辑器中,可以编写C动作。对于属性的C动作,必须定义触发器。对于事件的C动作,由于事件本身就是触发器所以不必再定义。完成的C动作必须进行编译,如果编译程序没有检测到错误,则可以通过单击确定退出动作编辑器

2.C动作的结构

通常,一个C动作相当与C中的一个函数。C动作由两种不同类型:为属性创建动作和为事件创建的动作。通常,属性的C动作用于根据不同的环境条件控制此属性的值(例如变量的值)。对于这种类型的C动作,必须定义触发器来控制其执行。事件的C动作来响应此事件。

3.属性的C动作

#include apdefap h

long-main(char* lpszPictureName.char* lpszObjectName.char*lpszPropertyName) {

/*1*/ long 1ReturnValue;

/*2*/ 1ReturnValue * GetTagSDword(*S32icourse-test-1*);

/*3*/ return 1ReturnValue; }

上述实例代码代表一个典型的属性的C动作。各部分的含义描述如下:

标题(灰色):灰色阴影显示的前三行构成C的动作标题。该标题自动生成并且不能更改。除返回类型(在实例代码中为long)之外,所有的函数标题完全相同。将三个参数传送给C动作。它们是画面名称(Lpsz PictureName),对象名(lpszObjectName)和属性名(lpszPropertyName).

变量声明(1):在可以编辑的第一段代码中声明使用的变量。在本实例代码中,指的是一个long型的变量。

数值计算(2):在本段中,执行属性值的计算。在实例代码中,只读入一个WinCC 变量的数值。

数值返回(3):将计算得出的属性值赋给属性。这通过return命令来完成

4.事件的C动作

#include apdefap.h*

void OnClicik(char* lpszPictureName.char* lpszObjectName.char* lpszPropertyName) {

/*1*/ long 1Value;

/*2*/ 1Value * GetTagSDWord(*s32i-course-tset-1”);

SetIeft (lpszPictureName,lpszobjectName,1value); }

上述实例代码代表一个典型的事件的C动作。各部分含义描述如下:

标题(灰色):灰色阴影显示的前三行构成C动作的标题。该标题自动生成并且不能更改。对于不同类型的事件,其参数标题也不同。将参数lpszPictureName(画面名称).lpszObjectName(对象名)和lpszPropertyName(属性名)传递给C动作。参数lpszPropertyName只包含与响应属性变化的事件相关的信息。可以传递附加的事件指定的参数。

变量声明(1):在可以编辑的第一代码段中声明使用的变量。在本实例代码中,指的是一个long型的变量。

事件处理(2):在本段中,执行响应事件的动作。在本实例代码中,读入一个WinCC变量的数值。该数值作为位置X分配给自己的对象。事件的C动作的返回值为void类型,也就是说不需要返回值

5.C动作的创建

创建C动作的步骤如下:

(1).打开图形编辑器,打开期望的WinCC画面,打开所期望对象的对象属性对话框

(2)通过鼠标R期望的属性或事件,然后从弹出式菜单中选择C动作来打开动作编辑器

(3)将显示动作编辑器,其中将显示函数的基本框架。此外,C动作的标题已经自动生成,该标题不能更改。

在C动作的标题的第一行内,包括文件apdefap.h.。通过该文件,向C动作预告所有项目的函数.标准函数以及内部函数。C动作标题的第二部分为函数标题。该函数标题提供有关C动作的返回值和可以在C动作中使用的传送参数的信息。C动作标题的第三部分开始是花括弧。此花括弧不能删除。在该开始大括弧和结束大括弧之间,编写C动作的实际代码。

(4)其他自动生成的代码部分包括两个注释块,若要使交叉索引编辑器可以访问C动作的内部信息,则需要这些块,要允许C动作中语句重新排列也需要这两个块。如果这些选项都不用。则可以删除这些注解。

第一个块用于定义C动作中使用的WinCC变量。在程序代码中必须使用定义变量名称而不是实际的变量名称

第二个注释块用于定义C中所使用的WinCC画面。在程序代码中也必须使用定义的画面名称而不是实际画面名称。

(5)编写执行期望计算的函数主题、动作等。有多种编辑辅助工具可供使用,其中一种辅助工具是变量选择对话框,此对话框如下所示的按钮可以打开。在显示的选择变量对话框中,选择WinCC变量然后单击确定来确认。于是在C动作中在当前光标位置处插入所选WinCC的变量名称。

(6)另一种辅助工具是动作编辑器左窗口中的函数选择。利用函数选择,可以在C动作中的当前光标位置处自动插入所有可用的项目函数、标准函数和内部函数。为此,通过鼠标D来选择其数据类型的列表。该函数可以在数值列中进行参数化。除简单的文本输入以外,选择变量.图形对象和画面选项都可以用。

为了在C动作中的当前光标位置插入函数,可通过单击确认来确定对话框。

(7)现在必须翻译已完成的函数。在通过如下所示的工具按钮来完成。翻译过程的结果显示在动作编辑器的左下角。它包括找到错误的个数和警告的个数。错误总会使C动作无法进行。而警告是一种提示,指出在执行C动作期间可能出现的错误。良好的编辑风格可防止在创建C动作时出现除0 Ereor(S),0 Warning(s)的输出结果之外的情况。

如果在编译过程中出现错误,则它们将在输出窗口中显示。通过鼠标D输出窗口中的错误消息,可以直接跳转到相应的代码行。

(8)对于已经为对象属性创建的C动作,必须定义触发器。对于事件本身就是触发器所以不用在定义。触发器的定义通过如下所示的按钮来执行。可以选择使用时间变量触发器。

(9)通过单击动作编辑器的确定按钮,可将已编写的C动作放置在期望的属性或事件处。通过C动作动态化的属性或事件将用绿箭头标记。

WinCC标签定义和画面定义

#include“apdefap.h”

long-main(char*lpszPictureName.char* lpsz ObjectName. Char* lpszPropertyName) {

/WINCC.TAGNAME-SECTTON-START

//syntax.#define TagNameInAction “DMTagName”

#define S32I-COURSE-0TEST-1 “S32i-course-test-1”

//next TagID :1

//WINCC TAGNAME-SECTION-END

//WINCC:PICNAME-SECCTON-START

//syntax: #define PicNameInAction “PictureName”

#define CC-0-STARTPICTURE-00 “cc-0-startpicture-00.Pd1”

//next PicID:1

//WINCC:PICNAME-SECTTON-END

SetTagSDWord(S32I-COURSE-TEST-1,100);

OpenPicture(CC-0-STARTPICTURE-00); Return 0; }

如果创建新的C的动作,则自动生成的代码将包括两个注释块。若要使用交叉索引编辑器可以仿问C动作的内部信息,则需要这些注释块。要允许C动作中语句重新排列也需要这两个块。

变量定义:第一个注释块用于定义C动作中使用的WinCC变量。该注释块以/MINCC:TAGAME-SECTION-START作为开始,以/MINCC:TAGNAME-SECTION-END作为结束。在两行命令之间,定义C动作中的所有WinCC的变量名称。通过预处理程序命令#define后跟定义的名称(在本实例代码中为S32I-COURSE-TEST-1), 其后在接WinCC变量的名称(在本实例中为(S32i-course-tsse-1)来定义。

画面定义:第二个注释块用来定义C动作中所使用的WinCC画面。该注释块以行/MINCC:PICNAME-SECTION-START作为开始,以行/MINCC:PICNAME-SECTION-END作为结束。在两行之间,定义C动作中使用的所有WinCC画面名称。它遵循的规律与上面所描述的定义变量名称时所遵循的规则相同。

应用:在实际程序代码中,必须使用定义的值,而不是实际的变量和画面名称。在编译C动作之前,预处理程序将用实际名称替换所有定义的名称 2.1.2全局脚本编辑器

全局脚本编辑器用于创建项目函数、标准函数和动作。

1.项目函数

如果在C动作中经常需要相同的功能,则该功能可以在项目函数中公式化。在WinCC 项目的所有C动作都可以按照调用所有其他函数一样的方式来调用项目函数。下面列出了使用项目函数对于在C动作中创建完整的程序代码的优点:

编辑器的中心位置:项目函数的改变会影响所有正在使用该函数的C动作。如果没有使用项目函数,则必须手动修改所有相关的C动作。这不但可以简化组态,而且可以简化维护和故障检测工作。

可重用性:一旦一个项目函数编写完并进行了广泛的测试,则它随时都可以再次使用,无须附加的组态或新的测试。

画面容量减少:如果并不是在对象的C动作中直接放置完整的程序代码,则画面的容量将减少。这可以使画面打开的速度更快并且在运行系统中的效果更佳。

口令保护:项目函数可以通过指定口令进行保护,以防更改。这样可以保护组态数据以及用户的技术窍门。项目函数只能在项目内使用。它们存储在WinCC Project Folder\\LIBRARY文件夹内并在相同的文件夹中的ap-pbib.h文件内定义。许多函数只能在项目内使用。与项目函数相反,标准函数可以用于所有的WinCC项目。可以更改现有的标准函数。也可以创建新的标准函数。

标准函数与项目函数的区别仅在于它们的可用性:标准函数可以跨项目使用,然而项目函数只能在项目内使用。标准函数存储在WinCCInstallationFolder\\LIBRARY文件夹内,并在同一文件夹中的ap-glob.h文件内定义。

2.内部函数

除项目函数和标准函数之外,还有内部函数。其中,它们是标准的C函数。用户不能对其进行更改,也不能创建新的内部函数。

动作:动作(与先前描述的函数相反)不能由C动作或其他函数调用。必须为动作指定触发器来控制其执行。它在运行系统中执行时与当前所选择的画面无关。可以组态全局动作,既跨项目动作。在这种情况下它们存储字WinCCProjectFolder\\PAS文件夹中。也可以组态全局动作(指定计算机的动作),它们将存储在WinCCProjiectFolder\\ComputerName\\PAS文件夹中。如果在计算机的启动列表中选中了全局脚本运行系统,则一旦项目启动,属于该计算机的所有全局动作和所有局部动作将被激活。

3.建立项目函数

创建项目函数所须的步骤与创建标准函数的步骤完全相同,因此下面的说明也适用于标准函数的创建

建立项目函数步骤:

(1)打开全局脚本编辑器 。

(2)通过鼠标的右键项目函数条目,然后从弹出式菜单中选择新建→ 函数,将创建新项目函数的基本框架。

(3)项目函数可以完全由用户进行配置,没有不能编译的代码段。编写函数标题,函数必须有一个名称,以便C动作或其他函数调用时所有。此外,必须指定返回值和函数所须的传递参数。

如果当前的函数中要使用其他项目函数或标准函数,则必须结合apdefap.h文件,这通过预处理程序命令#include“apdefap.h”来完成,该命令必须插在函数标题之前。

#include “apdefap.h”

int My-Project-Function(int iFirstParam,BOOL bSecondParem) { return 0; }

(4)编写函数主题。可以使用与编写C动作相同的辅助工具,特别是变量选择和函数选择。

(5)已完成的函数现在必须进行编译。这通过如下所示的工具栏按钮来完成。

编译过程的结果显示在输出窗口中,将列出产生的错误和警告,并且显示其数量。通过鼠标D输出窗口中的错误消息,可以直接跳转到相应的代码行。

Compiling

Line 3:error (0086):function ?My-Project-Function? does not return a val Error(s),o Warning(s)

(6)通过如下所示的工具栏按钮,可以将描述添加大批项目函数中。可以与描述一起定义一个口令,以保护项目函数免遭未**人员访问。

(7)完成的项目函数必须用合适的名称进行保存。

4.建立全局动作

创建全局动作所须的步骤与创建局部动作所须的步骤完全相同。因此,下面的步骤也适用于创建局部动作。

建立全局动作步骤:

(1)打开全局脚本编辑器

(2)通过鼠标的右键项目函数条目,然后从弹出式菜单中选择新建动作,将创建动作的基本框架。

(3)动作的标题将会自动生成并且不能更该。此外,插入用于定义WinCC变量和WinCC画面的两个注释块。这两个注释块的含义已经在先前的C动作一节中进行说明。

#include “apdefap.h”

int gscAction(void) {

//WINCC:TAGNAME-SETION-START

//syntax.#define TagNameInAction “DMTagName”

//next TagID :1

//WINCC:TAGNAME-SECTION-END

//WINCC:PICNAME-SECTION-START

//oyntax:#define PicNameInAction”PictureName”

//next PicID:1

//WINCC:PICNAME-SECTION-END return o; }

(4)编写动作主体。可以使用与编写C动作相同的辅助工具。特别是变量选择和函数选择。动作具有int类型的返回值。缺省的情况下,返回值为0。

(5)通过如下所示的工具按钮,可以如同函数描述一样将描述添加到动作中。也可以定义口令来保护项目函数免遭未**人员的访问。与函数相比,它还需要设置一个触发器来控制动作的执行。对于动作触发器的选择,用户所具有的选择的范围要比对象的C动作触发器的选择范围大。其中,可以编写一次执行过程

(6)完成的动作必须进行保存。

5.测试输出

执行程序来测试输出。这样便于在开发期间进行故障检测和错误诊断。测试输出可以通过printf()函数来启动。通过该函数,不但可输出简单文本。而且可输出当前变量值。为了使输出文本可见,必须组态全局脚本诊断窗口。

Printf()函数:Printf()函数允许执行测试输出功能。该函数的实例应用如下所示:

Printf(“I am %d years old\\r\\n,iAge);

Printf()函数至少一个参数。该参数是一个字符串。要传递的附加类型和数量取决于该字符串。字符%由prinft()函数用作在该位置插入变量值的标识符。跟在字符%之后的字符确定给变量的数据类型。上表中所使用的字符组合%d表明输出为十进制数,其他可能的组合及其描述如下:

%d 输出十进制数(int或char),%ld 长整型变量作为十进制输出,%c 输出字符(char),%x 以16进制格式输出数值。(用小写字母a,b,c f),%X以16进制格式输出数值。(用大写字母A F),%o 以八进制格式输出数值, %u 输出十进制数(专用于unsigned类型), %f 以浮点数计数制输出浮点型数值 例如3.43234, %e 以指数计数制输出浮点

型数值,例如23e+432,

%E 同%e但使用大写E,例如23E+432, %s 输出字符串(char*),%le 输出双精度型数值, %% 输出%字符, |n 换行输出(回车),、r 进一行输出, 、t 制表位输出, 、、 输出、字符

6.全局脚本诊断窗口

由printf()函数指定的文本输出显示在全局脚本诊断窗口中。组态这种诊断窗口的步骤如下:

(1).打开图形编辑器

打开期望的WinCC 画面。

(2)组态智能对象 应用窗口。

将应用窗口置于画面内之后,将打开窗口对话框。从列表中选择全局脚本条目。通过单击确定退出对话框。 打开模板对话框,从列表中选择GSC诊断条目。同样通过单击确定退出对话框。

(3)为了便于利用全局脚本诊断窗口,建议将对象属性对话框其他条目下的所有属性设置为是。

(4)如果项目在运行,则由printf()函数指定的文本输出将显示在诊断窗口中。如果用工具栏上相应的按钮中止更新,则可以保存或打印输出窗口内容。 2.2变量

在WinCC项目Project-C-Course中,有关变量的主题实例可以通过单击如下所示的浏览栏来访问。实例在kzz-00.PDL画面中组态。

变量:变量是由程序处理的数据对象。变量只有在定义以后才能使用。在第一条指令可以执行前,必须先定义程序中的所有变量。

变量可以比做一个容器。通过变量名,我们给容器一个唯一的名称。容器中内容的类型通过其数据类型来指定,容器的初始内容通过初始值来指定。在大多数情况下,该内容将在程序执行过程中进行处理。此处所描述的变量不应误认为是WinCC变量。它们只能在程序代码中使用。以下程序代码说明了定义变量的一个实例。

Int itag;

.在该实例中,用名字Itag来定义一个int数据类型的变量。代码行以分号结束。变量名的前面是描述数据类型的前缀。这并非必须遵循,但它却使得在程序创建期间能够立即识别变量的数据类型。在定义变量时,也可以将其初始化。

Int itag = 0;

常量:除变量之外,程序中也使用常量。它只是数值的直接使用。为了说明这种数值的含义,可以使用#define命令为它定义符号常量。

以下程序代码说明了定义符号常量的一个实例。

#define MAX-VALUE 7483647

在给实例中,用数值7483647来定义符号常量MAX-VALUE。注意代码行不得用分号结束。用大写字母表示符号常量是一般的编程规律,以便易于与变量区分。

数据类型:C所识别的基本数据类型如下:

Char 一个字节,可以接受一个字符,Int 整型数值,Float 单精度型浮点数,Double 双精度型浮点数,Char数据类型的变量需要一个字节的存储空间。其内容可以解释为一个字符或一个数字。

Int数据类型之前可以加关键字signed或unsigned。关键字signed代表有符号数,关键字unsigned代表无符号数。Int数据类型之前也可以加关键字long或short.这些关键字也可以不带int而单独使用,其含义仍然相同。Short(或short int)数据类型的变量需要2个字节的存储空间,long(或long int)数据类型的变量与int数据的变量一样需要4个字节的存储空间,然而double数据类型的变量需要8个字节的存储空间。

各数据类型的数值范围:每种数据类型都可以显示某一数值范围的数值。区别在于不同的数据类型所须的存储空间不同,以及是有符号还是无符号数据类型。

Int –2147483648至2147483647

Unsigned int 0至429967295

Short -32768至32767

Unsigtned short 0-65535

Long –2147483648至2147483647

Unsigned long 0至4294967295

Char –128至127(所有的ASC||字符)

Unsigned char 0至225(所有的ASC||字符)

float –10^38z 至0^38

double –10^308至0^308

2.2.1整数数据类型

用C的缺省数据类型来显示整数。在事件→鼠标→鼠标动作的对象按钮1组态了本实例。

1.按钮1的C动作

#include “apdefap.h”

void OnClick(char# lpszPictureName char3 lpszObjectName,char#lpszProper” {

char cNumber; //signad 0 bit value

long 1Nameber; // signad 32 bit value

short sNamber; // signad 16 bit value

int iNumber; // signad 32 bit value

unsigned char ucNumber; //unsigned 8 bit value

unsigned long ulNumber; //unsigned 32 bit value

unsigned short usNamber: //unsigned 16 bit value

unsigned int uiNumber; //unsigned 32 bit value

cNumber = -128;

sNumder = -32768;

lNumber = -2147483648;

iNumber = 2147483467;

//output in dignstics sindow

prinft(“\\r\\nExaple 1:\\r\\n”);

printf(“char:\\t\\t%d\\r\\nshort:\\t\\t%d\\r\\n”

“long:\\t\\t%d\\r\\ninth:\\t\\t%d\\r\\n”,

cNumber,sNumber,1Number,iNumber);

ucNumber = 255;

usNumder = 65535;

u1Nuber = 4294967295;

uiNuber = 4294967295;

//output in diagnostics vindow

printf(“unsigned char:\\t%u\\r\%unsigned short:\\t%u\\r\\n”

“unsigned long:\\t%u\\r\\nunsigned int:\\t%u\\r\\n”,

ucNumber,usNumber,ulNumber,uiNumber); }

前三行为C动作的标题。该标题不能更改。在第二部分中,定义变量。为char long short和int数据类型及其无符号的对应量各定义一个变量。变量名称前面加上描述数据类型的前缀。这并非必须遵循,但它却使得在程序创建期间能够立即识别变量的数据类型。作为注释,每一行包括变量所需的存储空间(以字符串//开始的注释部分用绿色标记)。在第三部分中,将数值赋给变量。这通过使用赋值运算符= 来完成。本实例中所使用的数值恰好是各种数据类型所能显示的数值范围中的极限值。这些数值通过函数printf()在诊断窗口中输出。此输出在下部分显示。

2.诊断窗口中的输出

本节中描述的实例在诊断窗口中内生成下列输出:

Example1:

Char: -128

Short: -32768

Long: -21474833648

Int: 2147483647

Unsigned char: 255

Unsigned short: 65535

Unsigned long: 4294967295

Unsigned int: 4294967295 2.2.2 整数WinCC变量

在大多数情况下,要通过C动作或其他函数来使对象动态化和解决类似的事情时,必须使用WinCC变量。为此,有许多用于读取和写入WinCC变量值的函数可以使用。这些函数可以与每种WinCC 缺省变量类型一起使用。在本实例中,将数值写入各种WinCC变量。WinCC变量的内容显示在输出域内。在事件→ 鼠标→ 鼠标动作处为对象按钮3组态了本实例

按钮3的C动作:

#include “apdefap.h”

void OnClick(char# lpszPictureName char3 lpszObjectName,char#lpszProper” {

CHAR cNumber; //signed 8 bit value

SHOURT sNumber; //signed 16 bit value

LONG 1Number: //signed 32 bit value

BOOL bNumbeer; //TRUE or FALSE

BYTE byNumber;//unsigned 8 bit value

WORD wNumber; //unsigned 16 bit value

DWORDdwNumber; //unsigned 32 bit value

CNumber = -128;

SNumber = -32768;

1Number = -2147483648;

//set wincc tage

Set agSByte(“SO8i-course-tag-1”,cNumber);

SetTagSWord(“S16i-course-tag-1”,sNumber);

SetTagSDWord(“S32i-course-tag-1”,1Number);

bNumber = TRUE;

#include “apdefap.h”

void OnClick(char# lpszPictureName char3 lpszObjectName,char#lpszProper” {

//declare external tag

exter int ext-iNumber;

//define static tag

static int statt-iNumber = 0:

//output in diagnostics window

printf(“\\r\\nExample 6:\\r\\n”

“mouseclicks since project was started:%d\\r\\n”

“mouseclicks since project was opend:%d\\r\\n”

++ext-iNumber,++stat-iNumber); }

在第一部分中声明外部变量ext-iNumber,以便能在C动作中使用它。在第二部分中,定义并初始化静态变量stat-iNumber。它们将在选择WINCC画面后首次执行C动作时执行。对于以后再此执行C动作,该变量的值将会保留。如果撤消选定后在再选择画面,则将会再生成变量。

变量的数值通过自增运算符++增加1,并通过printf()函数在诊断窗口中输出。因此,变量ext-iNumber将显示从项目启动后单击按钮的次数,而变量stat-iNumber将显示从画面打开后单击的次数。

2.3 C中的运算符和数学函数

运算符:在程序中,运算符控制变量和常量进行的运算。变量和常量与运算符连接,这样会导致产生新的变量值。运算符可以分成多种类别。包括数学运算符。按位运算符和赋值运算符。

数学运算符:

按位运算符:

描述 运算符 +(单目) 正号(实际不可使用) -(单目) 负号 +(双目) 加 -(双目) 减 * 乘 / 除 % 模(返回除法运算的余数) ++ 自增 –– 自减

这些运算符使得可以对变量中的各个位进行设置、查询或重新设定。

运算符 & | ^ ~ << >> 逻辑运算符

所有的逻辑运算符都遵循相同的原则:0表示假,所有其他数都表示真。这些运算符不是生成0(假)就是生成1(真)

运算符 > >= 大于 大于或等于 描述 按位与 按位或 按位异或 按位取反 将位向左移 将位相右移 描述 = = != <= < && || ! .3.1 基本的数学运算

在本实例中使用了基本的数学运算符。在事件→ 鼠标→ 鼠标动作处为对象按钮1组态了本实例。

按钮1的动作

#include “apdefap.h”

void OnClick(char# lpszPictureName char3 lpszObjectName,char#lpszProper” {

float fValuel = 123.6;

float fValuel = 23.4;

等于 不等于 小于或等于 小于 逻辑与 逻辑或 逻辑非

float fResAdd;

float fResSub;

float fResMul;

float fResDiv;

fResAdd = fValuel+fValue2;//add

fResAdd = fValuel-fValue2;//subtract

fResAdd = fValuel*fValue2;//multiply

fResAdd = fValuel/fValue2;//divide

//output in diagnostics window

printf(“\\r\\nExample 1\\r\\n”)

printf(“ +  = \\r\\n”,fValuel,fValue2,fResADD);

printf(“ -  = \\r\\n”,fValuel,fValue2,fResSub);

printf(“ *  = \\r\\n”,fValuel,fValue2,fResMul);

printf(“ / = \\r\\n”,fValuel,fValue2,fResDiv);

//read bytes

dwtempValue1 = dwValue<<8;

dwtempValue2 = dwValue>>8;

dwValue = dwtempValue1 | dwtempValue2;

//write result

SetTagWord(“V16i-course-op-3”,(WORD)dwValue); }

在第一部分中,定义一个数据类型为DWORD的变量。此变量用于临时存储WinCC变量。此外,再定义两个类型为DWORD的辅助变量。在第二部分中,把要进行处理的WinCC变量写入变量dwValue中。在第三部分中,变量dwValue的各个位向右移动8位。然后存储在变量dwtempValue2中。此处确定的两个数值按位连接(OR),并且将存储结果存储在变量dwValue中。在第四部分中,将变量dwValue所包含的循环移动后的变量值写入相应的WinCC变量中。

2.3.5 数学函数

在本实例中使用了缺省情况下在C语言中可使用的各种数学函数。在事件→ 鼠标→ 鼠标动作处为对象按钮5组态了本实例。

按钮5的C动作

#include “apdefap.h”

void OnClick(char# lpszPictureName char3 lpszObjectName,char#lpszProper” {

double dValue = 123.6;

int iValue = -24;

double dResPow;

double dResSqrt;

int iResAbs;

int iResRand;

dResPow = pow(dValue,3); //power of 3

dResSqrt = pow(dValue); //square root

iResAbs = ads(iValue);//absolute

iResRand = rand(); //random

//output in diagnostics window

printf(\\r\\nExample 5\\r\\n”);

printf(“ raised to the power of 3 = \\r\\n”,dValue,dResPow);

printf(“Square root of…if\\t = \\r\\n:,dValue,dResSqrt);

printf(“Absolute value of %d\\t = %d\\r\\n:,iValue,iResAbs

printf(“A pseudorandom number\\t %d\\r\\n”,iResRand); }

在第一部分中,定义变量。首先调用pow()函数。该函数分配两个参数。在本实例中,函数的返回值等于dValue变量值的三次方。接着调用sqrt()函数。此函数的返回值等于传送值的平方根。再接着调用ads()函数。此函数的返回值等于传送值的绝对值。然后再调用rand()函数。没有参数分配给此函数,它将返回一个随机值作为返回值。这些计算结果通过printf()函数在诊断窗口中输出。此输出在下一部分中显示。

其他数学函数,在函数选择中,数学函数可以在内部函数→ c-bib→ math下找到。 2.4指针

使用指针:指针是C语言的重要组件。指针是包含地址的变量,通常该地址是另一个变量的地址。定义指针就象定义普通变量一样。但是指针指向的数据类型名称要添加单目字符*。不得将此字符误认为是用与乘法运算的双目运算符*。在以下程序代码中,定义了int数据类型的指针变量。

Int * piValue;

指针的内容没有定义。它仍然指向一个无效的int数据类型的变量。为了澄清这一点,在定义指针时应该用实质NULL进行初始化。在应用指针前可检查其有效性。

Int * piValue = NULL;

要使指针指向int数据类型的变量,必须将变量的地址分配给它。这通过单目运算符来完成。单目运算符又称为地址运算符。此运算符返回变量地址,而不是变量值。在以下程序代码中,将数据类型为int的变量的地址分配给指针。

PiValue = &iValue;

可以通过单目运算符*(也称为内容运算符)来实现对指针所指向的变量值的访问。在以下程序代码中,将指针指向的变量值分配给一个数据类型为int的变量。

IValue ==*piValue;

使用向量:指针和向量密切相关。在以下程序代码中,定义了一个由5个int数据类型的变量组成的向量。

Int iVector[5];

向量的各个元素可以通过其下标来访问。在以下呈现代码中,访问最后一个向量元素的内容。这通过下标运算符[ ]来完成。

IValue = iVector[4];

向量名也可以作指向第一个向量元素的指针。可通过将此指针移动几个元素来访问某个向量元素。如以下程序代码所示,它通过将指针加上一个int数值来完成。结果指针的内容

通过内容运算符*来访问。同前所示,访问的是最后一个向量值。

IValue = *(iVector+4);

字符串:在C语言中,字符串可以定义为由字符组成的向量或指向字符的指针。除代码字符外,C语言还在字符串的结尾添加一个空字符。它作为字符串的结束符。在如下所示的程序代码中,定义了两种类型的字符串变量。

Char# lpszString =String1;

Char szString[10] =String2;

2.4.1指针实例

在本实例中执行基本的指针运算。在事件→ 鼠标→ 鼠标动作处为对象按钮1组态了本实例。

按钮1的C动作

#include “apdefap.h”

void OnClick(char# lpszPictureName char3 lpszObjectName,char#lpszProper” {

int iValue1 = 126;

int iValue2 = 23;

//declare and initialize pointer

int* piValue = NNULL;

printf(“\\r\\nExample 1\\r\\n”);

printf(“Address:%x\\tValue:undefined\\r\\n”,piValue);

//point at iValue1

piValue = &iValue1;

printf(“Address:%x\\tValue: %d\\r\\n”,piValue,*piValue);

//point at iValue1

piValue = &iValue2;

printf(“Address:%x\\tValue: %d\\r\\n”,piValue,*piValue); }

在第一部分中,定义并初始化两个数据类型为int的变量。在第二部分中,定义一个指向int 数据类型的变量指针,并用NULL对其进行初始化。在第三部分中,通过printf()函数输出该指针中包括的地址。当前该指针指向的内容没有定义。此时通过内容运算符*访问指针的内容会引起一般的访问违例。在第四部分中,将变量Ivalue1的地址赋给指针。通过printf()函数再次输出其地址和内容。在第五部分中,将变量iValue2的地址赋给指针,并且再次输出结果。

2.4.2 向量

在本实例中执行基本的向量运算。在事件→ 鼠标→ 鼠标动作处为对象按钮2组态了本实例。

按钮2的C动作

#include “apdefap.h”

void OnClick(char* lpszPictureName char*lpszObjectName, char#*pszProper” {

//declare and initialize int vector

int iValue[5] = {10,20,30,40,50};

int iIndex;

printf(“\\r\\nExample 2\\r\\n”);

//access vector elements

for (iIndex = 0;iIndex++) {

printf(“Index:%d\\t Value:%d\\t\\n”,iIndex,iValue[iIndex]); } }

在第一部分中,定义一个由5个int数据类型的变量组成的向量。向量在定义时就已用数值进行初始化。在第二部分中,定义int数据类型的计数器变量ilndex。向量的各个元素通过下标运算符[ ]来完成。涉及循环的内容在循环中描述。

2.4.3 指针与向量

在本实例中解释指针与变量之间的关系。在事件→ 鼠标→ 鼠标动作处为对象按钮3组态了本实例。

按钮3的C动作

#include “apdefap.h”

void OnClick(char* lpszPictureName char*lpszObjectName, char#*pszProper” {

int iValue[] = {10,20,30,40,50};

int iIndex;

int*piElement = NULL;

printf(“\\r\\nExample 3\\r\\n”);

//access vis seperat pointer

//point to the first element

piELEMENT = &IvALUE[0];

printf(“Startaddress:%x\\r\\n”,piElement);

for(iIndex = 0;Iinder<5;iIndex++) {

printf(“Index:%d\\t Value:%d\\r\\n,*(piElement+iIndex)); }

printf(“\\r\\n);

//access without seperat pointer

printf(“Startaddrees:%x|\\r\\n”,iValue);

for (iIndex = 0;iIndex<5;iIndex++) {

printf(“Index:%d\\t Value:%d\\r\\n”,iIndex,*(iValue+iIndex)); } }

在第一部分,定义一个由5个int数据类型的变量组成的向量。向量在定义时就已用数值进行初始化。在这种情况下,定义向量时可以省略大小规定。在第二部分中,定义int数据类型的计算器变量ilndex.。在第三部分中,为int数据类型的变量定义指针piElement,并用NULL进行初始化。在第四部分中,将第一个向量元素的地址赋给指针piElement。此地址通过printf()函数输出。在第五部分中,通过指针piElement访问向量各个元素。在一个for循环中通过指针指向各个元素,并且通过内容运算符*来进行访问。在第六部分中,再次访问向量的各个个元素。但是这次将向量名本身作为指针。

2.4.4 字符串

本实例中解释对字符串变量的使用。在事件→ 鼠标→ 鼠标动作处为对象按钮4组态了本实例。

按钮4的动作

#include “apdefap.h”

void OnClick(char* lpszPictureName char*lpszObjectName, char#*pszProper” {

//declare and initialize string

char szText[13] = “example text”; int I;

printf(“\\r\\nExample 4\\r\\nCharacters:\\r\\n”;

//access single characters for (i=0; i<12; i++) {

printf(“[%c],”szText[i]); }

printf(“\\r\\n”);

//access hole string

printf(“String:\\r\\n%s\\r\\n”,szText); }

在第一部分中,定义一个字符串(由13个字符组成的向量)。此字符串的长度比分配的初始化字符串多一个字符,以便为结束空字符留出空间。在第二部分中,定义int数据类型的计数器变量i。在第三部分中,通过printf()函数输出字符串的各个字符。在for循环中通过下标运算符[ ]来对这些字符进行访问。在第四部分中,通过printf()函数输出整个字符串。

2.4.5 WinCC 文本变量

在本实例中解释了C动作与WinCC文本变量之间的关系。在事件→ 鼠标→ 鼠标动作处为对象按钮5组态了本实例。

按钮5的C动作

void OnClick(char* lpszPictureName char*lpszObjectName, char#*pszProper” {

//declare and initialize pointer to string

char pszText[13] = NULL;

//get wincc tag value

pszText = GetTagChar(“TO8i-course-point-1”);

printf(“\\r\\nExample 5\\r\\n”);

//access string

printf(“string:%s\\r\\nStringLength:%d\\r\\nStartaddress:%x\\r\\n”,

pszText,strlen(pszText),pszText); }

在第一部分中,定义一个字符串(指向第一个字符的指针)。用NULL初始化此字符串。

在第二部分中,通过GetTagChar()函数读入wincc文本变量的内容。当返回字符串的起始地址时,函数保留字符串所需的内存空间。第三部分中,通过printf()函数输出整个字符串。此外,字符串的长度由strlen()函数来确定,并且与字符串的起始地址一起输出。

2.5 循环和条件语句

循环:只要条件满足,循环可用于重复执行一个代码。通常,有两种循环类型:预检查循环和后检查循环。预检查循环在要执行循环的循环体之前进行检查。后检查循环在要执行的循环体后进行检查。因此,后检查循环至少要执行一次。

循环可以分为以下类型。 1.While

Whlie循环的实例显示如下。只要条件满足,就重复执行循环。在本实例中,只要变量I的值小于5就执行循环。 Int I = o;

While (i<5) {

//do something ++I; } Do-while

Do-while循环的实例显示如下。该循环至少执行一次,然后只要条件满足就重复执行。在本实例中,只要变量i的值小于5就执行循环。 int i=0; do {

//do something ++I; }

while(i<5); 2.for

for循环的实例显示如下。只要条件满足,就重复执行循环。循环计数器的初始化以及循环计数器的运算过程可以在循环内用公式表示。 int I = 0

for (i=0,i<5,i++) {

//do something }

3.条件语句

在循环中,只要条件为真,就处理循环体。在条件语句中,如果条件为真,语句只处理一次。

条件语言可以可分为下列类型。

(1)If-else

如果条件为真就处理if分支中的语句。如果条件不合适,就执行else分支中的语句。如果没有另一个要执行的语句,也可以省略else分支。 If (i<5) {

//do something } else {

//do something else }

(2)switch-case

在这种情况下,检查变量是否匹配。Switch指定要检查的变量。程序检查哪一个case分支与变量的值一致,然后执行该case分支。可以定义任意case分支。每个case分支必须以break结束。可以选择插入default分支。如果要检查的变量的值与任何case分支都不一致,则执行此分支。 switch(i) {

case 0://do something break;

case 1://do something break;

default;//do something default break; }

2.5.1 while循环

在本实例中,解释while循环的应用。在事件→ 鼠标→ 鼠标动作处为对象按钮1组态了本实例。

按钮1的c动作

void OnClick(char* lpszPictureName char*lpszObjectName, char#*pszProper” {

//loop cuunt

int iCount = 0;

printf(“\\r\\nExample 1\\r\\n”);

//while (iCount<5) {

//do something

printf(“Executed loop: iCount = %d\\r\\n”,iCount);

++iCount; }

printf(“Exit lop: iCount = %d\\r\\n”,iCount); }

在第一部分中,定义并初始化int数据类型的计数器变量iCount.。接着,编写while循环。只要计数器变量iCount 的值小于5。就执行该循环。每次执行该循环时,通过printf()

函数进行输出。在循环结束时,计数器变量iCount增加1。 .5.2 do-while循环

在本实例中,解释do-while循环的应用。在事件→ 鼠标→ 鼠标动作为对象按钮组态了本实例。

按钮2的C动作

void OnClick(char* lpszPictureName char*lpszObjectName, char#*pszProper” {

//loop cuunt

int iCount = 0;

printf(“\\r\\nExample 2\\r\\n”);

//do-while loop do {

//do something

printf(“Exected loop: iCount = %d\\r\\n”,iCount);

++iCount; }

while (iCount<5);

printf(“Exit loop: iCount = %d\\r\\n”,iCount); }

在第一部分中,定义并初始化int数据类型的计数器变量iCount。接着,编写do-while循环。只要计数器变量iCount的值小于5,就执行该循环。条件只有在执行循环以后才检查,所以该循环至少执行一次。每次执行循环时,通过printf()函数进行输出。在循环结束时,计数器变量iCount增加1。

2.5.3 for循环

在本实例中,解释for循环的应用。在事件→ 鼠标→ 鼠标动作处为对象按钮组态了本实例。

按钮3 的C动作

#include “apdefap.h”

void OnClick(char* lpszPictureName char*lpszObjectName, char#*pszProper” {

//loop cuunt

int iCount = 0;

printf(“\\r\\nExample 3\\r\\n”); //for loop

for (iCount =0;iCount<5;iCont++)

{

//do something

printf(“Exected loop: iCount = %d\\r\\n”,iCount); }

printf(“Exit loop: iCount = %d\\r\\n”,iCount); }

在第一部分中,定义并初始化int数据类型的计数器变量iCount.。接着,编写for 循环。只要计数器变量iCount的值小于5,就执行该循环。计数器变量的初始化直接编写在循环的调用中,如同使计数器变量递增的动作一样。每次执行循环时,通过printf()函数进行输出。

2.5.4 无限循环

在本实例中,解释无限循环。在大多数情况下,这些循环是由于编程错误而无意识创建的,其循环条件始终保持为真。然而,也可以有意识地应用它们。在这种情况下,必须利用其他方式实现循环的终止,即通过break语句。在事件→ 鼠标→ 鼠标动作处为对象按钮4组态了本实例。

按钮4的C动作

#include “apdefap.h”

void OnClick(char* lpszPictureName char*lpszObjectName, char#*pszProper” {

//max loop executions

#define MAX_COUNT 1000000

//loop cuunt

int iCount = 0;

int iProgressBar = 1;

char szProgressText[5];

//endless loop

//another possible loop while(TRUE) {…} for(;;) {

if (iCount > MAX_COUNT) { break; }

++iCount;

if (iCount-(iProgressBar*MAX-COUNT/100) ! = 0)

{ continue; }

//set value of progress bar

SetWidth(lpszPictureName.”ProgressBar”,(int)(iProgressbar*2.7));

//set progress text

sprintf(szProgressText,”%d%%,iProressBar);

SetText(lpszPictureName,”ProgressText”,szProgressText);

++iProgressBar; } }

在第一部分中,定义符号常量MAX-CUNT。该常量代表以下无限循环最多执行的次数。

在第二部分中,定义并初始化int数据类型的计数器变量iCount.。当前循环执行的次数要通过进程显示来表示。该显示由一个棒图组成,其长度包含变量iProgressBar和静态文本,其内容包含字符串变量szProgressText.。接着,编写无限循环。该循环也可以利用while(TRUE)语句公式化。在该循环中,检查计数器变量iCount.如果该变量超过MAX_COUNT的值,则通过break语句退出循环。计数器变量iCount将递增。

进程显示表示循环已执行的百分比。对于每次达到新的百分比,都再次设置进程显示的始终。如果还没有达到新的百分比,则立即再次通过countinue语句循环,并且跳过剩余的行。

本文来源:https://www.bwwdw.com/article/k68x.html

Top