#include<iostream>
using namespace std;
//局部 静态对象
size_t count_calls() {
static size_t ctr = 0;
return ++ctr;
}
//使用引用避免拷贝
bool isShorter(const string& s1, const string& s2) {
return s1.size() < s2.size();
}
//使用标记指定数组的长度
void print(const char* cp) {
if (cp) //cp不是一个空指针
while (*cp) //指针所指的字符不是空字符
cout << *cp++;
}
//数组引用形参,c++允许将变量定义为数组的引用,基于同样的道理,形参也可以是数组的引用
void print(int(&arr)[10]) {
for (auto elem : arr) {
cout << elem << endl;
}
//注意:f(int &arr[10]) 将arr声明为引用的数组 f(int (&arr)[10]) arr是具有10个整数的整形数组的引用
}
//传递多维数组
void print(int(*matrix)[10], int rowsize) { //matrix代表指向含有10个整数的数组指针
return;
}
//等价于
void print(int matrix[][10], int rowsize) { //matrix代表指向含有10个整数的数组指针
return;
}
//含有可变形参的函数
void error_msg(initializer_list<string> il) {
for (auto beg = il.begin(); beg != il.end(); ++beg) {
cout << *beg << " ";
}
cout << endl;
}
string expected = "abc";
string actual = "def";
void test2() {
if (expected != actual) {
error_msg({ "functionx", expected, actual });
}
else {
error_msg({ "functionx", "okay" });
}
}
//省率符形参
//void foo(parm_list, ...);
//void foo(...);
//不要返回局部对象的引用或指针
const string& manip() {
string ret;
if (!ret.empty())
return ret; //错误,返回局部对象的引用
else
return "empty"; //错误,empty是一个局部临时量
}
//返回数组指针
typedef int arr[10];
using arr = int[10];
arr* func(int i); //func返回一个指向含有10个整数的数组的指针
/*
int (*func(int i))[10];
func(int i):代表调用func时需要一个int类型的实参
(*func(int i)):我们可以对函数调用的结果执行解引用操作
(*func(int i))[10]:解引用func的调用将得到一个大小是10的数组
int (*func(int i))[10] :表示数组中的元素是int类型
*/
//使用尾置返回类型
auto func(int i) ->int(*)[10];
//func接受一个int类型的实参,返回一个指针,该指针指向含有10个整数的数组
//使用decltype
int odd[] = { 1, 3, 4, 7, 9 };
int even[] = { 0, 2, 4 ,6, 8 };
decltype(odd)* arrptr(int i) {
return (i % 2) ? &odd : &even;
}
//const_cast和重载
const string& shoererString(const string& s1, const string& s2) {
return s1.size() <= s2.size() ? s1 : s2;
}
//这个函数的参数和返回类型都是const string的引用,我们可以对两个非常量的string实参调用这个函数,但是返回的结果任然是const string的引用
//因此我们需要引进一个新的shorterString函数,当他的实参不是常量时,得到的结果是一个普通的引用,使用const_cast可以做到
string &shorterString(string& s1, string& s2) {
auto &r = shorterString(const_cast<const string&>(s1), const_cast<const string&>(s2));
return const_cast<string&>(r);
}//报错了,不知道为什么
//重载与作用域
string read();
void print(const string&);
void print(double);
void fooBar(int ival) {
bool read = false; //新的作用域,隐藏了外层的read
//string = read(); //错误,read是一个布尔值,而非函数
void print(int);
//print("value"); //print(const string&)被隐藏了
print(3.14);
}
//内联函数和constexpr函数
inline const string& shorterString(const string& s1, const string& s2) {
return s1.size() <= s2.size() ? s1:s2;
}
//constexpr函数的返回类型及所有形参的类型必须都是字面值类型,而且函数体中必须有且只有一条 rerun语句
constexpr int new_sz(){
return 42;
};
constexpr int foo = new_sz();
//返回指向函数的指针
using F = int(int*, int); //F为函数类型,不是指针
using PF = int(*)(int*, int); //PF为指针类型
PF f1(int); //PF是指向函数的指针,F1返回指向函数的指针
int (*f1(int))(int*, int);
//f1有形参列表,所以f1是一个函数,f1前面有*,所以f1返回一个指针,指针类型本身也包含形参列表,因此指针指向函数,该函数的返回值为int
auto f1(int) -> int(*)(int*, int);
void test() {
void f1() ; //隐士的定义空参数列表
void f2(void); //显示的定义空参数列表
//自动对象:存在于块执行期间的对象称为自动对象,当块的执行结束后,块中创建的自动对象的值就变成未定义的
//const形参与实参
const int ci = 42;
int i = ci;
int* const p = &i;
*p = 0;
//下列三种形式是等价的
void print(const int*);
void print(const int[]);
void print(const int[10]);
}
int main() {
system("pause");
return 0;
}