为什么部分函数仅有函数原型声明明没有实现函数功能的函数体

> 头文件只是声明函数,为什么引入头文件就可以使用其中的函数?解决办法
头文件只是声明函数,为什么引入头文件就可以使用其中的函数?解决办法
qiming123go & &
发布时间: & &
浏览:6 & &
回复:4 & &
悬赏:0.0希赛币
头文件只是声明函数,为什么引入头文件就可以使用其中的函数?如题
如果是你自定义的函数只有声明没有定义就不行.标准库中的函数,我们只看到声明,是因为它的定义一般已编译在.lib文件中,而这些lib文件,默认已加入工程中,连接时会找到这些函数定义.qimingzhi & &
11:25:26 & &
& & (2)(0)引用连接器会帮你链接到相应的函数的
qimingzhi & &
11:25:26 & &
& & (0)(0)引用#include 指令表示把某文件包含到某个编译单元,如果已经包含则跳过通常在头文件里只是关于某个函数(这里以函数为例)的说明,也就是告诉编译器某个函数应该怎么调用因为C++有强类型检查,必须对参数进行检查,如果是C的话不用包含也不用怕,直接使用!当编译这个编译单元的时候,这个函数就是一个外部链接符号,在链接的时候在其它编译单元实现!
qin_er & &
11:25:26 & &
& & (0)(0)引用LZ是想问头文件里的函数原型在哪里吧?一般把头文件里的函数的实现代码封装在库里头,比如C标准库、C++标准库,头文件是留给用户的接口。
qiminhua000 & &
11:25:26 & &
& & (0)(0)引用
本问题标题:
本问题地址:
温馨提示:本问答中心的任何言论仅代表发言者个人的观点,与希赛网立场无关。请对您的言论负责,遵守中华人民共和国有关法律、法规。如果您的言论违反希赛网问答中心的规则,将会被删除。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&1.1&函数的原型和调用在使用函数前必须定义或者声明函数double&circle(double&r);int&main(){& &double&length = circle(10);& &printf("length = %f\n", length);& &return&0;}&double&circle(double&r){& &return&2&* 3.14&* r;}&1.2&函数的形参与实参在调用函数的时候,函数大多数都有参数,主调函数和被调用函数之间需要传递数据。在定义函数时函数名后面括弧中的变量名称为“形式参数”,简称形参。在调用函数时,函数名后面括号中的变量或表达式称为“实际参数”,简称实参。1形参在未出现函数调用时,他们并不占用内存单元,只有在发生函数调用的时候形参才被分配内存,函数调用完成后,形参所占的内存被释放2实参可以是变量,常量或者表达式3在定义函数时,一定要指定形参的数据类型4形参与实参的数据类型一定要可兼容5在C语言中,实参与形参的数据传递是“值传递”,即单向传递,只由实参传递给形参,而不能由形参传递给实参。如果函数的参数是个数组,那么是可以通过形参修改实参的值的1.3&函数的返回类型与返回值1函数的返回值通过函数中的return获得,如果函数的返回值为void可以不需要return语句。2函数return语句中的返回值数据类型应该与函数定义时相同。3如果函数中没有return语句,那么函数将返回一个不确定的值。1.4&main函数与exit函数与函数的return语句int&test1(){& printf("111111\n");& //return 0;& exit(0);//在子函数中调用exit同样代表程序终止,但在子函数中调用return只是子函数终止,程序正常执行& printf("222222\n");}&int&main(){& test1();& printf("AAAAAA\n");& exit(100);//exit是C语言的库函数,调用exit的结果就是程序终止& return&100;//在main函数中调用exit与调用return是一样的& printf("CCCCCCC\n");&& return&0;//main函数return代表程序终止printf("BBBBBB\n");}&&1.5&多个源代码文件程序的编译1.5.1&头文件的使用如果把main函数放在第一个文件中,而把自定义函数放在第二个文件中,那么就需要在第一个文件中声明函数原型。如果把函数原型包含在一个头文件里,那么就不必每次使用函数的时候都声明其原型了。把函数声明放入头文件是很好的习惯。1.5.2&#include与#define的意义#include就是简单的文件内容替换#define就是简单的文本替换而已1.5.3&#ifndef与#endif#ifndef的意思就是条件预编译,如果#ifndef 后面的条件成立,那么就预编译从#ifndef开始到#endif之间的代码,否则不会去预编译这段代码&1.6&函数的递归函数可以调用自己,这就叫函数的递归void&recurse(int&i){& &if&(i&& 0)& &{& & &recurse(i&- 1);& &}& &printf("i = %d\n", i);}&int&main(){& &recurse(10);& &return&0;}&1.6.1&递归的过程分析void&up_down(int&&n){& printf("in %d, location %p\n", n, &n);& if&(n&& 4)& & up_down((n&+ 1));& printf("out %d, location %p\n", n, &n);}&int&main(){& up_down(1);& return&0;}&& & & &有n个人排成一队,问第n个人多少岁,他回答比前面一个人大2岁,再问前面一个人多少岁,他回答比前面一个人大2岁,一直问到最后问第一个人,他回答10岁int&age(int&n){& int&i;& if&(n&== 1)& & i = 10;& else& & i = age(n&- 1) + 2;& return&i;}&将10进制数转化为二进制数的例子234在十进制下为2 * 10的2次方 + 3 * 10的1次方 + 4*10的0次方。奇数的二进制最后一位一定是1,偶数的二进制最后一位一定是0。可以通过 number % 2 得到二进制形式的最后一位,如果要将一个完整的整数转化为二进制就需要用到递归函数。在递归调用之前,计算 number % 2的值,然后在递归调用语句之后进行输出,这样计算出的第一个数值反而在最后一个输出。为了得出下一个数,需要把原数除以2,这种计算相当于十进制下把小数点左移一位,如果此时得出的数是偶数,,则下一个二进制的数值是0,如果得出的是奇数,那么下一个二进制数为1。直到被2除的结果小于2,就停止递归。void&to_binary(unsigned&int&n){& unsigned&int&i = n&% 2;& if&(n&&= 2)& & to_binary(n&/ 2);& printf("%c", i + 0x30);}&&斐波那契数列例子斐波那契数列指的是这样一个数列 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...第0项是0,第1项是第一个1。这个数列从第2项开始,每一项都等于前两项之和。int&fib(int&n){& if&(n&== 0)& & return&0;& if&(n&== 1)& & return&1;& if&(n&& 1)& & return&fib(n&- 1) + fib(n&- 2);}&1.6.2&递归的优点递归给某些编程问题提供了最简单的方法1.6.3&递归的缺点一个有缺陷的递归会很快耗尽计算机的资源,递归的程序难以理解和维护。C语言编程学习(cyuyanxuexi) 
 文章为作者独立观点,不代表大不六文章网立场
cyuyanxuexiC语言的主要用途是用来编写应用软件、系统软件、驱动、手游底层开发,中小型的游戏,服务器开发,工业机器制造等热门文章最新文章cyuyanxuexiC语言的主要用途是用来编写应用软件、系统软件、驱动、手游底层开发,中小型的游戏,服务器开发,工业机器制造等&&&&违法和不良信息举报电话:183-
举报邮箱:
Copyright(C)2016 大不六文章网
京公网安备78&&&&& 对函数的&定义&和&声明&不是一回事。函数的定义是指对函数功能的确立,包括指定函数名,函数值类型、形参及其类型以及函数体等,它是一个完整的、独立的函数单位。而函数的声明的作用则是把函数的名字,函数类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时进行对照检查(例如,函数名是否正确,实参与形参的类型和个数是否一致),它不包括函数体。&&&&谭浩强 ,《C程序设计》(第四版),清华大学出版社,2010年6月,p182&&&&& 这段论述包含了许多概念性错误,这些概念错误在许多C语言书中都同样普遍存在。为了说明这些错误,首先来回顾一下C语言演变和发展的一些情况。&&&&& 最早,C语言的代码可以这样写:
printf("hello,world!\n");
&&&&& 注意,这段代码对标识符printf没有进行任何说明。这是因为printf()函数的返回值为int类型。当时的C语言规定,对于没有任何说明的函数名,编译器会默认为返回值为int类型,因此对这样的函数名可以不做任何说明。那个时期的C语言,很多情况下int可以不写。例如main()函数返回值的类型为int就可以不写。&&&&& 但是需要特别说明的是,这种&省劲&的写法已经过时,从C90标准起,这种写法就步入了被逐步抛弃的过程(尽管当时还没有完全立即废止)。C99废除了隐式函数声明法则(remove implicit function declaration),另外,省略main()前面的int也已经不再容许了。&&&&& 在C语言早期,尽管有时不需要对函数名进行说明,但有些情况下对函数名进行说明还是必须的,比如:
double sqrt();
int main()
printf("%f\n" , sqrt(9.) );
&&&&& 这是因为函数sqrt()返回值的类型不是int类型而是double类型,编译器编译时需要知道sqrt(9.)这个表达式的类型。&&&&& 不难注意到这种对函数名的说明非常简单,这是最早期的一种函数类型说明的形式。这种说明只着重说明函数名是一个函数及其返回值类型,如果程序员在调用函数时存在参数类型或个数方面的错误编译器是无法察觉的,因为函数类型说明中&()&内没有任何信息。&&&&& 这种办法只说明了函数名与()进行运算的结果也就是函数返回值的数据类型,无法进一步检查参数方面的错误是这种写法的不足之处。&&&&& 如果不写函数类型说明,也可以把函数定义写在函数调用之前:
double square ( double x)
return x *
int main(void)
printf("%f\n" , square(3.) );
&&&&& 这表明函数定义也具有对函数名的类型加以说明的效果,因此从这个意义上来说,函数定义也是一种对函数类型的说明。这种办法可以检查出函数调用时在参数个数和类型方面的错误。&&&&& 但是,用这种办法说明函数名并不好,因为这样做在编程时还需要考虑应该把哪个函数定义写在前面,哪个写在后面的问题。假如函数A调用函数B,函数B调用函数C,函数C又调用函数A,究竟如何安排函数定义的顺序就会让人感到无所适从。此外这种办法也不利于代码的组织,在由多个源文件组成的源程序时,这种写法就更会捉襟见肘、漏洞百出。因此,在1990年,C标准借鉴C++语言规定了一种新的说明函数名的方法,这就是函数原型(Function Propotype)式说明函数类型的方法:
double square ( double );
//或 double square ( double x)
int main(void)
printf("%f\n" , square(3.) );
double square ( double x)
return x *
&&&&& 使用这种办法,不但可以检查函数调用时参数类型和个数方面的错误,同时解决了源代码的组织问题,因为程序员不必再考虑该把哪个函数写在前面、哪个写在后面这种无聊的问题了。这种办法全面地说明了函数名的数据类型。此外要说明的是,把形参及其数据类型写在&()&内形式的函数定义也属于函数原型(Function Propotype)的范畴。&&&&& 由此可见,古老的、不对参数进行任何说明的函数类型说明方式、函数定义以及函数原型式的函数类型说明方式都具有说明函数名意义的效用。从这个意义上讲它们都是函数声明。在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, includ)。函数原型则特指包括说明参数类型的函数声明,它同样包含用这种方式写出的函数定义。&&&&& 现在回过头来看样本中的第一句话:&对函数的&定义&和&声明&不是一回事&。由于函数定义本身就是一种函数声明,怎么可以说它们不是一回事呢?这句话的逻辑就如同说&男人&和&人&不是一回事。你可以说男人和女人不是一回事,因为他们没有交集。但没法说男人和人不是一回事,因为男人是人的子集,男人就是人的一种,怎么可以说男人和人不是一回事呢?&&&&& 那么,不带函数体的函数声明应该如何称呼呢?在C语言中,它们叫被做&函数类型声明&(Function type declaration)。函数类型声明最主要的特点是声明了函数名是一个函数及其返回值的类型,如果也声明了参数的类型,则是函数原型式的函数类型声明。&&&&& 样本中的&而函数的声明的作用则是把函数的名字,函数类型以及形参的类型、个数和顺序通知编译系统,以便在调用该函数时进行对照检查(例如,函数名是否正确,实参与形参的类型和个数是否一致),它不包括函数体&这句话同样不通。其主要错误是它混淆了&函数原型式类型声明&与&函数声明&这两个概念,前一个概念只是后一个概念的子集。函数声明中不但包含&函数类型声明&,也包含&函数定义&和老式的&函数类型声明&。由于函数定义本身就是一种函数声明,所以无法断定函数的声明是否包括函数体;而且老式的函数类型声明(例如double sqrt();)也属于函数声明,这种函数声明并不检查参数类型及个数方面的错误。此外函数声明也并没有检查&函数名&正确与否的功能。&&&&& 这段文字中的&函数类型&这个概念也有错误,函数类型所描述的不但包括函数返回值类型,也可能一并描述参数的个数和类型(如果是函数原型),因此不能与&形参的类型、个数&相提并论。&&&&& 现代的C语言的函数定义和函数类型声明都采用函数原型式的风格,C99把旧的非原型形式视为过时,这意味着非原型形式以后可能被禁止。
阅读(...) 评论()}

我要回帖

更多关于 函数原型和函数声明 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信