Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么程序会编译?_C_Function_Kr C - Fatal编程技术网

C 为什么程序会编译?

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函

我只是试图理解这段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
函数的有效声明,请参见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 ... */
}