1、局部静态变量,只初始化一次,程序终止才销毁
static int a = 1;
2、如果形参是引用类型,它将绑定到对应的实参上;否则,将实参的值拷贝给形参。C++建议使用引用类型的形参代替指针。如果函数无需改变引用形参的值,最好将其声明为常量引用。
//即(int &)i,引用对象i
void reset(int &i)
{
i = 0;
}
int j;
reset(j);//则j = 0
//比较两个字符串长度,采取引用
//调用的时候会定义(const string &)s1 = 实参字符串
bool isShorter(const string &s1, const string &s2)//引用两个常类型字符串
{
return s1.size() < s2.size();
}
3、不能把const对象、字面值或者需要类型转换的对象传递给普通的引用形参。
int i =42;
const int &r = i; //初始化绑定,但是不能修改i的值
//非const可以传递给const,只是不能修改
int &r3 = r; // 错误!!非const不能绑定const类型
4、数组以指针的形式传递给函数,一开始不知道切确的尺寸,调用者应该提供一些额外的信息。
数组的大小类型为size_t;
void print(const int *beg, const int *end)
{
while(beg != end)
cout << *beg++ << endl;
}
int a[4] = {0, 1, 2, 3};
print(begin(a), end(a));
//(&a)这是一个引用,该引用指向10int的数组
void f(int (&a)[10])
{
}
5、main
//第一个参数argc存命令行传入的字符串数量;二维数组(字符串数组)存每个字符串(命令行传入的具体字符串),一般argv[0]为程序名字,不需要用户传入。
int main(int argc, char *argv[])
{
....
}
6、含有可变形参的函数
initializer_list类型类似于vector,initializer_list是一种库类型,参数数量可变,类型必须相同,对象中的元素永远是常量值。
void error_msg(initializer_list<string> il)
{
for(auto beg = il.begin(); beg != il.end(); ++beg)
cout << *beg << "";
cout << endl;
}
string expected = "1234";
string actual = "abcdefg";
if(expected != actual)
error_msg({"functionX", expected, actual});
else
error_msg({"functionX", "okay"});
6、函数返回
不要返回局部对象的引用和指针
//返回类型为引用(const string &)
const string &mapip()
{
string ret;
if(!ret.empty())
return ret; //错!!,调用时相等于绑定const string &x =ret,那么就是返回局部变量的引用
else
return "Empty";//错!!返回了局部临时变量,函数调用完会回收
}
尾式返回
//func函数返回一个指针,该指针指向10整数的数组
// -> int(*)[10]表示返回类型
auto func(int i) -> int(*)[10];
7、函数重载:几个函数名字相同,参数列表不同。
(1)单独返回类型不同不行
(2)顶层const(const执行对象非其指针)不行,底层const可以,即const指针和引用是可以区分的
(3)C++中名字查找发生在类型检测之前
8、默认实参:用户调用时不指定值,则使用默认值
typedef string::size_type sz;
string screen(sz ht = 24; sz wid = 80; char backgrnd = ' ');
9、内连函数:在函数前面加上inline,避免函数调用开销
10、constexpr函数:用于常量表达式,规定:返回值及所有形参类型都必须是字面量。编译器会把constexpr函数隐式转化为内连函数。
constexpr int new_sz()
{
return 42;
}
11、调试,预处理宏assert(),定义NDEBUG则关闭该功能,头文件cassert, 预处理命令不需要使用using声明
assert(表达式),如果表达式为假(0),则输出信息并,停止程序
__func__//函数名
__FILE__//文件名
__LINE__//行号
__TIME__//编译时间
__DATA__//编译日期
12、函数指针
int func(const string &a)
{
......
}
int (*f)(const string &);
//下面2句等价
f = func;
f = &func;
//下面调用函数等价
f("hello");
(*f)("hello");
func("hello");
//下面2句等价
//*f1(int),f1返回一个指针;int (*xx)(int *, int);该指针指向函数
int (*f1(int))(int *, int);
auto f1(int) -> int (*)(int *, int);
13、为解决不同源文件中同名函数或变量的问题(引用其他文件变量要加extern,引用函数不需要),C++引入命名空间。命名空间给一组全局程序实体的定义取一个名字,使之构成一个作用域。
- file.h
namespace A
{
extern int x;
void f();
void g();
}
- file.cpp
namespace A
{
int x = 1;
void f()
{
.......
}
void g()
{
.......
}
}
- main.cpp
#include "file.h"
void main()
{
A::f();
}