天天看点

《C程序设计新思维》一6.2 持久性的状态变量

本节书摘来自异步社区《c程序设计新思维》一书中的第6章,第6.2节,作者 【美】ben klemens,更多章节内容可以访问云栖社区“异步社区”公众号查看

本章主要讨论自动内存、手工内存和指针的交互,对静态变量的讨论较少,但是静态变量还是很有用处的,因此值得在此花点篇幅探讨一下它们的作用。

静态变量可以具有局部作用域。也就是说,我们可以让一个静态变量只存在于某个函数内部,但是当这个函数执行时,这个变量会保持它的值。因此,它可以作为内部计数器或可复用的临时空间。由于静态变量永远不会移动,因此指向一个静态变量的指针在函数完成执行之后仍然是有效的。

例6-1展示了一个传统的教科书例子:菲波那契数列。我们把前两个成员声明为0和1,以后的每个成员都是它之前两个成员的和。

例6-1 由一个状态机所生成的菲波那契数列(fibo.c)

《C程序设计新思维》一6.2 持久性的状态变量

可以看到main函数何其的简单。这里的fibonacci函数是一台小型的自己运行的机器。main函数只是驱动这个函数运行,由后者不断吐出另一个值。也就是说,fibonacci函数是个简单的状态机,而静态变量正是在c中实现状态机的关键技巧。

在一个必须做到线程安全的世界里,我们应该怎样使用静态的状态机呢?iso c委员会看到了这个问题,因此c11包含了一种_thread_local内存类型。只要把它放在声明中:

《C程序设计新思维》一6.2 持久性的状态变量

就可以为每个线程获取一个不同的计数器。第12章“12.2.2用pthreads轻松实现线程”这一节我将详细讨论这个问题。

《C程序设计新思维》一6.2 持久性的状态变量

静态变量(即便是位于函数内部)是在程序启动之前被初始化的,此时main函数还没有启动,因此我们不能用非常量值对它们进行初始化。

《C程序设计新思维》一6.2 持久性的状态变量

这确实是件麻烦的事情,但是我们可以用一个宏开始为0并在第一次使用时为它分配值的宏来轻易解决:

《C程序设计新思维》一6.2 持久性的状态变量

只要预期绝不会初始化为零(用指针的说法为null),这种方法就是有效的。如果初始化为零,它也会在下一次执行时重新进行初始化。因此,不管是什么情况,这个方法都是可行的。

继续阅读