如果我有,假设初始化了一个全局变量F,并在main函数中打印它的值,那么将打印0(应该是)。
但是当我在main函数中传递参数int F,同时以与之前完全相同的方式声明全局变量F时,使用gcc打印F的值会打印1。
任何人都能解释为什么会这样吗?
这是我的代码。
#include<stdio.h>
int F;
int main(int F){
printf("F is %d\n", F);
return 0;
}
答案 0 :(得分:2)
当你的main函数包含一个与全局变量同名的参数时,stub会被引用到局部变量..而不是全局变量
#include <stdio.h>
static int F;
int main(){
printf("F is %d", F);
return 0;
}
答案 1 :(得分:2)
但是当我在主函数中传递参数int F? F
只是参数计数,即argc
。
在特殊情况下,您提到在F
参数中声明的全局F
和main()
是不同的。
int main(int F){ printf("F is %d\n", F); return 0; }
此处printf()
打印1
因为当您运行可执行文件时./a.out
没有命令行输入为1
,它类似于argc
。
您的编译器可能会警告您提供给main()
的参数,使用-Wall
标志进行编译并阅读警告。另请检查main()
原型。从C标准
ISO / IEC 9899:1999
§5.1.2.2.1程序启动
¶1程序启动时调用的函数名为main。该 实现声明此函数没有原型。应该是 使用没有参数的返回类型的intand定义:
int main(void){/ * ... * /}
或有两个参数(这里称为argc和argv,尽管如此) 可以使用名称,因为它们是它们所在的函数的本地名称 声明):
int main(int argc,char argv []){/ ... * /}
或等效的; 9)或其他一些实现定义的方式。
答案 2 :(得分:2)
在您发布的代码中,main
有一个名为F
的参数。在main
内,对F
的任何引用都引用该变量,而不是全局变量。
使用不正确的变量名称会让生活变得更加困难。大多数情况下,main
的参数被命名为argc
和argv
- 参数计数和参数值。
int main(int argc, char** argv) { ... }
使用具有意义的变量名称是很好的。使用int F;
作为全局变量也没有意义。将其命名为有意义。然后,你会遇到像你做的少得多的问题。
答案 3 :(得分:1)
您应该main()
符合标准的要求,您应该打印全局F
以及参数F
:
#include <stdio.h>
int F;
int main(int F, char **G)
{
printf("F is %d\n", F);
{
extern int F;
printf("%s: F is %d\n", G[0], F);
}
return 0;
}
编译时(从源文件quirky43.c
到程序quirky43
),然后运行,我得到:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror quirky43.c -o quirky43
$ ./quirky43
F is 1
quirky43: F is 0
$ ./quirky43 this is why you get command line arguments
F is 9
quirky43: F is 0
$
第一个printf()
正在将第一个参数打印到main()
(通常称为argc
,但调用它F
并没有错,除非它是意外的)。第二个打印全局变量F
(以及程序名称,通常为argv[0]
但是再次使用G
除了意外之外没有任何问题)。一组大括号内的extern int F;
表示该语句块中的F
引用在封闭范围外定义的变量F
,这意味着文件范围变量F
- ,可以注意到,正确初始化为0
。 1
之所以出现是因为您调用了没有参数的程序,并且参数计数包括程序名称。这也是为什么当8个参数添加到命令行时打印的值为9
。
请注意,要使用的另一个好的编译选项是-Wshadow
:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wshadow quirky43.c -o quirky43
quirky43.c: In function ‘main’:
quirky43.c:6:14: error: declaration of ‘F’ shadows a global declaration [-Werror=shadow]
int main(int F, char **G)
~~~~^
quirky43.c:4:5: note: shadowed declaration is here
int F;
^
cc1: all warnings being treated as errors
$
(在运行macOS High Sierra 10.13.5的Mac上使用GCC 8.1.0进行编译。)