| 作者 | 主题 |
|---|---|
|
幸福的方向 侠士 经验值:1149 发帖数:227 精华帖:0 |
楼主
主题:也来谈谈“先赋值后使用”!
对于临时变量的“先赋值后使用”大家都不会陌生,可是你是否真正正确地理解了“先赋值后使用”呢,我们来看看以下的例子: 通过仿真运行:I10.0=1,Q10.0=1 ,此时Q10.1=0属于先赋值后使用,彼此不受影响 ; I10.2=1,此时,Q10.1=Q10.6=Q10.7=1(q10.6和q10.7都受临时变量的影响,而且是受FC2内的临时变量影响,只因为FC2和FB1内的临时变量同名。)并且,尽管FB1调用时有DB块,也一样受临时变量影响,这是因为,FB1内使用的是临时变量,而非静态变量。 若将图1FC2中并联的#run换成#run1,则,I10.0=1,q10.0,q10.1,q10.6,q10.7都将=1,也就是,后面的结果都受到临时变量的影响。 以上弄明白了,我想“先赋值后使用”才算真正弄明白了。若有错误,敬请指正
雨过分洼种瓜,旱时饮水浇麻。
|
|
Haohaobb 至圣 经验值:15996 发帖数:1637 精华帖:39 |
3楼
主题:回复:也来谈谈“先赋值后使用”!自锁以及边沿触发的存储位是不能用temp的。 fc里面,如果就是为了演示而加了个run1可以理解,否则直接用run互锁就是了,另外,如果是博途,最好把run定义为inout,否则会有警告,当然也不影响使用。 fc里面的temp区和fb里面的temp区功能和特点是完全一样的,不明白演示第二个是什么意图。而且你可以发现fb里面的temp在背景db里面是没有的。
天道酬勤
|
|
幸福的方向 侠士 经验值:1149 发帖数:227 精华帖:0 |
4楼
主题:回复:也来谈谈“先赋值后使用”!“自锁以及边沿触发的存储位是不能用temp的。”开门见山,一针见血。的确这样,自锁如果用temp,立马就不是“先赋值后使用”了。 “而且你可以发现fb里面的temp在背景db里面是没有的。”这句也是一针见血啊,初学的时候,总以为FB是带DB块的,应该不存在“先赋值后使用”这个问题,后来才发现,DB块其实是为静态变量准备的,根本与temp无关。也就是无论FC还是FB,只要是临时变量,都要满足“先赋值后使用”这一条才不会出错。 很感谢,开眼界了。
雨过分洼种瓜,旱时饮水浇麻。
|
|
Letham 至圣 经验值:14191 发帖数:2021 精华帖:43 |
5楼
主题:回复:也来谈谈“先赋值后使用”!I10.2=1,此时,Q10.1=Q10.6=Q10.7=1(q10.6和q10.7都受临时变量的影响,而且是受FC2内的临时变量影响,只因为FC2和FB1内的临时变量同名。) 临时变量作用范围仅仅是在程序快内部,而已,不同程序块内部的临时变量是否同名没有任何关系。 临时变量在程序快调用结束后,内存会自动释放,所以 如楼上几位所说 ,比如上升沿等需要存储功能的指令是不能使用临时变量的。
人生就像一场旅行!
|
|
幸福的方向 侠士 经验值:1149 发帖数:227 精华帖:0 |
7楼
主题:回复:也来谈谈“先赋值后使用”!版主:发现个新情况,我重做了一下试验,为了简便,只做了一个FC1 和一个 FB1, DB为FB1的背景数据块。 FC1内run1为临时变量,FB1内run1也是临时变量。FC1和FB1内程序完全相同。 OB1内无条件调用FC1和FB1,运行结果却是FC1和FB1内的临时变量是相互影响的。请看以下图片: 从试验结果来看,不同块中的临时变量好像是要相互影响的,怎么回事?
雨过分洼种瓜,旱时饮水浇麻。
|
|
幸福的方向 侠士 经验值:1149 发帖数:227 精华帖:0 |
8楼
主题:回复:也来谈谈“先赋值后使用”!又试验了一下,这次把FB1内的临时变量改名为run2,运行结果也一样,是相互影响的。我再加了一个FB2,中间变量run1 用静态变量来代替,运行结果是FC1与FB1因为临时变量相互影响,而FB2因为用的是静态变量,不受其他两个影响。 想了一下:临时变量调用后会保存调用后的结果,真正释放的是局部变量(如那些#start)。临时变量就像内存,调用后会留下上次使用的结果。这些内存是公用的,两个不同的块分别使用相同的内存(如FC1和FB1都是使用的一个位),而不管你给这个位起命为run1,还是run2,反正使用的都是公共内存的这个位,那么就会相互影响。这也正好就有了:临时变量必须“先赋值后使用”。 很容易被麻痹,块调用结束临时变量不会释放,释放的是一些局部变量。
雨过分洼种瓜,旱时饮水浇麻。
|
|
emil128 侠圣 经验值:3827 发帖数:271 精华帖:10 |
9楼
主题:回复:也来谈谈“先赋值后使用”!楼主实验做的是对的,可结论我看不懂。 “块调用结束临时变量不会释放,释放的是一些局部变量”??? 什么是临时变量?什么是局部变量?各是什么地址类型? 1、每一个优先级都拥有属于自己的本地堆栈区(L区),所有运行在该优先级下的OB、FB、FC的Temp都属于该区域。 2、不同优先级的本地堆栈区不同,不会互相干扰。这是西门子从系统角度保证了各中断程序和主程序间的堆栈数据安全。 3、每次调用FB或FC其temp区域的本地堆栈地址由系统指定,调用结束释放(只是不再占用,并不清零)。所以FB或FC的调用可能会使用重合的本地堆栈,这也就是为什么temp不能跨周期传递的原因,于是所有需要跨周期传递的自保、边沿都不能用temp。 L 堆栈永远以地址“0”开始。 指针总是指向当前打开块的第一个字节。 |
|
看雪001 至圣 经验值:22507 发帖数:2416 精华帖:87 |
10楼
主题:回复:也来谈谈“先赋值后使用”!你也可以使用“代入法”,将输入输出接口全部替换为实参,象下面这样: 这样演化一下,可以撇开块接口的干扰,将“临时变量”等同于“双线圈”来看待。观察“双线圈”在一个扫描周期内的逻辑变化情况,梯形图虽然形式上看上去象继电逻辑,但它是扫描执行,不等于继电逻辑。
大道至简,知易行难
|
|
幸福的方向 侠士 经验值:1149 发帖数:227 精华帖:0 |
11楼
主题:回复:也来谈谈“先赋值后使用”!谢谢大侠指点,我照这样试验了一下,但“一个扫描周期”内的逻辑变化没观察到。但对于扫描执行,我是理解的: 如图所示,当到达第3网段时,因为在一个网段中扫描是从左到右一个节点一个节点扫描的,那么,与i0.0并联的触点run3一定run3的线圈先扫描到。触点扫描是“使用”,线圈扫描是“赋值”;那么在网段3中,临时变量run3就是先使用后赋值了。这就违背了临时变量“先赋值后使用”的原则,这就是网段3出错的原因。 所谓“临时变量不能用于自锁”,正如以上分析,根本原因还是违背了“先赋值后使用”的原则。 我想,大侠应该是想让我观察分析出以上结论吧,谢谢
雨过分洼种瓜,旱时饮水浇麻。
|
|
幸福的方向 侠士 经验值:1149 发帖数:227 精华帖:0 |
12楼
主题:回复:也来谈谈“先赋值后使用”!谢谢大侠的指正,其实当时最后那句结论自己都觉得不对,只是当时没删,也幸好没删才引出老师的指正。以前错误的认为,FC中的临时变量存储区就在FC中,FB中的临时变量存储区就在FB中,看了你们提供的资料才认识清楚。 “飞天玉虎: 嗯,每一个组织块都拥有一片自己的独立的临时本地数据存储区,该组织块下调用的功能和功能块的临时变量都位于该区域。”一并谢了,一句话切中要害。原来,在OB块中调用的FC也好,FB也好,其临时变量都来自于调用块OB。 “2、不同优先级的本地堆栈区不同,不会互相干扰。”这说的应该是不同的OB块,分别有各自的临时变量存储区,那么在不同OB块里调用执行程序时,临时变量存储区各用各的,互不影响。 感谢指正,又总结了一下,如果有错,还请继续指正。谢谢
雨过分洼种瓜,旱时饮水浇麻。
|
|
Letham 至圣 经验值:14191 发帖数:2021 精华帖:43 |
13楼
主题:回复:也来谈谈“先赋值后使用”!调用结束释放(只是不再占用,并不清零),所言极是! 所以 楼主做的实验,并不是FCFB 里的变量同名影响,只是 楼主用了 RUN1这临时变量实现自锁的原因》 I0.3 为1 看看 FB的输出Q0.1是否为1 就知道了! 其实 说到底 在使用临时变量时 先初始化赋值才是 规范的编程方法!
人生就像一场旅行!
|
|
幸福的方向 侠士 经验值:1149 发帖数:227 精华帖:0 |
14楼
主题:回复:也来谈谈“先赋值后使用”!开始是不理解为何混合调用FC与FB会相互影响,以为只是单纯的重复调用FC(或FB)才相互影响。是没搞懂临时变量存储区来源。谢谢各位
雨过分洼种瓜,旱时饮水浇麻。
|