作为一名在OO出生和成长的开发人员,我很想知道如何在程序性程序中避免全局状态。
答案 0 :(得分:12)
你也可以在C中编写面向对象的代码。你没有得到所有的C ++好东西而且它很难看,你必须手动传递这个指针(我已经看到self
用于此,为了使它与C ++兼容),但它的工作原理。从技术上讲,您不需要纯过程语言中的全局状态,原因与面向对象语言中不需要它的原因相同。你只需要明确地传递状态,而不是像在OO语言中那样隐式地传递状态。
答案 1 :(得分:6)
作为示例,请查看C标准库中的文件I / O函数如何使用指向({很大程度上)不透明的FILE
个对象的指针。或者看看OS API如何处理句柄以及封装信息。程序创建对象,使用作用于这些对象的API并关闭/删除对象 - 所有这些都使用直接C。
答案 2 :(得分:3)
所有面向对象都是一种心态和一大堆编译器支持。
您可以通过规则,编码约定以及在大多数语言中传递结构来实现相同的目标。
例如,我曾经将函数/过程作为其模块标识的前缀,将第一个参数作为相关的模块结构。
// System.h
typedef struct _System
{
struct _System *owner;
LinkedList *elements;
} System;
// System.c
int System_FindName ( System * system, char *name)
{
..
}
等。
我真的非常不想不得不回到这样的编码。我很高兴我至少18年没有编写和调试链表。那时没有互联网很困难,坐在那间隔着冷光明亮房间的角落里,绿色荧光粉燃烧进你的视网膜......
答案 3 :(得分:3)
全局变量只不过是一个隐式过程参数。使它显式,全局变量消失。
注意:您不再使用全局变量的事实并不意味着您不再使用全局状态!我们上面做的只是一个纯粹的语法转换,程序的语义根本没有改变。它就像以前一样不可组合,非模块化,非线程安全,不可并行化。
答案 4 :(得分:2)
当然。只需在某处声明一个struct
,为它分配一些内存,将指针传递给分配的内存到初始化函数,然后关闭。只需将指针传递给需要使用struct的所有函数。
虽然问题在于你将指针存储在哪里,你不希望它是全局的,然后你可能会得到一个全局指针; - )
答案 5 :(得分:0)
您可以在堆栈或堆中拥有在整个程序生命周期中都存在的变量。
将对象样式结构指针传递给每个函数是获得OO C编码风格的好方法。
(我建议看一下linux源代码)
答案 6 :(得分:0)
作为一个例子,您可以尝试使用dia(图表工具)创建一个简单的类(例如,正方形)。
http://projects.gnome.org/dia/
http://dia-installer.de/index_en.html
然后,您可以使用dia2code在C代码中转换该类:
http://dia2code.sourceforge.net/
具体来说,假设你在square.dia图中创建了class square。然后,键入:
$ dia2code -t c square.dia
...你会发现在没有全局变量的情况下,可以在C程序中转换任何面向对象的编程。浏览创建的文件square.c和square.h
注意:在Windows中,您需要一种解决方法才能使dia2code正常工作。在使用dia2code之前,将square.dia更改为square.zip,将其解压缩,并将结果重命名为square.dia
答案 7 :(得分:0)
简单。每当一个过程访问一个全局变量时,就可以通过值或引用或指针,或者通过编程语言提供的任何内容,将此变量作为参数提供给过程。之后,不再需要变量是全局的。