p187~p199:
【传值参数】
【传引用参数】
使用引用形参返回额外信息:传入一个(或者多个)额外的引用实参,令其保存字符出现的次数。
6.11
#include <iostream> using namespace std; void reset(int &i) { i = 0; } int main() { int i = 9999; reset(i); cout << "i = " << i << endl; // output: i = 0 return 0; }
6.12
#include <iostream> using namespace std; void swap(int &p, int &q) { int temp; temp = p; p = q; q = temp; } int main() { int a = 3, b = 4; cout << a << " " << b << endl; swap(a , b); // 交换之后 cout << a << " " << b << endl; /* output: 4 3 */ return 0; }
6.13
void f(T)中的T在调用函数的时候将拷贝实参的值,而voidd f(&T)中的T则是传入实参的临时别名。
6.14
感觉几乎都可以用引用类型,想到的一个是“删减字符串然后返回”,但是仍然可以在函数内部定义局部变量再进行操作。
6.15
因为不希望在函数里面改变string的值,因此s是常量引用(s设置为const可以提高可读性、更加安全,但是这应该不是必须的)。
s定义为引用类型可以避免拷贝,occurs定义为引用类型是为了返回“额外的信息”,定义成常量就无法统计值了。
至于c为什么不是引用类型。。。(更多原因见下文)
【const形参和实参】
续上节,补充尽量使用常量引用的原因:形参的初始化和变量的初始化是相同的,常量引用相比普通引用能够接收更多的类型。一个实例是f(string &s)无法传入字面值(非常量引用无非用字面值来初始化),如果传入将发生编译错误。正确的做法是:f(const string &s)。
6.16
见上文。
6.17
#include <iostream> using namespace std; // 函数1 bool has_bigc(const string &s) { for (char c : s) { if (c >= 'A' || c <= 'Z') { return true; } } return false; } // 函数2 void to_Lower(string &s) { int L = 'A' - 'a'; for (char &c : s) { if (c >= 'A' || c <= 'Z') { c -= L; } } } int main() { cout << (has_bigc("Lovecpp") ? "Yes!" : "No!") << endl; string s = "HeLlo WORLD"; to_Lower(s); cout << s << endl; return 0; }
6.18
bool compare(matrix&, matrix&); vector<int>::iterator change_val(int , vector<int>::iterator);
6.19
不合法 合法 合法 合法
6.20
略。
【数组形参】
一维数组
含有数组形参的函数的声明方式:
void opera_array(const int*); // 推荐,更符合实际意义 void opera_array(const int[]); void opera_array(const int[10]);
以上三个函数是等价的。可以看出,函数参数实际接收的是指向数组首元素的指针(假设一个数组a,传入a等价于传入&a[0])。因为数组是以指针形式传递给函数,所以函数并不知道数组的确切尺寸。调用者因此应该提供额外的信息,主要有三种途径:
1、在数组尾部放标记。(例如c风格的字符串尾部的' ')
2、传入指向数组首尾元素的指针。(借助标准库的begin(a);end(j);)
3、显式传入长度。(例如void f(int *a, int len);)
多维数组
多位数组实质上是“数组的数组”,数组的第二维(以及以后的维度)的大小都是数组类型的一部分,在声明的时候不可省略!正确使用的例子:
void f(int (*array)[10]);
避免混乱的一个好办法就是:坚持一种直观的方式。
6.21
const int *p;
6.22
#include <iostream> using namespace std; void swap(int* &p, int* &q) { int* temp; temp = p; p = q; q = temp; } int main() { int i = 3; int *p = &i; int *q = nullptr; swap(p, q); cout << *q << endl; return 0; }
6.23
略。
6.24
打印元素个数为10的int型数组元素,代码没问题。
【main:处理命令行选项】
简单的示例:
#include <iostream> using namespace std; int main(int argc, char *argv[]) { for (size_t i = 0; i != argc; ++i) cout << argv[i] << endl; // c风格的字符串可以当成字面值来用。 return 0; }
$ a hello world i love you a # 第一个元素是exe文件的名字 hello # 以下是传入的参数 world i love you
6.25
#include <iostream> #include <string> using namespace std; int main(int argc, char *argv[]) { string hi = ""; for (size_t i = 0; i != argc; ++i){ hi += argv[i]; hi += " "; } cout << hi << endl; return 0; }
6.26
略。
【含有可变形参的函数】
initializer_list<T> 的特点:1、元素永远是常量 2、传入值要加花括号
6.27
#include <iostream> #include <initializer_list> using namespace std; int sum(initializer_list<int> il) { int sum = 0; for (auto &x : il) { sum += x; } return sum; } int main() { cout << sum({1, 2, 3, 4, 5}) << endl; // output=15 return 0; }
6.28
string
6.29
看具体情况。