#C++Primer之 函数探幽算法
C++函数包括函数声明和函数定义,函数声明即函数原型,通常隐藏在include文件中。 ###为何须要原型? 1.原型告诉编辑器,函数的参数,若是程序没有提供正确的参数,让编辑器可以捕获这种错误。 2.函数执行完成后,将把返回值放置在指定的位置,编译器根据函数原型的类型去检索和解释。 没有以上信息,编译器只能去猜想。 ###原型的功能数组
###指针和const const表示指向一个常量,该值不能被修改.编辑器
int n = 10; const int *p = &n;
p表示指向一个常量的指针,虽然不能够经过p来需改n,可是能够 经过n++来达到修改p指向的数据。 C++禁止将const的地址赋给非const地址,但容许将非const地址赋给const地址当且仅当只有一层间接关系时。 ###const的做用函数
char *build(char c, int n) { char *pstr = new char[n+1]; pstr[n] = '\0'; while(n>0) pstr[n--] = c; return pstr; }
变量pstr的做用域是函数内,所以函数执行结束时,pstr所使用的内存将被释放,但因为函数返回了pstr的值,程序仍然能够在main()中的指针访问新建的字符串。ui
###内联函数 ####函数执行过程: 执行到函数调用指令时,程序将在函数调用后当即存储该指令的内存地址,并将函数参数复制到对战(为此保留的内存块),调到编辑函数七点的内存单元,执行函数代码,而后跳回到地址被保存的指令处,来回跳跃并记录跳跃位置意味着使用函数调用时须要必定的开销。指针
void incline f();
内联函数的编译代码和其余程序代码"内联"了,即编译器直接将相应的函数调用替换为代码,无需来回跳转,使得运行速度比常规的函数快,代价是占用更多的内存,因此通常要求内联函数必须很短,被调用不少次。 ###将引用做为参数传递给函数code
double refcube(double &ra); ... double x = 2.1; double z = refcube(x + 3.0);//error
上述代码会编译错误,由于x+3.0 不是变量。对象
double y = 3.2; double z = refcube(x+y);
这样就不会报错,这就涉及到了临时变量、引用参数和const 若是实参和引用参数不匹配,C++将生成临时变量,当且仅当参数为const引用时,C++才容许这么作。 若是引用参数是const,如下状况将生成临时变量:内存
void swap(int &a, int &b) {..}//swap a and b long a =3, b = 5; swap(a,b);
这里类型不匹配,所以编译器将建立两个临时的int变量,初始化为3和5,而后交换临时变量内容,而a和b不变. 因此const的做用还有另外一个做用就是使函数可以正确生成临时变量 ###函数重载 函数重载的关键是函数的参数列表(也称函数特征标),即函数名相同,参数数目和类型以及排列顺序也相同,则特征值相同,参数变量名可有可无。作用域
double cube(double x); double cube(double &x);
此处不是函数重载,由于如代码 cout<<cube(x);
x与double和double&都匹配,编译器没法肯定使用哪一个原型。为避免混乱,编译器检查特征表时,将类型引用和类型自己视为同一个特征标,此外匹配函数时并不区分const和非const。 是特征标不是函数类型使得函数能够对函数进行重载,一下为互斥的:
long f(int a, int b); double f(int a, int b);
返回类型能够不一样,但特征标必须不一样。编译器一般会根据参数列表对函数的民称进行惟一标示,便于内部识别。 ###函数模板 函数模板是通用的函数描述,经过将类型做为参数传递给模板,使编译器生成可用具体的类型的函数。相似于:
template<class Any> void swap(Any &a, Any &b);
对于不一样类型使用同一种算法,可以使用模板,有时须要像重载常规函数那样去重载函数模板。