上一篇随笔写了关于C++在注释,输入输出,局部变量说明的扩充,以及const修饰符与C中的#define的比较,也得到了几位学习C++朋友们的帮助讲解,十分感谢,我也希望欢迎有更多学习C++的朋友一起来讨论,这样大家都能共同进步。那么,今天这篇要讲的是C++在函数原型上和C的区别、内联函数、带有默认参数的函数以及函数的重载。

  1.大家都熟悉在C中,如果函数调用的位置在函数定义之前,那么在函数调用之前要对函数原型声明或调用之前就把函数直接定义好了。比如:

#include<stdio.h>

int add(int x,int y);

int main()

{

  int x,y,sum;

  printf("请输入两个整数:\n");

  scanf("%d,%d",&x,&y);

  sum=add(x,y);

  printf("x+y=%d",sum);

  return 0;

}

int add(int x,int y)

{

  return x+y;  

}

不过也可以采用简洁的方式来声明,如:int add(); add(); 都可以通过编译;但是在C++里,如果函数定义在后,调用在前,那函数原型的声明必须是int add(int x,int y);函数名称,参数类型和个数,以及返回值都必须说明;如果函数定义在前,调用在后则和C一样。以上这种形式在C++里也等同于int add(int ,int);如果在原型说明中没有指出返回类型C++默认返回类型为int,不需要返回值,就用void。另外标准C++要求的main函数的返回值必须为int;

  2.内联函数就是在函数说明前冠以关键字"inline",当C++在编译时使用函数体中的代码插入到要调用该函数的语句之处,同时用实参代替形参,以便在程序运行时不再进行函数调用。比如:

#include <iostream>

using namespace std;

inline int add(int a,int b)

{

  return a+b;

}

int main()

{

  int x,y,sum;

  cin>>x>>y;

  sum=add(x,y);

  cout<<"x+y="<<sum<<endl;

  return 0;

}

在编译时,遇到函数啊add(x,y)时,用函数体代替add(x,y),同时实参代替形参,这样“sum=add(x,y)”被替换成“{

int a=x;int b=y;sum=a+b;}”;那么为什么要引入内联函数呢?主要是为消除函数调用时的系统开销,以提高系统的运行速度。在程序执行过程中调用函数,系统要将程序当前的一些状态信息存到栈中,同时转到函数的代码处去执行函数体的语句,这些参数保存和传递过程中需要时间和空间的开销,使得程序效率降低。但是并不是什么函数都可以定义为内联函数,一般情况下,只有规模很小而是用频繁的函数才定义为内联函数,这样可以大大提高运行速率。

  3.一般情况下,实参的个数应该和形参的一样,但在C++中则不一定,方法是在说明函数原型时,为一个或多个形参制定默认值,以后调用此函数,如省略其中一实参,C++自动地以默认值作为相应参数的值。比如int add(int x=10,int y=10),那么我们在调用该函数时可以有三种写法:add(50,50)//结果为50+50;add(50)//结果为50+10;add()//结果10+10;这样使函数更加灵活。但要注意的是默认参数必须是在参数列表的最右端,int add(int x,int y=10,int z)这样是错误的,还有不允许某个参数省略后,再给其后的参数指定参数值。如果函数定义在函数调用之后,则函数调用之前需要函数声明,此时必须在函数声明中给出默认值,在函数定义时就不要给出默认值了(因为有的C++编译系统会给出"重复指定默认值"的错误信息);

  4.函数的重载,对于这个我想学过C#的朋友一定在熟悉不过了,它意味着,只要函数参数的类型不同,或者参数的个数不同,或者两者兼而有之,两个或两个以上的的函数可以使用相同的函数名。尽管简单,但是我还是想说说它在C++里所要注意的几个问题:1.函数返回值不再函数参数匹配检查之列;2.函数重载与带默认参数的函数一起使用可能引起二义性比如:int fun(int x=0;int y=10){return x+y;}和int fun(int r){return r;}这时候我这样调用fun(10);3.如果函数调用给出的实参和形参类型不符,C++会自定执行类型转换,转换成功会继续执行,但是在这种情况下可能会出现不可识别的错误:int add(int x,int y)和long add(long,long),这时候我这样调用add(9.9,8.8);

  5.最后还是一样通过一个实例来总结一下今天的内容:


1 #include "stdafx.h"
2 #include <iostream>
3 usingnamespace std;

5 int add(int x,int y);//或int add(int,int)

7 inline int sub(int x,int y)//内联函数
8 {
9 return x-y;
10 }
11 
12 double mul(double x=10.0,double y=10.0);//带有默认参数的函数
13 
14 float add(float x,float y)//函数重载
15 {
16 return x+y;
17 }
18 
19 int main()
20 {
21 int x,y,result;
22 cout<<"请输入两个整数:";
23 cin>>x>>y;
24 result=add(x,y);
25 cout<<"普通函数(加法):x+y="<<result<<endl;
26 
27 cout<<"请输入两个整数:";
28 cin>>x>>y;
29 result=sub(x,y);
30 cout<<"内联函数(减法):x-y="<<result<<endl;
31 
32 double a,b,mul_result;
33 cout<<"请输入两个双精度数:";
34 cin>>a>>b;
35 mul_result=mul(a,b);
36 cout<<"带有默认参数的函数(乘法):a*b="<<mul_result<<endl;
37 
38 float c,d,sum;
39 cout<<"请输入两个单精度数:";
40 cin>>c>>d;
41 sum=add(c,d);
42 cout<<"重载加法函数:c+d="<<sum<<endl;
43 
44 return0;
45 }
46 
47 int add(int x,int y)
48 {
49 return x+y;
50 }
51 
52 double mul(double x,double y)
53 {
54 return x*y;
55 }

