C 为什么程序会编译?
我只是试图理解这段C代码(而不是试图通过程序实现任何功能目标)。这是使用gcc编译的。 这是主楼吗 main(int a,char*argv[]) 格式?是否允许在参数和函数体之间声明任何内容(类似于char*a;此处)C 为什么程序会编译?,c,function,kr-c,C,Function,Kr C,我只是试图理解这段C代码(而不是试图通过程序实现任何功能目标)。这是使用gcc编译的。 这是主楼吗 main(int a,char*argv[]) 格式?是否允许在参数和函数体之间声明任何内容(类似于char*a;此处) #包括 干管(u,u,a) 烧焦 *a; { //printf(“%s\n”,u,a);//只是为了帮助调试 //printf(“%d\n”,u);//只是为了帮助调试 } 这是一种无效的main声明形式。这在C99/C11中无效,但在C90中也无效。 (关于C90中main函
#包括
干管(u,u,a)
烧焦
*a;
{
//printf(“%s\n”,u,a);//只是为了帮助调试
//printf(“%d\n”,u);//只是为了帮助调试
}
这是一种无效的main
声明形式。这在C99/C11中无效,但在C90中也无效。
(关于C90中
main
函数的有效声明,请参见5.1.2.2.1)。这是一个古老的声明,除了混淆之外,没有人再使用它了(另请参见:trigraphs!)。我认为这在新的C标准下是非法的,但是gcc仍然支持它的向后兼容性
它的工作方式是在函数下列出类型,而不使用返回类型。无返回类型表示它默认为int
。典型的主功能可以这样编写:
main(argc, argv)
int argc;
char** argv;
{
printf("%d\n", argc);
return 0;
}
不能在大括号开始之前声明其他变量。尝试添加intc代码>并获取此错误:
test.c:4: error: declaration for parameter ‘c’ but no such parameter
参数列表和函数体之间的声明是所谓的K&RC(C的第一个版本)的一部分。因此,如果编译器可以编译K&R代码,那么它们是有效的
关于main()
具有两个以上参数。。。是的,事实上,main最多可以有三个参数:
int main (int argc, char *argv[], char *envp[]);
第三个参数是指向字符串的指针数组,其中每一个都包含一个环境变量定义(字符串的形式为name=value
)这是一种陈旧的编写C函数的方法
在C的祖先语言中,没有类型:所有变量都包含一个机器字。因此,函数定义的开头是这样的:
main(u, _, a) {
/* ... some code ... */
}
,从(Brian Kernighan和Dennis Ritchie)的作者那里被称为“K&R C”,以一种看起来像变量声明的形式添加类型,并且介于函数参数列表和函数代码之间
int main(u, _, a)
int u;
int _;
char *a;
{
/* ... some code ... */
}
在K&R C中,如果一个类型是int
,那么在许多地方它可以省略。对于函数参数,可以完全省略类型声明行
int main(u, _, a)
char *a;
{
/* ... some code ... */
}
1989年标准化,其主要创新之一是功能原型。在正确的ANSI C中,在使用之前声明所有函数,并声明所有参数的类型
int main(int u, int _, char *a)
{
/* ... some code ... */
}
C编译器仍然支持旧形式的遗留代码。(如果它们符合1989年的C标准,它们就必须这么做。)20多年后,遗留代码就不多了,所以您不会经常找到这样的代码
(请注意,对于main
,这不是正确的类型。我认为Gcc会就此向您发出警告,但您可能必须将警告设置调高。)看起来像是C89之前的函数。添加一个不值得回答的有趣事实:在编写16位可引导程序时,我必须使用这种类型的函数声明。gcc不能编译到16位,所以我不得不使用不支持ANSI的bcc(Bruce的C编译器)。所以你可能会在某些领域遇到这种东西!因此,“为什么它还需要编译”的答案是“因为GCC过于宽容”。虽然从技术上讲这是正确的,但这是毫无帮助的,并且没有回答为什么编译器会接受这样的无效代码的问题。这是因为它是K&R c。不幸的是,未指定的类型都是int
@ouah-Yap@user1741125,正如我所说,它是C90中的5.1.2.2.1。它是C89中的2.1.2.2。关于C99和C11,不再允许省略函数声明的int
返回类型。
int main(int u, int _, char *a)
{
/* ... some code ... */
}