版权声明:本文转载于公众号TeachPlus---C语言面试题---main函数
1、下面的代码能编译通过吗?如果能,它有什么潜在的问题吗?
在绝大多数的编译器中,该段代码都是可以编译通过的,但是可能会报出警告。main()的返回类型应该是“int”而不是“void”。因为“int”返回类型会让程序返回状态值。这点非常重要,特别当程序是作为依赖于程序成功运行的脚本的 一部分运行时。
我们可能在许多地方都会看到这样的写法,或者其他多种多样的写法,这让初学者,甚至 一部分老手都会搞不明白main函数到底应该怎么去写。下面就是几种常 见的main函数的写法:
1.
int main()
{
//do something
return 0;
}
这是大家最常见的写法,那么这种写法好不好呢?
这种写法会产生歧义,函数main是有参数,还是没有参数。
你可能觉得很奇怪,它明明是没有参数的,但编译器 可不这么认为。
不同编译器 可能有不同解释。原因在于要与旧式代码风格的兼容。如下面的代码:
int fun()
int main()
{
//do somethings
return 0;
}
int fun(int a,int b)
{
//do somethings
}
int main()
{
//do somethings
return ;
}
int fun(int a,int b)
{
//do somethings
}
这段代码编译完全没有问题,可是fun函数明明是有参数的.
这种写法,编译器只会记住函数的返回类型,并不会检查函数的参数个数和类型是否匹配。你写了了这么多,编译器就只记住intfun() ;
所以,只能通过这种形式main( void ),表明main函数没有参数
2.
void main()
{
//do somethings
}
这种写法的流传也非常广泛,因为许多教科书里就是这么写的, 而且绝大部分编译器 都能够正常编译。
虽然在 一些编译器中,voidmain可以通过编译(如vc6)。
并且编译器 对于你写的voidmain,在实际编译的时候还是默认返回一个int.
有些编译器允许这种形式,但是还没有任何标准考虑接受它。
C++之 父Bjarne Stroustrup在他的主 页上的FAQ中明确地表示:
voidmain()的定义从来就不存在于C++或者C。
所以,编译器不必接受这种形式,并且很多编译器也不允许这么写。
我们要考虑程序的可扩展性,养成 一个良好的习惯。
3.
main()
{
//do somethings
}
这种方法比较罕见,但是现在仍然有很多编译器支持这种写法。
这种写法往往存在于非常老的c语 言版本中。
C90标准允许这种形式,但是C99标准不允许。因此即使你当前的编译器允许,也不要这么写.
正本清源
其实在C99标准中,只有以下两种定义 方式是正确的:
int main(void) /*无参数形式*/
{
//do somethings
return 0;
}
int main(int argc, char*argv[]) /*带参数形势*/
{
//do somethings
return 0;
}
int指明了了main()函数的返回类型,函数名后面的圆括号 一般包含传递给函数的信息。void表示没
有给函数传递参数。
main函数可以不带参数,也可以带参数,这个参数可以认为是main函数的形式参数。C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv。因此,main函数的函数头可写为:
main (argc,argv)
C语言还规定argc(第 一个形参)必须是整型变量,argv(第 二个形参)必须是指向字符串的指针数组。加上形参说明后,main函数的函数头应写为:
main (int argc,char *argv[])
由于main函数不能被其它函数调用,因此不可能在程序内部取得实际值。那么,在何处把实参值赋予main函数的形参呢?实际上,main函数的参数值是从操作系统命令 行上获得的。当我们要运行 一个可执行文件时,在命令提示符下键 入文件名,再输入实际参数即可把这些实参传送到main的形参中去。
Linux命令提示符下的 一般形式为:
ubuntu@ubuntu:~$./可执 行行 文件名 参数1参数2……;
但是应该特别注意的是,main的两个形参和命令行中的参数在位置上不是 一 一对应的。因
为,main的形参只有二个, 而命令行中的参数个数原则上未加限制。argc参数表示了了命令行中参
数的个数(注意: 文件名本身也算 一个参数),argc的值是在输入命令行时由系统按实际参数的个
数 自动赋予的。
例如有命令 行行为:
ubuntu@ubuntu:~$./a.out BASIC foxpro FORTRAN
由于文件名a.out本身也算 一个参数,所以共有4个参数,因此argc取得的值为4。argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理理)的首地址。 指针数组的长度
即为参数个数。数组元素初值由系统自动赋予。其表示如下所示:
int main(int argc,char *argv[])
{
int i = 0;
for(i = 1 ; i< argc; i++)
{
printf("%s\n",argv[i]);
}
return 0;
}
本例是显示命令行中输入的参数。如果上例的可执行文件名为a.out,因此输入的命令行为:
ubuntu@ubuntu:~$./a.outBASIC foxpro FORTRAN
则运 行行结果为:
BASIC
foxpro
FORTRAN
该行共有4个参数,执行main时,argc的初值即为4。argv的4个元素分为4个字符串的首地址。