1、声明和定义
2、参数传递声明:type func_name(type paraopt,type paraopt);//inline函数暂时不考虑,用处不大
静态变量static---仅初始化一次,如:
void f(int a) {while(a--){ static int n=0; int x=0; cout<<"n === "<<n++<<" ,x == "<<x++<<endl; //x一直是0 } }
传值vs传引用
const引用void f(int val, int& ref){ val++; //增加的是一个临时副本 ref++; //传递的参数本身++ }
数组参数int strcmp(const char*,const char*); float fsqrt(const float&); float update(float &i); void g(double d,float r){ update(2.0f); //error,非const的引用参数不允许做类型转换 update(d); //error update(r); fsqrt(2.0f); //ok,文字量、常量和需转换的参数都可以传递给const &参数 fsqrt(d); //ok fsqrt(r); }
如果将数组作为函数的参数,传递的就是到数组的首元素的指针。
三种方式可以使用,具体参见http://www.runoob.com/cplusplus/cpp-passing-arrays-to-functions.html
3、重载函数名
重载的匹配规则:1、精准匹配;2、提升的匹配(如char->int);3、标准转换(如int->double);4、用户定义转换;5、利用函数声明中的省略号匹配
void print(int); int print(const char*); void print(long); int print(char); void h(char c,int i, short s, float f){ print(c); print(i); print(s); //整数提升short->int,与返回值类型无关 print(f); //float->double的提升 print('a'); print(49); //精准匹配print(int) print("a"); }
4、默认参数
int f(int,int=0,char*=0); //ok int g(int=0,int, char*=0); //error,默认参数必须从后往前提供
5、未确定数目的参数
int printf(const char*...); //仅仅是个形式而已,具体咋用我还真不知道
6、指向函数的指针
7、宏对于一个函数只能做两件事情,调用它或者取得它的地址。
void (*pf)(string); void f1(string); int f2(string); void f3(int*); void g(){ pf=f1; pf=&f1; //可以省略取地址的& pf("Boss"); (*pf)("Boss"); //对于函数指针,可以省略间接运算符* pf=&f2; //error,返回值类型不匹配 pf=f3; //error,参数类型不匹配 }
//人们常常为了方便而为指向函数的指针类型定义一个名字,如来自unix系统头文件的一个例子 typedef void(*SIG_TYP)(int); //from <sinal.h>,https://blog.csdn.net/yockie/article/details/51729774 typedef void(*SIG_ARG_TYP)(int); SIG_TYP signal(int,SIG_ARG_TYP); //参考https://blog.csdn.net/davidsky11/article/details/28278973
1st principle:能不用尽可能不适用
#define PRINT(a,b) cout<<(a)<<(b); #define PRINT(a,b,c) cout<<(a)<<(b)<<(c); //如果使用的时候仅使用其中一个只报warnning,两个都用就是error #define FAC(n) (n>1)?n*FAC(n-1):1; //不支持递归
define中的三个特殊符号:#,##,#@
define NAME(a,b) a##b //两个字符串合并 define TEST(a) #@a //单引号'a' define YINHAO(a) #a //双引号"a"
条件编译
#ifndef BODYDEF_H #define BODYDEF_H //头文件内容 #endif