一. 函数的参数表严格匹配,空参代表没有任何参数,void形参依然可以使用
二. 不再支持C语言中的隐式声明方式,函数调用前必需先声明或定义
三. 函数的返回类型int不能省略
四. 函数可以重载
1. 在同一作用域中,函数名相同,参数列表不同的函数可以存在若干个,其返回值任意
2. 当出现重载函数时,使用函数指针显得有点问题,当给函数指针赋值时,指针的类型代表着具体的函数。
3. 函数重载的实现是基于函数名的编译时改变
4. 当程序跨越编译器或由其它语言调用重载函数时,函数名在编译时编译器不能对其改变,否则无法调用
5. extern“C” 可以告诉编译器,像C语言那样进行编译处理。
//
// main.cpp
// day01-Function
//
// Created by aiqiyisheng on 15/1/11.
// Copyright (c) 2015年 HYR. All rights reserved.
//
#include <iostream>
using namespace std;
//在C语言中 不写返回值类型 则默认返回整型int
/*
*
fa();//声明 声明的时候参数可以不写,定义的时候可以任意给参数
fa(int a,int b){//定义
//函数体
}
*
*/
/*
在C++中的函数一定要写返回值类型,如果没有返回值,则写void空的返回值
C++中的参数如果你不写的话,会默认给你一个void空参数
*/
//英雄打怪后增加经验的函数
int addExp(int heroExp,int addExp){
return heroExp + addExp;
}
//打打怪就会增长百分比的经验
int addExp2(int heroExp,double addExpPtr){
return heroExp * (1 + addExpPtr);
}
/*
void addExp2(int heroExp,double addExpPtr){
//重载跟返回值类型无关
}
*/
/*
* 方法重载
*
方法名相同,参数列表不同(参数个数,参数类型,参数顺序) 这样就构成方法重载了 跟返回值类型无关
编译器在编译的时候遇到相同名字的方法,编译器可能会自己生成一个方法名,
例如:int addExp(int heroExp,int addExp)可能会生成这样的方法名int addExp_i_i()....
int addExp(int heroExp,double addExpPtr)可能会生成这样的方法名int addExp_i_d()...
在调用的时候编译器会根据你给的参数去找对应的方法
*
*
*/
/*
重写 :子类重写父类的方法
*/
int addExp(int heroExp,double addExpPtr){
return heroExp * (1 + addExpPtr);
}
//告诉编译器 该方法按照“C”语言的方式处理 (不会帮你重命名)
extern "C"
void test(){
cout << "extern \"C\" 的作用" << endl;
}
//主函数
int main(int argc, const char * argv[])
{
int heroExp = 1000;
cout << addExp(heroExp, 100) << endl;
cout << addExp2(heroExp, 0.5) << endl;
cout << addExp(heroExp, 0.5) << endl;
test();
return 0;
}
运行结果如下:
1100
1500
1500
extern "C" 的作用
Program ended with exit code: 0
另外需要注意的是: 函数重载的时候要注意一点就是如果找不到匹配类型的,或者找到好几个匹配类型的,该如何???
#include <iostream>
using namespace std;
//定义函数 函数重载
//如果找不到匹配的类型,C++会找一个相对合适的类型
//同样 如果找到很多合适的类型 那也不知道该执行那一个,例如注释掉int的方法
//void fa(char ch){ cout << "fa(char ch)" << endl;}
//void fa(short st){ cout << "fa(short st)" << endl;}
void fa(int it){ cout << "fa(int it)" << endl;}
void fa(long lg){ cout << "fa(long lg)" << endl;}
void fa(float ft){ cout << "fa(float ft)" << endl;}
void fa(double de){ cout << "fa(double de)" << endl;}
int main(){
//声明变量
char ch;
short st;
int it;
long lg;
float ft;
double de;
//
fa(ch);
fa(st);
fa(it);
fa(lg);
fa(ft);
fa(de);
return 0;
}
运行结果如下:
fa(int it)
fa(int it)
fa(int it)
fa(long lg)
fa(float ft)
fa(double de)
Program ended with exit code: 0
===================================================
重复了
#pragma 函数的写法:
/*
*
*
返回值类型 函数名(参数列表){
...
函数体
...
}
*
*
*/
#include <iostream>
using namespace std;
/*
* C语言
//函数声明
void fa();
//函数定义
void fa(int x, int y){ //C语言的函数声明里面如果参数为空,在实现的时候可以随便给
}
//C语言的函数不给返回值类型的话 ,默认返回int类型
*
*/
//C++中
void fa(){ //可以声明 定义 写在一起。 如果是这样,编译器会默认自动给我们添加上void参数
}
//增长经验值的函数
#pragma 方法重载: 方法名相同,参数列表不同(类型不同,参数个数不同, 顺序不同),那么该两个函数就形成了重载的关系
int addExp(int heroExp,int addExp){ //传进英雄当前的经验值 和 增加的经验
return heroExp + addExp;
}
int addExp2(int heroExp,double addExpPer){ //传进英雄的经验值 和 增长的百分比
return heroExp * (1 + addExpPer);
}
//参数类型不同
int addExp(int heroExp,double addExpPer){ //重载
return heroExp * (1 + addExpPer);
}
//参数个数不同
int addExp(int heroExp,double addExpPer,int z){ //重载
return z;
}
//参数顺序不同 其实我觉得也是类型不同
int addExp(double addExpPer,int heroExp){ //重载
return heroExp * (1 + addExpPer);
}
/*
这里爆红是因为 函数重载跟返回值类型无关 只看两点,函数名和参数列表
void addExp2(int heroExp,double addExpPer){ //传进英雄的经验值 和 增长的百分比
return heroExp * (1 + addExpPer);
}
*/
//主函数
int main(){
//
int heroExp = 1000;
cout << addExp(heroExp, 100) << endl;//累加
//cout << addExp2(heroExp, 0.5) << endl;
//假如我现在有50个方法 那么在选择方法的时候需要考虑一下是哪一个才是增长百分比的那一个
//现在能够确定的是 heroExp 和 0.5 ,那么我只需要找到一个方法的参数满足这两个条件就可以了
cout << addExp(heroExp, 0.5) << endl;//自动找到百分比的那个方法了
//真正运行的时候编译器会找编译器自己写的方法
/*
原理是这样
编译器在编译这个函数的时候
int addExp(int heroExp,double addExpPer){
}
会生成这么一个自己的方法
int addExp_int_double(int heroExp,double addExpPer){
}
编译器在编译这个函数的时候
int addExp(int heroExp,int addExp){
}
会生成这么一个自己的方法
int addExp_int_int(int heroExp,int addExp){
}
*/
//那你会问 你这两个方法名不是冲突了吗??
//其实这就是叫做 方法重载
#pragma OC里面没有方法重载 方法名不可能相同
//因为OC里面的参数名是方法名的一部分,如果参数不一样了,那么方法名一定不一样了
return 0;
}