自动对象的声明周期:对于普通局部对象, 当函数的控制路径经过变量定义语句时创建该对象。当达到定义所在块末尾时销毁它。
内置类型不会默认初始化,即产生未定义的值
局部静态对象:
static a = 0;
当函数的控制路径经过变量定义语句时创建该对象。程序终止才进行销毁。内置类型会自动初始化为0
函数声明:含有函数声明的头文件应该被包含到定义函数的源文件中
void print(int a, int b);
- 当用实参初始化形参的时候,会忽略掉顶层“const
void f(const int i);
void f(int i); //error:重复定义
- 数组形参:传递的是指向数组首元素的指针
void print(const int*)
void print(const int[])
void print(const int[10])
- 传递数组长度
void print(const int *beg, const int *end)
void print(const int *beg, size_t size)
void print(int (&arr)[10]) //传递引用,这个10限制了数组长度是10
- 传递多维数组
void print(int (*matrix)[10], int rowSize) //数组对象是int[10]
void print(int matrix[][10], int rowSize) //等价的
main
:命令行选项
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
for(int i=1; i<=argc; i++){
//argc是字符串的个数, argv是字符串数组,
//argv[0]保存数组的名字,而非用户输入
cout << argv[i] << " ";
}
cin.get();
}
//运行
// g++ a.cpp
// .\a.exe i d d
//输出:i d d
- 传递不同数量实参
initializer_list
。定义在同名的头文件下
void error_msg(initializer_list<string> il)
{
for(auto beg = il.begin(); beg != il.end(); ++beg)
cout << *beg << " ";
cout << endl;
}
- 引用返回左值
char &get_val(string &str)
{
return str[0];
}
get_val(s) = 'a'; //可以当左值
- 列表初始化返回值
return {"dsdf", "dfdgfdf"}; //a={"dsdf", "dfdgfdf"}; a根据列表值进行初始化
- 返回数组指针。感觉没有软用
typedef int arrT[10]; //arrT是一个类型别名:含有10个整数的数组
using arrT = int[10]; //等价
arrT* func(int i); //函数返回一个指针,指针指向含有10个整数的数组
//定义返回数组指针的函数
int (*func(int i))[10];
//使用尾置返回类型
auto func(int i)->int(*)[10]
//使用decltype
int odd[] = {1,2,3,4,5};
decltype(odd) *arrPtr(int i)
{
return &odd;
}
- 函数重载:同一作用域,形参列表不同,函数名相同。
main
函数不能重载。返回值没影响
//重载和const形参:顶层ocnst有无都相同。底层const有无可以重载
void fact(int i);
void fact(const int i); //error:重复声明。 顶层const 就是 i不能变
void fact(int*);
void fact(int* const); //error:重复声明
void fact(int&);
void fact(const int&);
void fatc(int*);
void fact(const int*); //不过,传入非const对象时,优先选择非const参数的函数
const_cast
:改变const
属性
const_cast<const string&>(s1);
const_cast<string&>(s1);
- 重载和作用域:
名字查找发生在类型检测之前
void print(const string&);
void print(double);
{
void print(int);
void print("hahaha"); //error:void print(int)屏蔽掉了之前的2个
}
内联函数:在函数前面加上
inline
constexpr
:是指能用于常量表达式的函数,遵守约定:函数返回类型及所有形参的类型都是字面值常量,而且函数体有且只有一条return
语句调试帮助:
assert(expr)
,在头文件<cassert>
中。assert(word.size()>threshold);
如果是假,则输出信息并终止程序执行。assert
是预处理宏,由预处理器处理NDEBUG
预处理变量:如果定义了它,则assert
将不执行运行时检查。
#ifndef NDEBUG
//执行检查
#endif
- 编译器定义的局部静态变量
// __func__ :局部静态变量
cout << __func__ ;
//__FILE__:存放文件名的字符串字面值
//__LINE__:存放当前行的整型字面值
//__TIME__:存放文件编译时间的字符串字面值
//__DATE__:存放文件编译日期的字符串字面值
函数匹配
- 确定候选函数:函数同名;声明在调用点可见
- 可行函数:形参,实参数量相等;实参,形参类型相同,或能转换为形参的类型
- 寻找最佳匹配:实参,形参类型越接近,匹配的越好。最佳匹配应满足,每个实参的匹配不劣于其他可行函数;至少一个匹配优于其他可行函数
函数指针:
bool fun(int a, int b);
//函数指针
bool (*pf)(int a, int b); //未初始化
pf = fun; // 函数名作为右值时,自动转换未指针
pf = &fun; //pf(a,b) or *pf(a, b) //函数指针之间不存在转换规则
//函数指针形参
//返回指向函数的指针 类型别名有用到 auto decltype using typedef