如果我想将值修改为函数并将其恢复为主函数,哪一个更好?通过在C中通过引用传递,我的意思是使用指针,就像这个例子。我应该把'a'作为全局变量吗?
#include <stdio.h>
#include <conio.h>
int sum;
int example(int *a,int b)
{
sum = *a + b;
(*a)++;
}
int main(void)
{
int a, b;
printf("Tell me the value of A and B: \n");
scanf("%d %d", &a, &b);
example(&a, b);
printf("The result: %d . And the new value of A: %d", sum, a);
printf("\n\nTHE END\n");
getch();
return 0;
}
答案 0 :(得分:5)
我发现将全局变量视为存在于C程序中正常的函数层次结构之外的特殊空间中会有所帮助。如果您在框中绘制了每个函数的图表,并且在框之间显示哪些函数在执行程序时调用其他函数,main()
将位于顶部(因为它没有调用者),以及所有其他功能将出现在main()
下面的一个或另一个级别上,其中的行会导致其他功能。
大多数数据仅存在于一个函数中 - 在图中的单个框内。有些函数从一个函数传递到另一个函数:C语言中的大多数参数和返回值都适合此类别。但是全局变量是在所有方框之外的 - 在任何功能可以看到和改变它们的地方,以及这种开放性&#34;使它们变得非常危险 - 如果任何函数中的任何代码都可以改变它们,那么对于你来说,或者对于使用相同代码的其他程序员来说,一旦它达到真实世界的大小,它就会很难跟踪可以更改全局数据的所有可能位置。 (这是&#34;可变状态的问题&#34;这对于编程语言来说是常见的,而不仅仅是C,以及面向对象和函数式编程范例在某种程度上的解决。)
在您的示例中,只是您提出问题的事实
如果我想修改哪一个更好 将值转换为函数并将其恢复 到主?
是一个线索,该特定值不应存储在全局变量中。您已将此特定数据概念化为仅在两个函数main()
和example()
之间共享的内容。根据我上面给出的推理,这意味着如果可能的话,变量应作为参数传递给example()
,然后通过main()
的{{1}}返回return
。 {1}}。将指向example()
的指针传递到a
,然后在example()
内修改a
,以便在控件返回给调用者后对example()
的更改仍然存在,是但是需要仔细记录哪些参数可以通过这种方式进行修改,否则你很快就会遇到类似全局数据的情况,只有不那么糟糕,难以理解跟踪a
可能发生变化的地方以及可能发生变化的地方。
这并不是说全局变量都很糟糕。它们存在是有原因的。如果代码的许多部分需要对相同数据的读/写访问权限,并且效率很重要,那么全局变量可能是实现这一目标的最佳方式。在最近经常运行C代码的环境中 - &#34;接近金属,&#34;在嵌入式系统或驱动程序代码中 - 通常有硬件资源,如寄存器或专用内存,可以通过大量的全局变量最有效地访问。或者在某些程序中,您可能需要跟踪大量状态 - 一组变量,其值会影响整个程序的行为 - 并且传递这些值不仅效率低,而且使程序更少 clear因为你有许多参数传递给大量函数。 (这个经典的例子是游戏,游戏世界的当前状态,玩家的位置,生命数量等在某种程度上与大多数代码相关。)即使在这些情况下记录和命名全局变量以使它们与其他类似命名的本地变量或函数参数不冲突至关重要。
有关更高级但相关的主题,请参阅this answer以获取简要说明,或this page进行更长时间的讨论,了解如何限制C中全局的范围(即可见性)使用a
关键字到单个源文件,或在多个文件之间共享。这样可以对全局数据的可访问性进行更细粒度的控制,并有助于减轻上面提到的全局数据的免费使用中的一些问题。
答案 1 :(得分:3)
全局变量的问题是只有一个。一旦你的代码变得有点复杂,并开始使用多个线程,你会遇到只有一个全局变量的问题,如果从两个线程调用该函数,则会出现问题,因为两个调用都使用了一些全局变量。
全局变量的另一个问题是它需要一个唯一的名称。你称你为“总和”。有一段时间你有什么机会可以添加其他函数来添加数字并尝试将它们存储到名为sum的变量中?再一次,你陷入了困境。如果您设法使用不同的变量名称,那么您选择错误名称的可能性有多大?
全局变量的使用应该非常有限。仅将它们用于真正全局的事物,即在应用程序中有两个没有任何意义的地方。
答案 2 :(得分:0)
在这种特殊情况下,最好的办法是
int example(int a, int b)
{
return a + b;
}
int main(void)
{
int a, b;
printf("Tell me the value of A and B: \n");
if (scanf("%d%d", &a, &b) == 2) /* Avoid Undefined Behavior */
{
int sum;
sum = example(a, b);
printf("The result: %d . And the new value of A: %d\n", sum, a);
printf("THE END\n");
}
return 0;
}
当然,没有现实生活计划会有这样的功能。
如果函数只是修改int
,这是避免全局变量的另一个原因,因为你可以从函数返回它,如果它是一个更复杂的情况,那么你可以返回{{1}同样,如果它不符合您的需求,您可以传递/返回指针。