c++入门之缺省参数和函数重载
1.雀省参数的概念
缺省参数是==声明或定义函数==时为函数的参数指定一个缺省值。在调用该函数时,如果==没有指定实参==则采用==该形参的缺省值==,否则使用指定的实参。
#include <iostream>
using namespace std;
void fun(int x = 10)
{
cout << x <<endl;
}
int main()
{
int a = 100;
fun();//没有传入参数的时候就是用给定的缺省值
fun(a);//传入参数的事就就是用给定的参数!
}
1.1缺省值的分类
缺省值分为全缺省和半缺省
#include <iostream>
using namespace std;
int func(int a = 10,int b = 100,int c = 1000)//这就是全缺省
{
return a+b+c;
}
int func1(int a,int b = 100,int c =1000)//这就是半缺省
{
return a+b+c;
}
int main()
{
cout << func() << endl;
cout << func1(100) << endl;
}
1.2缺省值的使用注意
-
缺省值必须从右往左连续缺省!
#include <iostream>
using namespace std;
int func(int a = 10,int b = 100,int c)
{
return a+b+c;
}
int func1(int a = 10,int b,int c = 1000)
{
return a+b+c;
}
int func2(int a,int b = 100,int c)
{
return a+b+c;
}
//这样的设置缺省值是会报错的!
-
缺省值不可以同时在声明和定义中同时存在!
-
//a.h(在头文件a中) int func(int a = 10); //a.cpp (在源文件a中) int func(int a = 10) { return a; }
这是为了防止在声明和定义中出现完全不同的缺省值导致二义性!
-
缺省值必须是常量或在全局变量!
-
缺省值不兼容c语言!
1.3缺省值的应用
缺省值可以让我们在已知必要的前提条件下更好的节省程序的性能!
using namespace std;
namespace bit
{
struct stack
{
int* a;
int capacity;
int top;
};
void StackIint(stack* p)
{
int capacity = 4;
assert(p);
int* temp = (int*)malloc(sizeof(int) * capacity);
if (temp)
{
perror("malloc fail");
return;
}
p->capacity = capacity;
p->top = 0;
p->a = temp;
}//这是我们一开始使用的栈的初始化,这个方式有一个缺点,加入我们已经知道了需要的空间的大小!我们仍需要在插入的时候使用realloc开辟新的空间!浪费不必要的性能!
void StackIint_2(stack* p ,int defaultCP = 4)
{
assert(p);
int* temp = (int*)malloc(sizeof(int) * defaultCP);
if (temp)
{
perror("malloc fail");
return;
}
p->capacity = defaultCP;
p->top = 0;
p->a = temp;
}//使用了缺省值后,我们就可以在已知需要开辟多少空间的条件下,一次性开辟出足够的空间,使程序足够的灵活,而且保持程序的使用方式仍与上面的那种一样!
}
int main()
{
bit::stack a;
bit::StackIint_2(&a);//不知道该使用多少内存
bit::stack b;
bit::StackIint_2(&b, 100);//知道使用多少内存
return 0;
}
2.函数重载
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这 些同名函数的形参列表**(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型 不同的问题**。
int add(int x, int y)
{
return x + y;
}
int add(double x, double y)
{
return x + y;
}
int main()
{
cout << add(1, 2) << endl;
cout << add(10.9, 8.6) << endl;
}
==利用函数重载的特性我们就可以制作出例如能兼容多种的类型的swap函数==,像是我们c++中经常使用的cout和cin函数,它自动识别类型的本质就是重载!
2.1函数重载的二义性!
void test()
{
cout << "hahah" <<endl;
}
void test(int a =1 ,int b = 10)
{
cout << a <<endl;
cout << b <<endl;
}
int main()
{
test(1);
test(1,2);
test();//这行代码会报错!因为系统无法辨别究竟要调用那个函数!
//函数重载+缺省参数!
return 0;
}
2.2 编译重载的原理
在预编译的过程中有一个符号表!符号表存储着函数名和地址!
对于c语言,它会==粗糙地不加修饰==把所有参数名和地址统统放进去!
而c++会对根据函数的参数的不同类型,不同数量,类型顺序对函数名进行修饰!
在linux的g++中以c语言编译器下编译后的结果
可以看出函数名是完全没有变化的!
在linux的g++中以c++器下编译后的结果
在linux下,采用g++编译完成后,==函数名字的修饰发生改变==,编译器将函数==参数类型信息==添加到修改后的名字中。