Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C全球变量的适当使用_C_Shell_Arguments_Global Variables_Main - Fatal编程技术网

C全球变量的适当使用

C全球变量的适当使用,c,shell,arguments,global-variables,main,C,Shell,Arguments,Global Variables,Main,我正在用C语言构建一个迷你shell,遇到了一个障碍,似乎可以通过使用全局变量(确切地说是3)轻松解决这个问题。我之所以认为全局变量是必要的,是因为替代方法是将这些变量传递给我程序中的几乎每个函数 变量为mainargc、mainargv和shiftedMArgV。前两个分别是传递给main的参数数和参数列表。变量shiftedMArgV是参数列表,但它可能已被移位。我试图创建内置函数shift和unshift,并使shiftedMArgV指向不同的参数 那么,仅仅把这些全球化是愚蠢的吗?否则,

我正在用C语言构建一个迷你shell,遇到了一个障碍,似乎可以通过使用全局变量(确切地说是3)轻松解决这个问题。我之所以认为全局变量是必要的,是因为替代方法是将这些变量传递给我程序中的几乎每个函数

变量为mainargc、mainargv和shiftedMArgV。前两个分别是传递给main的参数数和参数列表。变量shiftedMArgV是参数列表,但它可能已被移位。我试图创建内置函数shift和unshift,并使shiftedMArgV指向不同的参数

那么,仅仅把这些全球化是愚蠢的吗?否则,我将不得不修改大量的代码,我不确定通过使它们全球化会损失什么

如果我真的让它们成为全局的,那么从主头文件这样做会很愚蠢吗


感谢大家的帮助,如果你需要任何澄清,请询问。

全球人是可以的,只要他们在逻辑上是真正的全球人,而不仅仅是为了让你的生活更轻松。例如,globals可以描述程序执行的环境,或者换句话说,描述与应用程序的系统级相关的属性。

几乎所有我使用过的复杂软件都有一组定义良好的globals。这没什么错。它们的数量从一小撮到十几只不等。在后一种情况下,它们通常在结构中进行逻辑分组


全局变量通常在头文件中作为外部变量公开,然后在源文件中定义。请记住,全局变量是在线程之间共享的,因此必须加以保护,除非使用线程本地存储声明它们更有意义。

我想说这并不愚蠢,但您应该谨慎行事

通常避免使用globals的原因并不是因为永远不应该使用globals,而是因为globals的使用经常导致程序员崩溃和烧坏。通过经验,一个人学会了何时是正确的时间和何时是错误的时间之间的区别

如果您已经深入思考了您试图解决的问题,并考虑了您为解决此问题而编写的代码,同时也考虑了此代码的未来(即,您是否在损害可维护性),并且认为全局性是不可避免的,或者更能代表编码的解决方案,那么您应该使用全局性

稍后,你可能会崩溃和烧毁,但这种经历将帮助你以后辨别出更好的选择可能是什么。相反,如果你觉得不使用globals可能会导致crashage和burnage,那么这就是你之前的经验,你应该使用globals。你应该相信这种直觉

Dijkstra在书中讨论了“goto”语句可能造成的伤害,但在我看来,他的讨论也解释了我们在全球化方面的一些困难。也许值得一读


也可以使用。

< P>作为全局变量的替代,考虑“全局函数”:

extern int    msh_mainArgC(void);
extern char **msh_mainArgV(void);
extern char **msh_shiftedArgV(void);
这些函数的实现很简单,但它允许您控制对内存的访问。如果您需要做一些有趣的事情,您可以更改函数的实现。(我选择将C和V大写,以使差异更加明显;当一个8-12个字母的名称中只有最后一个字符不同时,很难发现差异。)

将有一个实现文件来定义这些函数。在该文件中,将有存储相关信息的静态变量,以及设置和操作变量的函数。原则上,如果使用了足够多的
const
限定符,则可以确保调用代码不能修改数据,除非通过设计用于修改数据的函数(或使用强制转换来删除const)

这对你来说是否值得值得值得商榷。但可能是这样。这是一种更接近“面向对象”的操作方式。这是一种考虑,然后放弃,而不是一些不考虑的东西。
请注意,使用这些函数的子系统可能有一个函数收集全局值,然后将这些值传递给其下属函数。这使下属不必知道价值观的来源;只有正确地使用它们,机器才能正常工作。如果存在全局变量,则必须担心别名-函数传递了值(全局变量的副本),但它是否也访问全局变量。对于函数,您不必以同样的方式担心这个问题。

对于shell,您拥有的状态比这个多得多。您拥有重新映射的文件描述符的状态(出于各种原因需要跟踪这些描述符)、
trap
dispositions、
set
选项、环境和shell变量

一般来说,全局变量是错误的解决方案。相反,所有状态都应该保存在某种上下文结构中,指向该结构的指针到处传递。这是一种很好的程序设计,通常允许您在同一进程中运行同一代码的多个实例(例如多个解释器、多个视频解码器等)

话虽如此,shell是一种非常特殊的情况,因为它还处理许多无法保存在结构中的全局状态:信号处理、文件描述符和映射、子进程、进程组、控制终端、,等。可能可以通过一个额外的层来抽象其中的很多内容,这样您就可以模拟所需的行为,同时保持在单个进程中以多种形式存在的干净上下文,但这比编写传统shell困难得多。因此,我可能会给你自己一些余地,让你用全局变量“懒惰的方式”编写shell。如果这是一个l