您的位置:首页 > 其它

函数原型,函数声明,函数定义,他们的三角关系

2016-05-14 15:51 417 查看
前景提示:c语言的标准从K&Rc,c89(ANSI c),c99,c11不断的发展,新标准不断的提出。但是,目前大部分编译器对c89完全支持,其他的标准可能就只是部分支持。c89是在K&Rc的基础发展而来,所以,K&R c 中的一些老式风格,许多编译还是支持。这就为我编写移植良好的程序带来许多问题。函数定义:声明  +  具体实现 。它向编译器提供函数的信息,以及调用函数时的操作。
int fun( int a, int b){a + b;printf("%d",a);return 0;}
编译器得知的信息:(1)函数的返回值(2)参数的类型,参数的个数。这都是声明做的工作,所以在后期调用函数时,编译器会检查函数的使用情况,确保函数正确调用。函数实现就是 { .... } 花括号中的代码老式的代码风格
int fun( a , b )int a ;int b;{a + b;printf("%d",a);return 0;}
区别:参数的类型写在参数的列表和左花括号之间。缺点:编译器只会记住函数 的返回类型,关于参数个数以及类型,编译器不管
#include<stdio.h>int fun();//编译器记住的信息int main( void ){int a = 1;int b = 2;fun( a );}int fun( a,  b )int a;int b;{printf("%d",a);return 0;}
gcc 编译完全没问题,并且不会报错,或警告函数声明:向编译器提供函数的信息,确保函数正确调用。一般,向函数提供编译的信息有两种,一种是是没有参数的列表(老式风格),编译器只会记住返回值。另一种是函数原型(新式风格,现在我们一般写的,所提倡的)。函数原型
int fun( int a, int b);
优点:编译器知道参数类型,个数,当参数不匹配,会向用户发错警告。还有些关于原型你必须知道的事。(1)函数原型像变量一样具有作用域。
int main( void ){{int fun( int a ,int b);fun();}......{int fun( int a ,int *b);fun();}}
虽然你可能不这样写,但是编译器还是不会报错,你两个fun函数不一致,一定有哪里写错了,最好函数原型有文件作用域,放在头文件中,或者位于main函数前。(2)函数原型中可以不写参数名
int fun( int , int );
编译器不关心变量名,实际上,代码翻译成机器码,根本没有变量名,有的只是一个个地址(不同地址对于不同变量)。但是程序是给人看的,所以在函数原型中的变量名最好能体现变量在函数中的作用,让程序员很快知道你函数的功能,这是一个不错的代码习惯。没有参数列表(老式风格)
int fun( );
这种写法很常见,也许曾经就出现在你的代码中。你会说我这是一个参数为0的函数,可是编译器却不这么认为,即使你调用函数fun(a ,b ,c ..... ),这样写也不好出错。原因在于,只要声明函数时,不使用函数原型,编译器都不会记住参数相关信息。所以,区分有没有参数应该加void
int fun( void );int fun( );//二义性,是新风格无参函数,还是旧风格 忽略参数列表的声明
再提一点:函数声明省略时,系统会添加一个返回值为int 同名函数声明
#include<stdio.h>//int fun();  编译自动添加int main( void ){float a = fun();printf("%lf",a);}float fun(){return 3.14;}
当你写的函数返回值为int,你忽略了编译可能不发出警告,因为它默认帮你添加。当函数返回值是其他类型,记得写函数原型很有必要。函数原型:函数声明的一种情况。关于他们的三角关系,有了一个大致的了解定义实现了声明的功能,但不等同与声明。原型是声明的一种 。定义只能一次,声明可有多次(是不是想起,变量的定义和声明 )。以上的所有情况,你或许见过,或许没见过,但是他们是真是存在的,好的代码风格,程序会有好的移植性
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: