c语言声明函数位置 c语言声明函数和定义函数( 三 )


由此可见,古老的、不对参数进行任何说明的函数类型说明方式、函数定义以及函数原型式的函数类型说明方式都具有说明函数名意义的效用 。从这个意义上讲它们都是函数声明 。在C语言中,声明(Declaration)这个词的本义就是指定标识符的意义和性质(A declaration specifies the interpretation and attributes of a set of identifiers.),某个标识符的定义(Definition)同时也是这个标志符的“声明”(Declaration) 。函数定义(Function definition)则意指包括函数体 。(A definition of an identifier is a declaration for that identifier that: ……for a function, includes the function body;) 。函数原型则特指包括说明参数类型的函数声明 , 它同样包含用这种方式写出的函数定义 。
现在回过头来看样本中的第一句话:“对函数的“定义”和“声明”不是一回事” 。由于函数定义本身就是一种函数声明,怎么可以说它们不是一回事呢?这句话的逻辑就如同说“男人”和“人”不是一回事 。你可以说男人和女人不是一回事,因为他们没有交集 。但没法说男人和人不是一回事,因为男人是人的子集,男人就是人的一种,怎么可以说男人和人不是一回事呢?
那么,不带函数体的函数声明应该如何称呼呢?在C语言中,它们叫被做“函数类型声明”(Function type declaration) 。函数类型声明最主要的特点是声明了函数名是一个函数及其返回值的类型,如果也声明了参数的类型 , 则是函数原型式的函数类型声明 。
样本中的“而函数的声明的作用则是把函数的名字,函数类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时进行对照检查(例如,函数名是否正确,实参与形参的类型和个数是否一致),它不包括函数体”这句话同样不通 。其主要错误是它混淆了“函数原型式类型声明”与“函数声明”这两个概念 , 前一个概念只是后一个概念的子集 。函数声明中不但包含“函数类型声明”,也包含“函数定义”和老式的“函数类型声明” 。由于函数定义本身就是一种函数声明,所以无法断定函数的声明是否包括函数体;而且老式的函数类型声明(例如double sqrt();)也属于函数声明,这种函数声明并不检查参数类型及个数方面的错误 。此外函数声明也并没有检查“函数名”正确与否的功能 。
这段文字中的“函数类型”这个概念也有错误,函数类型所描述的不但包括函数返回值类型 , 也可能一并描述参数的个数和类型(如果是函数原型),因此不能与“形参的类型、个数”相提并论 。
现代的C语言的函数定义和函数类型声明都采用函数原型式的风格,C99把旧的非原型形式视为过时 , 这意味着非原型形式以后可能被禁止 。
main()函数
在各种C语言书上,能看到各式各样main()函数的写法,简直令人无所适从 , 这是这么回事?原因主要有两个:一个是随着C语言的发展和演化,main()函数的写法也在不断变化;另外,某些书籍写法不规范或误导的现象也同时存在 。
最初main()函数的写法非常简洁,那个时候的C程序员哪怕一个字符似乎都不肯多写 。不知道是因为当时键盘质量不好还是因为编辑器太糟糕的缘故,那个时代的C程序员似乎惊人地一致崇尚“简约”——甚至可以说是“至简” 。
?
1234
main(){ printf("hello,world\n");}
这就是main()函数最古老的写法 , KR在他们的经典名著《The C Programming Language》中的第一个C语言源程序(1978) 。这种写法是那个时代的主流 。
简直和裸体差不多,连#includestdio.h也没有么?在《The C Programming Language》的第一版中确实没有 。那个时代的C语言,返回值类型为int的函数不用声明 。不过在该书的第二版(1988)中这个程序被改成了:

推荐阅读