这里写目录标题
1.函数一定需要块
double square(double x) //错误,一定需要大括号括起来
return x * x;
2.自动对象
在函数体内部声明的局部变量,成为自动对象. 形参就是一种自动对象
3.局部静态变量
可以延长变量的声明周期,程序终止时销毁.重复定义的静态变量不会修改原来的值.默认初始化为0
size_t count_calls()
{
static size_t ctr = 0;
return ++ctr;
}
for (int i = 0; i < 10; i++)
{
cout << count_calls() << endl; //输出1~10;
}
4.参数类型
如果函数不用修改参数的值,最好声明为常量引用(
const &
)
5.重载函数/形参是 const
void fun(const int i){} //可以接受const int 和 int型参数
void fun(int i){} //错误,不能重复定义fun(int);
void fun(int &a){} //接受引用
void fun(const int& a){} //正确,接受常量引用
//特殊情况
//1.
void fun(const int num){}
void fun(const float num){}
double num = 3.14;
fun(num)/fun(3.14); //报错,有多个重载函数 "fun" 实例与参数列表匹配: 3.14字面值为double
//要么追加一个double类型的,要么删除一个
//2.
void fun(const int a, const int b)
void fun(const double a, const double b)
fun(42,3.14); //报错,同上
//3.
void fun( int* a, int* b){}
void fun(int* const a, int* const b){} //报错,同上
6.数组做参数
//下面三个均可.传入的参数均为 const int*
void print(const int*);
void print(const int[]);
void print(const int[num]);
//数组引用
f(int &arr[10]){..} //错误.arr声明成引用的数组
f(int (&arr)[10]){..} //正确,arr是具有10个整数的整形数组的引用(括号不可少)
7.主函数传递参数
//argc 参数数量
/*argv 是参数数组
- 第一个是程序名称或者空字符串;
- 第二个开始是传递参数;
- 最后一个需要为0;
*/
int main(int argc,char *argv[]){..}
8.可变形参 initialize_list形参
//与vector类似,不同之处:initialize_list中的值均为常量
//只要三个成员函数 begin,end,size
initialize_list<T> lst; //默认初始化
void myPrintf(其他参数,initializer_list<string> a)
{
for (auto it = a.begin(); it != a.end(); it++)
{
cout << *it << endl;
}
}
myPrintf({ "a","b","c" });
9.返回值
- 返回值不会进行拷贝.所有不要返回局部指针或者引用或者局部变量.因为函数执行后会被清楚,指针或者引用指向一个不存在的对象.
- 返回值可以返回引用类型,所有可以返回左值.
get_val() = 'a';
返回值 = ‘a’;
10. typedef 定义数组
typedef int arr[10]; //arr代表含有10个int变量的数组
11.数组指针
//从右往左,括号优先,不确定返回类型就指定auto
int *p1[10]; //p1是一个含有10个指针的数组(指针数组)
int (*p1)[10]; //p1是一个指向10个整数的数组指针(数组指针)
12.默认实参
只能从右往左一个个开始填,不能跳过,默认形参不同并不会造成重载,会报重复定义
void fun(const int num = 3){}
void fun(const int num = 3.14){}
13.inline
函数
- 在编译时,把使用该函数的地方用函数内容替换.
- 只是像编译器提议,接不接受还得看编译器.只能接受一些功能简单,语句简单的函数
14.assert
断言函数,明确告诉编译器这种情况不会发生
- 如果expression的结果为 0(条件不成立),那么断言失败,表明程序出错,assert() 会向标准输出设备(一般是显示器)打印一条错误信息,并调用 abort() 函数终止程序的执行。
- 如果expression的结果为非 0(条件成立),那么断言成功,表明程序正确,assert() 不进行任何操作。
- 如果定义了
NDEBUG
,assert就什么都做不了.linux下-D NDEBUG
assert(判断);
string n = "abcde";
assert(n.size() < 4); //报错:Assertion failed: n.size() < 4
15.!!一些宏定义!!
__FILE__ //当前文件的绝对路径的字符串字面值
__LINE__ //存放当前行号的整形字面值
__TIME__ //存文件编译时间的字符串字面值
__DATE__ //存放文件编译日期的字符串字面值
16.候选函数,可行函数
- 候选函数具备两个特征:一是与被调用的函数同名,二是其声明在调用点可见。
- 可行函数是从候选函数中选出的,有两个特征:一是其形参数量与本次调用提供的实参数量相等,二是每个实参的类型与对应的形参类型相同,或者能转换成形参的类型。
17.函数指针
void (*pf)(...); //函数指针,括号不可省略,不然就是返回一个 void* 的函数
//调用
pf(...);
(*pf)(...); //等价调用
//做参数
fun( void(*pf)(...) ){} //可以自动将函数转化为函数指针
//做模板
vector<int (*)(int, int)> vf;
tip:太麻烦或者不会写用auto