• 《C++PrimePlus》第8章 函数探幽


    8.1 内联函数

    使用内联函数

    1. #include
    2. using namespace std;
    3. inline double square(double x) { return x * x; }
    4. int main(){
    5. double a;
    6. a = square(5.0);
    7. cout << "a = " << a << endl;
    8. return 0;
    9. }

    8.2 引用变量

    将引用用作函数参数(使用const)

    1. #include
    2. using namespace std;
    3. double cube(const double &ra);
    4. int main(){
    5. double x = 3.0;
    6. cout << cube(x) << " = cube of " << x << endl;
    7. cout << cube(5) << " = cube of " << "5" << endl;
    8. cout << cube(x+5) << " = cube of " << x+5 << endl;
    9. return 0;
    10. }
    11. double cube(const double &ra) {
    12. return ra*ra*ra;
    13. }

    将引用用于结构

    1. #include
    2. #include
    3. using namespace std;
    4. struct free_throws {
    5. string name;
    6. int made;
    7. int attempts;
    8. float percent;
    9. };
    10. void set_pc(free_throws &ft);
    11. void display(const free_throws &ft);
    12. free_throws &accumulate(free_throws &target, const free_throws &source);
    13. int main(){
    14. free_throws one = { "Rick", 13, 14 }; // 最后一个值没赋值,为空
    15. free_throws two = { "Jack", 10, 16 };
    16. free_throws team = { "All", 0, 0 };
    17. set_pc(one); // 赋值
    18. display(one); // 展示
    19. display(accumulate(team, one)); // 汇总
    20. return 0;
    21. }
    22. void set_pc(free_throws &ft) { // 要修改原始数据,不加const
    23. if (ft.attempts != 0)
    24. ft.percent = 100.0 * float(ft.made) / float(ft.attempts);
    25. else
    26. ft.attempts = 0;
    27. }
    28. void display(const free_throws &ft) {
    29. cout << "Name: " << ft.name << endl;
    30. cout << "Made: " << ft.made << '\t';
    31. cout << "Attempts: " << ft.attempts << '\t';
    32. cout << "Percent: " << ft.percent << endl;
    33. }
    34. // 把函数的返回值定义为结构体引用
    35. free_throws &accumulate(free_throws &target, const free_throws &source) {
    36. target.attempts += source.attempts;
    37. target.made += source.made;
    38. set_pc(target);
    39. return target;
    40. }

    将引用用于类的对象

    1. #include
    2. #include
    3. using namespace std;
    4. string version1(const string &s1, const string &s2);
    5. const string &version2(string &s1, const string &s2);
    6. // const string &version3(string &s1, const string &s2);
    7. int main(){
    8. string input;
    9. string copy;
    10. string result;
    11. cout << "Enter a string: ";
    12. getline(cin, input);
    13. copy = input;
    14. cout << "You string: " << input << endl;
    15. result = version1(input, "***"); // 在字符串前后都加上***
    16. cout << "Your string enhanced: " << result << endl;
    17. cout << "Your input: " << input << endl;
    18. cout << "-------------------------------------" << endl;
    19. result = version2(input, "###");
    20. cout << "Your string enhanced: " << result << endl;
    21. cout << "Your input: " << input << endl;
    22. //cout << "-------------------------------------" << endl;
    23. //input = copy;
    24. //result = version3(input, "@@@");
    25. //cout << "Your string enhanced: " << result << endl;
    26. //cout << "Your input: " << input << endl;
    27. return 0;
    28. }
    29. // const string &s2 对应的是 "***"
    30. // 当使用const限定符时,会产生临时变量并进行类型转换
    31. string version1(const string &s1, const string &s2) {
    32. string temp;
    33. temp = s2 + s1 + s2;
    34. return temp;
    35. }
    36. // 返回一个string类的对象的引用
    37. const string &version2(string &s1, const string &s2) {
    38. s1 = s2 + s1 + s2;
    39. return s1;
    40. }
    41. /*错误的使用方法:返回临时变量的引用
    42. const string &version3(string &s1, const string &s2) {
    43. string temp;
    44. temp = s2 + s1 + s2;
    45. return temp;
    46. }
    47. */

    对象、继承和引用

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. const int LIMIT = 5;
    7. void file_it(ostream &os, double fo, const double fe[], int n);
    8. int main(){
    9. fstream fout;
    10. // 先在路径中里新建这个txt文件
    11. const char *fn = "ep-data.txt";
    12. fout.open(fn);
    13. if (!fout.is_open()) {
    14. cout << "Can't open " << fn << "." << endl;
    15. exit(EXIT_FAILURE);
    16. }
    17. double objective; // 物镜的焦距
    18. cout << "Enter the focal length of telescope objective in mm: ";
    19. cin >> objective;
    20. double eps[LIMIT]; // 目镜的焦距
    21. for (int i = 0; i < LIMIT; i++) {
    22. cout << "Eyepieces #" << i + 1 << ": ";
    23. cin >> eps[i];
    24. }
    25. file_it(cout, objective, eps, LIMIT); // 在终端上显示
    26. file_it(fout, objective, eps, LIMIT); // 在文件中显示
    27. cout << "Done." << endl;
    28. return 0;
    29. }
    30. // ostream &os 基类的引用,可以指向基类的对象,也可以指向派生类的对象
    31. void file_it(ostream &os, double fo, const double fe[], int n) {
    32. os << "Focal length of objective: " << fo << endl;
    33. os << "f.l. eyepieces" << " magnification" << endl;
    34. for (int i = 0; i < n; i++) {
    35. os << " " << fe[i] << " " << int(fo / fe[i] + 0.5) << endl;
    36. }
    37. }

    8.3 默认参数

    默认参数的用法(取出字符串的前n个值)

    1. #include
    2. using namespace std;
    3. const int ArSize = 80;
    4. char *left(const char *str, int n = 1); // 默认参数n=1
    5. int main(){
    6. char sample[ArSize];
    7. cout << "Enter a string: " << endl;
    8. cin.get(sample, ArSize);
    9. char *ps = left(sample, 4);
    10. cout << ps << endl;
    11. delete[] ps; // 注意new和delete成对出现
    12. ps = left(sample); // 使用默认参数
    13. cout << ps << endl;
    14. delete[] ps;
    15. return 0;
    16. }
    17. char *left(const char *str, int n) {
    18. int m = 0;
    19. while (m < n && str[m] != '\0') m++; // 确定字符串长度
    20. char *p = new char[m + 1];
    21. int i;
    22. for (i = 0; i < m; i++) {
    23. p[i] = str[i];
    24. }
    25. p[i] = '\0'; // 最后要补上一个空字符
    26. return p;
    27. }

    8.4 函数重载

    函数重载示例(取出字符串/数字的前n个值)

    1. #include
    2. using namespace std;
    3. const int ArSize = 80;
    4. char *left(const char *str, int n = 1);
    5. unsigned long left(unsigned long num, unsigned int ct);
    6. int main(){
    7. const char *trip = "Hawaii";
    8. unsigned long n = 12345678;
    9. int i;
    10. char *temp;
    11. for (i = 0; i < 10; i++) {
    12. cout << left(n, i) << endl;
    13. temp = left(trip, i);
    14. cout << temp << endl;
    15. delete[] temp;
    16. }
    17. return 0;
    18. }
    19. char *left(const char *str, int n) {
    20. int m = 0;
    21. while (m < n && str[m] != '\0') m++; // 确定字符串长度
    22. char *p = new char[m + 1];
    23. int i;
    24. for (i = 0; i < m; i++) {
    25. p[i] = str[i];
    26. }
    27. p[i] = '\0'; // 最后要补上一个空字符
    28. return p;
    29. }
    30. unsigned long left(unsigned long num, unsigned int ct) {
    31. unsigned long n = num;
    32. unsigned int digits = 1;
    33. if (num == 0 || ct == 0) return 0; // 特殊情况
    34. while (n /= 10) digits++; // 判断数字有几位
    35. if (digits > ct) {
    36. ct = digits - ct; // 要除几次10
    37. while (ct--) num /= 10;
    38. return num;
    39. }
    40. else
    41. return num;
    42. }

    8.5 函数模板

    函数模板示例(交换两个数的值)

    1. #include
    2. using namespace std;
    3. template <typename T>
    4. void Swap(T &a, T &b);
    5. int main(){
    6. int i = 10;
    7. int j = 20;
    8. cout << "i, j = " << i << ", " << j << "." << endl;
    9. Swap(i, j);
    10. cout << "Afer swap, i, j = " << i << ", " << j << "." << endl;
    11. double x = 24.5;
    12. double y = 81.7;
    13. cout << "x, y = " << x << ", " << y << "." << endl;
    14. Swap(x, y);
    15. cout << "Afer swap, x, y = " << x << ", " << y << "." << endl;
    16. return 0;
    17. }
    18. template <typename T>
    19. void Swap(T &a, T &b) {
    20. T temp;
    21. temp = a;
    22. a = b;
    23. b = temp;
    24. }

    重载的模板示例(交换两个数或两个数组)

    1. #include
    2. using namespace std;
    3. template <typename T>
    4. void Swap(T &a, T &b);
    5. template <typename T>
    6. void Swap(T a[], T b[], int n);
    7. const int LIMIT = 8;
    8. void show(int arr[], int n);
    9. int main(){
    10. int i = 10;
    11. int j = 20;
    12. cout << "i, j = " << i << ", " << j << "." << endl;
    13. Swap(i, j);
    14. cout << "Afer swap, i, j = " << i << ", " << j << "." << endl;
    15. int d1[LIMIT] = { 0,7,0,4,1,7,7,6 };
    16. int d2[LIMIT] = { 0,7,2,0,1,9,6,9 };
    17. cout << "Original arrays: " << endl;
    18. show(d1, LIMIT);
    19. show(d2, LIMIT);
    20. Swap(d1, d2, LIMIT);
    21. cout << "After swap: " << endl;
    22. show(d1, LIMIT);
    23. show(d2, LIMIT);
    24. return 0;
    25. }
    26. template <typename T>
    27. void Swap(T &a, T &b) {
    28. T temp;
    29. temp = a;
    30. a = b;
    31. b = temp;
    32. }
    33. template <typename T>
    34. void Swap(T a[], T b[], int n) {
    35. T temp;
    36. for (int i = 0; i < n; i++) {
    37. temp = a[i];
    38. a[i] = b[i];
    39. b[i] = temp;
    40. }
    41. }
    42. void show(int arr[], int n) {
    43. for (int i = 0; i < n; i++) {
    44. cout << arr[i] << " ";
    45. }
    46. cout << endl;
    47. }

    调用函数时的最佳匹配(打印数组内容)

    1. #include
    2. using namespace std;
    3. template <typename T>
    4. void ShowArray(T arr[], int n);
    5. template <typename T>
    6. void ShowArray(T *arr[], int n);
    7. struct debts {
    8. char name[50]; // 名字
    9. double amount; // 数量
    10. };
    11. int main(){
    12. int things[6] = { 13,31,103,301,310,130 };
    13. struct debts mr_E[3] =
    14. {
    15. {"Rick", 2400.00},
    16. {"Jack", 1300.0},
    17. {"Rose", 1800.0}
    18. };
    19. double *pd[3]; // 3个元素的数组,每个元素都是指针
    20. for (int i = 0; i < 3; i++) {
    21. pd[i] = &mr_E[i].amount;
    22. }
    23. ShowArray(things, 6);
    24. // 更匹配 void ShowArray(T *arr[], int n)
    25. // 会打印出来指针指向的数值
    26. ShowArray(pd, 3);
    27. return 0;
    28. }
    29. template <typename T>
    30. void ShowArray(T arr[], int n) {
    31. cout << "template A:" << endl;
    32. for (int i = 0; i < n; i++)
    33. cout << arr[i] << " ";
    34. cout << endl;
    35. }
    36. template <typename T>
    37. void ShowArray(T *arr[], int n) {
    38. cout << "template B:" << endl;
    39. for (int i = 0; i < n; i++)
    40. cout << *arr[i] << " ";
    41. cout << endl;
    42. }

    引导编译器使用指定函数(打印较小的值)

    1. #include
    2. using namespace std;
    3. template <class T>
    4. T lesser(T a, T b) { // 函数1 返回较小值
    5. return a < b ? a : b;
    6. }
    7. int lesser(int a, int b) { // 函数2 返回绝对值的较小值
    8. a = a < 0 ? -a : a;
    9. b = b < 0 ? -b : b;
    10. return a < b ? a : b;
    11. }
    12. int main(){
    13. int m = 20, n = -30;
    14. double x = 15.5, y = -25.9;
    15. // 非模板函数优先,调用的是函数2
    16. cout << lesser(m, n) << endl;
    17. // 非模板函数不是最优(要进行类型转换),调用的是函数1
    18. cout << lesser(x, y) << endl;
    19. // 尖括号<>告诉编译器使用模板函数,调用函数1
    20. cout << lesser<>(m, n) << endl;
    21. // 把x和y强制转换为int类型,再使用模板函数2
    22. cout << lesser<int>(x, y) << endl;
    23. return 0;
    24. }

  • 相关阅读:
    如何避免osg绘制场景时因Z冲突导致绘制重影或不正常
    安全协议分类
    Hadoop的集群搭建及HDFS命令
    Visual studio代码提示(IntelliSense)的语言(包括汉化等)修改
    华为HCIA无线题库(H12-811)
    用HTML、CSS和JavaScript制作的通用进制转换器
    前端学习笔记--TypeScript
    QLineEdit设置数据的输入范围QIntValidator和QDoubleValidator
    android studio编译SDL so库
    Objective-C对象dealloc过程
  • 原文地址:https://blog.csdn.net/Mako5455/article/details/134418073