结果:

C++对C语言的非面向对象特性扩充(2)的更多相关文章

  1. C++对C语言的非面向对象特性扩充(3)

    今天要讲的是C++作用域运算符"::",强制类型转换的扩充,C++中相对于C中malloc和free函数的运算符new和delete,以及C++对C的一个重要扩充:引用(refer ...

  2. C++对C语言的非面向对象特性扩充(1)

    我将分3篇来介绍C++相对于C在非对象特性上的扩充,今天要讲的是C++在注释,输入输出,局部变量说明的扩充,以及const修饰符与C中的#define的比较. 1.C++注释除了包括原有C的块注释/* ...

  3. Java语言中的面向对象特性总结

    Java语言中的面向对象特性 (总结得不错) [课前思考]  1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类?  2. 面向对象编程的特性有哪三个?它们各自又有哪些特性?  3. 你知 ...

  4. Java语言中的面向对象特性:封装、继承、多态,面向对象的基本思想(总结得不错)

    Java语言中的面向对象特性(总结得不错) [课前思考] 1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类? 2. 面向对象编程的特性有哪三个?它们各自又有哪些特性? 3. 你知道jav ...

  5. Java语言中的面向对象特性

    面向对象的基本特征 1.封装性 封装性就是把对象的属性和服务结合成一个独立的相同单位,并尽可能隐蔽对象的内部细节,包含两个含义: ◇ 把对象的全部属性和全部服务结合在一起,形成一个不可分割的独立单位( ...

  6. javascript进阶——面向对象特性

    面向对象的javascript是这门语言被设计出来时就考虑的问题,熟悉OOP编程的概念后,学习不同的语言都会发现不同语言的实现是不同的,javascript的面向对象特性与其他具有面向对象特性的语言的 ...

  7. Javascript面向对象特性实现封装、继承、接口详细案例——进级高手篇

    Javascript面向对象特性实现(封装.继承.接口) Javascript作为弱类型语言,和Java.php等服务端脚本语言相比,拥有极强的灵活性.对于小型的web需求,在编写javascript ...

  8. java安全沙箱(三)之内置于Java虚拟机(及语言)的安全特性

    java是一种类型安全的语言,它有四类称为安全沙箱机制的安全机制来保证语言的安全性,这四类安全沙箱分别是: 类加载体系 .class文件检验器 内置于Java虚拟机(及语言)的安全特性 安全管理器及J ...

  9. 浅谈Objective—C中的面向对象特性

    Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...

随机推荐

  1. Mysql 笔记:

    1:可以查看information_schema.index_statistics 来查看索引的使用信息.还可以使用pt-index-usage 这个工具来分析日志再结合explain 来分析使用的索 ...

  2. DelphiXe5中的双向绑定(使用使用TBindScope和TBindExpression,并覆盖AfterConstruction函数)

    在Delphi下等这一功能很久了,虽然C#下早已实现了这一功能.但是在Dephi下尝试这项功能时还是有些许的激动.闲言少絮,直接上代码. unit BindingDemo; interface use ...

  3. libmemcached安装及简单例子

    libmemcached安装及简单例子 1.下载安装libmemcached  $ wget http://launchpad.net/libmemcached/1.0/0.44/+download/ ...

  4. python 在 for i in range() 块中改变 i 的值的效果

    先上一段代码: for i in range(3): i = 2 print(i) 实际结果是: 2 2 2 可以发现实际效果就是 在每次执行 for 语句块的内容后 i 会被重新赋值

  5. [Docker]初次接触

    Docker 初次接触 近期看了不少docker介绍性文章,也听了不少公开课,于是今天去官网逛了逛,发现了一个交互式的小教程于是决定跟着学习下. 仅仅是把认为重点的知识记录下来,不是非常系统的学习和笔 ...

  6. C++学习笔记6

    泛型算法 1. 算法怎样工作 每一个泛型算法的实现都独立于单独的容器.这些算法还是大而不全的,而且不依赖于容器存储的元素类型.为了知道算法怎样工作,让我们深入了解find 操作.该操作的任务是在一个未 ...

  7. golang printf

    1:  打印包括字段在内的实例的完整信息 同 %+V fmt.Printf("Hello world! %v","hufeng") 输出:Hello world ...

  8. BZOJ 2064: 分裂( 状压dp )

    n1+n2次一定可以满足..然后假如之前土地集合S1的子集subs1和之后土地集合S2的子集subs2相等的话...那么就少了2个+操作...所以最后答案就是n1+n2-少掉的最多操作数, 由状压dp ...

  9. Java ByteArrayOutputStream中buf 的大小增长问题

    问题:写入固定长度的字符串[write(byte b[])],观察ByteArrayOutputStream中buf 的大小始终比字符串 Bytes的Size大很多,很是不解 分析发现: privat ...

  10. Mongodb PHP开发类库

    <?php /** * Mongodb 基本操作API,支持基本类似关系统型数据库的操作接口 * * @version 1.0 * * [说明] * * 1:该版本API实现了 Mongodb ...