当我运行这个程序时,它输出10 20
(第一个代码片段)。
#include <stdio.h>
int x = 10;
int y = 20;
int main()
{
fun(x, y);
printf("%d %d", x, y);
}
int fun(int x, int y)
{
x = 30;
y = 40;
}
字符串
但是当我这样写的时候:
#include <stdio.h>
int x = 10;
int y = 20;
int main()
{
fun(x, y);
printf("%d %d", x, y);
}
int fun(int n1, int n2) // I include other variables except from global variable.
{
x = 30;
y = 40;
}
型
它输出30 40
。我想知道为什么它修改全局变量只有第二个代码片段,即使没有使用指针?为什么第一个不是?如果有人建议我参考这个理论部分,我会很充分。
我想正确地学习这些理论部分,因为我是编程新手。
4条答案
按热度按时间b1uwtaje1#
对于初学者,请注意函数
fun
应在其在main
的主体中使用之前声明。在第一个函数中
字符串
存在作为函数的局部变量的改变的函数参数
x
和y
。参数由文件范围全局变量x
和y
的值初始化,但全局变量本身没有更改。在函数中,全局变量
x
和y
被同名参数隐藏。因此,函数处理的是参数而不是全局变量。您可以使用以下技巧来更改函数中的全局变量
型
在这种情况下,函数内部块中的声明
型
引用具有外部链接的全局变量,并且全局变量被改变。
在第二个函数中,不使用参数。
型
在这种情况下,编译器会发出一条关于未使用参数的消息。
在函数中直接改变全局变量。文件作用域变量
x
和y
在函数体中是可见和可访问的。您可以按以下方式考虑第二个函数的主体
型
jgwigjjp2#
在第一个示例中,您正在修改局部变量
x
和y
,它们是作为函数fun
的参数创建的在第二个示例中,您将不修改这些参数,而是修改全局变量
x
和y
如果你想修改第二个例子中的参数,你可以修改
字符串
t1qtbnec3#
正如您所了解的,在C中,函数参数是通过值传递的,因此当调用
fun(x, y)
时,您将全局变量x
和y
的当前值传递给函数fun
。在第一个例子中,函数
fun
被定义为函数参数的名称x
和y
。在函数体中,当引用x
和y
时,参数定义在作用域中,修改x
和y
只修改参数值,这些值是函数的局部值。全局变量不受影响。当一个局部定义在外部作用域中隐藏了另一个局部定义时,我们说外部定义被内部定义 * 遮蔽 * 了。这有点令人困惑和容易出错:如果将-Wall -Wextra
传递给gcc或clang编译器,则会在这种情况下启用警告。在第二个例子中,函数参数被定义为
n1
和n2
,因此函数体中的代码确实修改了全局变量x
和y
,并且实际上程序输出了修改后的值。还请注意这些备注:
main
的原型是C中的int main(void)
;fun
应该在使用前声明或定义。编译器宽容地接受这个调用,并从函数参数中推断出原型为int fun(int, int)
,这与后面的函数定义一致。支持这种ANSI之前的行为是为了与旧代码兼容,例如原始K&R书中的示例,但现代C程序不应依赖于此,额外的警告级别将对此提出异议。main
函数应该返回0
成功,尽管C99在没有return
语句的情况下将其作为默认行为。%
或$
。fun
被定义为返回一个int
,但是该函数在没有return
语句的情况下退出。您应该将函数定义为void
,以避免未定义的行为。以下是修改后的版本:
字符串
ryoqjall4#
在第一个代码片段中,fun函数通过值接收参数x和y,这意味着该函数创建了这些变量的本地副本。对这些局部副本所做的任何修改都不会影响在main函数外部定义的原始全局变量x和y。因此,当您在调用fun后在main函数中打印x和y时,它们的值保持不变,导致打印“10 20”。
在第二个代码片段中,您使用了与fun函数中的全局变量相同的变量名x和y。这会产生歧义,因为函数参数n1和n2与全局变量具有相同的名称。在这种情况下,当你在fun函数中为x和y赋值时,它会修改全局变量本身,因为它们具有相同的名称。这称为隐藏,其中局部变量隐藏具有相同名称的全局变量。因此,当您在调用fun后在main函数中打印x和y时,您会看到修改后的值“30 40”,因为全局变量是在函数中直接修改的。
为了避免混淆和类似的潜在问题,通常建议在函数中为局部变量使用不同的名称,以清楚地将它们与全局变量区分开来。这有助于提高代码的可读性,并避免对全局变量的无意修改。
要进一步了解变量作用域和隐藏,您可以参考详细介绍这些主题的C编程语言教科书或在线资源。一些推荐的资源包括Brian Kernighan和Dennis里奇的“C编程语言”或tutorialspoint.com或cplusplus.com等网站。