首页 理论教育 Arduino开发技术:全局作用域与名称冲突

Arduino开发技术:全局作用域与名称冲突

时间:2023-10-23 理论教育 版权反馈
【摘要】:图7-4全局变量作用域现在程序中有了一个可以提供给所有函数都可以访问的变量,这使得从一个函数向另一个函数传递数据变得更容易了。如果在loop()中定义了一个名为port的变量,你已经编写了一个名为SetPort()的函数,该函数需要访问端口,然后可以移动定义loop()外部的端口,并使其具有全局作用域。再次使用代码清单7-1作为讨论点,假设你在loop()函数中定义了一个名为k的变量。因为k的全局范围包括loop(),所以这两个变量不会有名称。

Arduino开发技术:全局作用域与名称冲突

有时,你需要一个程序中所有函数都可以访问的变量。如果有一段数据必须在程序中的任何地方都可用,那么应该使用全局变量。如果变量在函数块外部定义,则该变量具有全局作用域。请看清单7-1。在清单顶部附近,你可以看到变量k定义为:

int k;

请注意,k是在setup()和loop()函数块之外定义的。在这种情况下,变量k的范围从其定义点扩展到文件的末尾。k的全局范围为图7-4中的阴影区域。这意味着在定义k之后出现的任何语句都可以访问变量k。k是源文件中的所有函数和语句块都可以随便访问的变量。

图7-4 全局变量作用域

现在程序中有了一个可以提供给所有函数都可以访问的变量,这使得从一个函数向另一个函数传递数据变得更容易了。不足之处是这种可以随时访问变量数据的方式和之前提到的变量数据被封装的做法就完全脱离了。因为程序文件中的所有语句都可以访问k。这有点像把一块金砖放在保险柜里,然后保险柜的钥匙可以分给相关的每个人,这样一来,保险柜就不再有保险作用了。如果k出了问题,那就更难确定问题的原因了,因为对k的访问没有限制。(www.xing528.com)

然而,这里有一个权衡做法,就是一方面使用更严格的定义(即使用语句或函数块范围)来保护变量;另一方面,还是使用全局变量,易于共享函数之间的数据(在实际使用中视情况而定)。如果在loop()中定义了一个名为port的变量,你已经编写了一个名为SetPort()的函数,该函数需要访问端口,然后可以移动定义loop()外部的端口,并使其具有全局作用域。由于数据的原因,这并不是我们刚才指出的保证数据安全所在。

然而,还有其他选择。合适的替代方法是将端口的定义保留在loop()中,但将端口作为函数参数传递给SetPort()。现在SetPort(port)可以使用port的值,并且仍然可以为它提供某种程度的保护。如果现在端口发生了一些奇怪的事情,那么至少能确定异常发生的来源。

再次使用代码清单7-1作为讨论点,假设你在loop()函数中定义了一个名为k的变量。因为k的全局范围包括loop()(见图7-4),所以这两个变量不会有名称。

原因是C的语法规则规定,两个或以上的同名变量,在不同作用域级别中,它们执行的优先顺序是语句块最先,再到函数本地作用域,最后是全局范围。在我们的示例中,因为变量k在loop()函数中定义,同时又有全局变量k,这两个同名变量k在执行中,loop()函数范围的变量优先于全局变量k。如果你傻到去定义另一个if语句块中的变量k,则当程序执行if时,k将优先执行,尽管其他两个k变量也在有效范围内。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