C 关于函数和参数的几个问题
所以我在一本书中学习函数C 关于函数和参数的几个问题,c,bash,function,shell,C,Bash,Function,Shell,所以我在一本书中学习函数 它说,我们需要对函数进行原型化或声明,以便编译器能够理解它们是否被正确调用 但是为什么main函数在没有原型的情况下工作 在我的学习过程中,我经常这样写主要函数: int main(void) 由于(void) 我试图用参数运行我的程序,例如./a.out 2 int main(int y){ printf("%s %d\n","y is",y); } 当我正常运行它时,y是1,当使用>运行它时。/a.out 1
main
函数在没有原型的情况下工作
int main(void)
由于(void)
我试图用参数运行我的程序,例如./a.out 2
int main(int y){
printf("%s %d\n","y is",y);
}
当我正常运行它时,y
是1,当使用>运行它时。/a.out 1
y
是2,当有多个参数时,它增加1。所以这不是正确的方法,但是什么原因造成的呢
将y
声明为char
不会说明什么,所以我猜它的工作原理与scanf()的返回值类似。它返回成功输入的数量
函数在调用之前必须声明(即原型)或定义。
main
函数与其他函数的不同之处在于,它由程序启动代码调用,而不是由其他函数调用
但是,main
的签名有限制。在常规托管实现中,C标准表示它可以是:
int main(void)
或:
后一种情况用于读取命令行参数argc
包含参数传递的数量,包括程序名argv
将实际参数作为char*
数组包含
许多系统还支持:
int main(int argc, char **argv, char **envp)
其中envp
包含程序已知的环境变量
您正在使用的原型:intmain(inty)
在我所知道的任何实现中都不受支持,因此尝试将这样的原型用于main
调用
当我正常运行它时,y
是1,当使用>运行它时。/a.out 1
y
是2,当有多个参数时,它增加1。所以这不是正确的方法,但是什么原因造成的呢
程序启动的标准条目回答了您的两个问题:
N1570§5.1.2.2.1程序启动
1程序启动时调用的函数名为main
实现没有声明此函数的原型。应使用返回类型int
进行定义,且无参数:
int main(void) { /* ... */ }
或具有两个参数(此处称为argc
和argv
,,尽管可以使用任何名称,因为它们是声明它们的函数的本地名称):
[……]
正如公认的答案中已经说明的那样,这些是标准所允许的仅有的两个main
实现
该标准保留了处理未定义构造的责任,并且没有对行为应该是什么强加任何要求,给定的实现可以以其认为合适的任何方式处理这种情况,这称为
似乎正在发生的事情是,编译器假设
y
是argc
,这是允许的(正如您在上面突出显示的引文的第二个片段中所看到的),并且argc
在命令行中存储参数的数量,这与您得到的结果一致,但是,在不同的编译器、系统甚至同一编译器的版本中,这种行为可能会有所不同。我认为您的一些问题的答案可以查看。请分别提问。当你同时问几个不同的问题时,那些只知道其中一些问题答案的人可能不愿意回答,因为他们无法提供完整的答案。花几天时间阅读和讨论。我猜你正在使用Linux。比如,Linux是免费软件,你可以下载并研究它的源代码code@BasileStarynkevitch是的,我在用linux。顺便说一句,谢谢你的推荐书。似乎是我在寻找我的最后一个问题阅读的文档,然后用gcc-Wall-Wextra-g
编译您的C代码,谢谢。但是argc
和y
都可以作为启动代码调用的参数数量main
,与是否需要“原型”无关。(“Prototype”是一个错误的术语;C标准将其定义为包含参数类型的函数声明,而不是()
。这里真正有争议的是函数声明。)在现代C中,所有函数标识符在使用之前都必须声明main
在其定义中声明,不需要任何单独的声明,因为它通常不在程序的C源代码中使用。如果使用它,它需要一个声明,与任何其他标识符相同。@IMIEET参数的名称可以自由更改。重要的部分是参数的数量和类型。@imieet:C标准提供的main
的标准声明是intmain(void)
和intmain(int,char**)
,在int
和char**
之后可以填写任何参数名称。名称是不相关的,但具体形式是相关的:要匹配其中一种形式,您必须具有void
,或者必须具有两个参数,第一个参数类型为int
,第二个参数类型为char**
intmain(int)
与其中一个不匹配,因此使用它违反了C标准中的规则,除非您的实现定义了它。
int main(void) { /* ... */ }
int main(int argc, char *argv[]) { /* ... */ }