zoukankan      html  css  js  c++  java
  • [C++ Primer Plus] 第8章、函数探幽(一)程序清单——内联、引用、格式化输入输出、模板、decltype

    程序清单8.1(inline内联函数)

    #include<iostream>
    using namespace std;
    
    inline double square(double x) {//inline表示内联函数
        return x*x;
    }
    
    void main()
    {
        double a, b, c = 13.0;
        a = square(5.0);
        b = square(4.5+7.5);
        cout << "a=" << a << ",b=" << b << endl;
        cout << "c=" << c << ",c square=" << square(c++) << endl;
        cout << "Now c=" <<c<< endl;
        system("pause");
    }

    程序清单8.2+8.3(引用变量)

    引用变量的主要用途是作为函数的形参:引用变量做参数,函数将使用原始数据

    #include<iostream>
    using namespace std;
    
    void main()
    {
        int rat = 101;
        int &rodent = rat;//将rodent的类型声明为int&,即指向int变量的引用
        cout << "rat=" <<rat<< ",rodent=" <<rodent<< endl;
        rodent++;
        cout << "Now,rat=" << rat << ",rodent=" << rodent << endl;
        cout << "rat address=" << &rat << endl;
        cout << "rodent address=" <<&rodent<< endl;
    
        cout << "************************************" << endl;
        int bunny = 50;
        rodent = bunny;
        cout << "rat=" << rat << ",rodent=" << rodent<<",bunny="<<bunny << endl;
        cout << "bunny address=" << &bunny << endl;
        cout << "rodent address=" << &rodent << endl;
    
        system("pause");
    }


     临时变量、引用参数和const

    如果实参与引用参数不匹配,仅当参数为const引用时,C++将生成临时变量。

    程序清单8.6

    #include<iostream>
    #include<string>
    using namespace std;
    
    struct  free_throw
    {
        string name;
        int made;
        int attempt;
        float percent;
    };
    void display(const free_throw &ft) {
        cout << "Name=" << ft.name << endl;
        cout << "Made=" << ft.made << "		";
        cout << "Attempt=" << ft.attempt<< "	";
        cout << "Percent=" << ft.percent<<endl;
    }
    void set(free_throw &ft) {
        if (ft.attempt != 0)
            ft.percent = 100.0f*float(ft.made) / float(ft.attempt);
        else
            ft.percent = 0;
    }
    free_throw & accumulate(free_throw &target,const free_throw &source) {
        target.attempt += source.attempt;
        target.made += source.made;
        set(target);
        return target;
    }
    
    void main()
    {
        free_throw one = { "If Branch",13,14 };
        free_throw two = { "Andor Knott",10,16 };
        free_throw three = { "Min Max",7,9 };
        free_throw four = { "Whi Loo",5,9 };
        free_throw five = { "Long Long",6,14 };
        free_throw team = { "Throw",0,0};
        free_throw dup;
    
        set(one);
        display(one);
        accumulate(team, one);
        display(team);
        display(accumulate(team,two));
        accumulate(accumulate(team, three), four);
        display(team);
        dup = accumulate(team, five);//返回的team赋给dup
        cout << "Displaying team:" << endl;
        display(team);//team经过48行代码,已经发生了变化
        cout << "Displaying dup after assignment:" << endl;
        display(dup);
        set(four);
        accumulate(dup, five) = four;//four赋给dup
        cout << "Displaying dup after ill-advised assignment:" << endl;
        display(dup);
    
        system("pause");
    }

     程序清单8.7

    string:标准库允许把字符串字面值和字符字面值转换为 string 对象,当把 string 对象和字符字面值以及字符串字面值混在一条语句中使用时,必须确保加法运算符( + )的两侧运算对象至少有一个是 string:

    #include <iostream>  
    #include <string>  
    using namespace std;
    
    string version1(const string &s1, const string &s2) {
        string tmp;
        tmp = s2 + s1 + s2;
        return tmp;//返回main函数时,tmp不复存在,但tmp的内容被复制到临时存储单元
    }
    string & version2(string &s1, const string &s2) {//有副作用,改变了s1的内容
        s1 = s2 + s1 + s2;
        return s1;
    }
    string & version3(string &s1, const string &s2) {//坏设计
        string tmp;
        tmp = s2 + s1 + s2;
        return tmp;//返回main函数时,tmp内存已被释放,程序不能引用已经释放的内存
    }
    
    void main()
    {
        string input, copy, result;
        cout << "Enter a string:";
        getline(cin, input);//用于字符串的输入
        copy = input;//C++中,string可以直接赋值
        cout << "Your string as entered:" << input << endl;
        result = version1(input, "***");
        cout << "Your string enhanced:" << result << endl;
        cout << "Your original string:" << input << endl;
    
        result = version2(input, "###");
        cout << "Your string enhanced:" << result << endl;
        cout << "Your original string:" << input << endl;
    
        cout << "Resetting original string." << endl;
        input = copy;
        result = version3(input, "@@@");//version3返回地址值时报错,因为该地址已释放
        cout << "Your string enhanced:" << result << endl;
        cout << "Your original string:" << input << endl;
    
        system("pause");
    }

     程序清单8.8(格式化输入输出)

    #include <iostream>  
    #include <fstream>  
    #include <cstdlib>  
    using namespace std;
    const int LIMIT = 5;
    
    void file_it(ostream &os,double fo,const double fe[],int n) {//参数os可以指向ostream对象(如cout),也可以指向ofstream对象(如fout)
        ios_base::fmtflags initial;//ios_base::fmtflags是存储这种信息所需的数据类型名称
        initial = os.setf(ios_base::fixed);//setf(ios_base::fixed)使用定点表示法 表示对象
        os.precision(0);//指定显示多少位小数(假定处于定点模式下)
        os << "Focal length of objective:" << fo << " mm"<<endl;
        os.setf(ios::showpoint);//使用小数点 表示对象,即使小数部分为0
        os.precision(1);
        os.width(12);//设置下一次输出操作使用的字段宽度,只在显示下一个值时有效
        os << "f.1. eyepiece";
        os.width(15);
        os << "magnification" << endl;
        for (int i = 0; i < n; i++)
        {
            os.width(12);
            os << fe[i];
            os.width(15);
            os << int(fo / fe[i] + 0.5) << endl;
        }
        os.setf(initial);//返回调用它之前有效的所有格式化设置,即将对象回到传递给file_it()之前的状态
        //当程序将cout传递给file_it()时,cout的设置将被修改,然后被恢复;fout同样如此
    }
    void main()
    {
        ofstream fout;
        const char *fn = "ep-data.txt";
        fout.open(fn);
        if (!fout.is_open()) {
            cout << "Can't open "<< fn <<".Bye."<< endl;
            exit(EXIT_FAILURE);
        }
        double objective;
        cout << "Enter ……:";
        cin >> objective;
        double eps[LIMIT];
        cout << "Enter XXX" << endl;
        for (int i = 0; i < LIMIT; i++)
        {
            cout << "Eyepiece #" << i + 1 << ": ";
            cin >> eps[i];
        }
        file_it(fout, objective, eps, LIMIT);//将数据写入文件ep-data.txt
        file_it(cout, objective, eps, LIMIT);//将同样的信息以相同的格式显示到屏幕上
        cout << "Done" << endl;
        system("pause");
    }

    以下是一些常见的控制函数的:
    dec 置基数为10 相当于"%d"
    hex 置基数为16 相当于"%X"
    oct 置基数为8 相当于"%o"
    setfill(c) 设填充字符为c
    setprecision(n) 设显示小数精度为n位
    setw(n) 设域宽为n个字符

    setioflags(ios::fixed) 固定的浮点显示
    setioflags(ios::scientific) 指数表示
    setiosflags(ios::left) 左对齐
    setiosflags(ios::right) 右对齐
    setiosflags(ios::skipws 忽略前导空白
    setiosflags(ios::uppercase) 16进制数大写输出
    setiosflags(ios::lowercase) 16进制小写输出
    setiosflags(ios::showpoint) 强制显示小数点
    setiosflags(ios::showpos) 强制显示符号

     程序清单8.9(默认参数)

    #include <iostream>   
    using namespace std;
    
    const int Size = 80;
    char *left(const char *str, int n = 1);//默认n为1
    
    void main()
    {
        char sample[Size];
        cout << "Enter a string:
    ";
        cin.get(sample, Size);
        char *p = left(sample, 4);//调用此方法后要记得delete
        cout << p << endl;
        delete[] p;
    
        p = left(sample);
        cout << p << endl;
        delete[] p;
        system("pause");
    }
    
    char *left(const char *str, int n) {//内部使用了new未delete,所以在main函数调用此方法后一定要记得delete
        if (n < 0)
            n = 0;
        char *p = new char[n + 1];//new和delete成对出现
        int i;
        for (i = 0; i < n&&str[i]; i++)
            p[i] = str[i];
        while (i <= n)
            p[i++] = '';
        return p;
    }

    程序清单8.10(函数重载)

    #include <iostream>   
    using namespace std;
    
    char *left(const char *str, int n) {//内部使用了new未delete,所以在main函数调用此方法后一定要记得delete
        if (n < 0)
            n = 0;
        char *p = new char[n + 1];//new和delete成对出现
        int i;
        for (i = 0; i < n&&str[i]; i++)
            p[i] = str[i];
        while (i <= n)
            p[i++] = '';
        return p;
    }
    unsigned long left(unsigned long num, unsigned ct) {
        if (ct == 0 || num == 0)
            return 0;
        unsigned digit = 1;
        unsigned long n = num;
        while (n /= 10)
            digit++;
        if (digit > ct) {
            ct = digit - ct;
            while (ct--)
                num /= 10;
            return num;
        }
        else
            return num;
    }
    void main()
    {
        char *trip = "Hawaii!!";
        unsigned long n = 12345678;
        int i;
        char * temp;
        for (i = 1; i < 10; i++)
        {
            cout << left(n, i) << endl;
            temp = left(trip, i);
            cout << temp << endl;
            delete[] temp;
        }
        system("pause");
    }

    程序清单8.11+12(函数模板,模板重载)

    #include <iostream>   
    using namespace std;
    
    template <typename T>    //函数模板
    void swap2(T &a, T &b) { //引用        不能用swap函数名,用户自己定义的swap()函数与STL库定义的函数重载冲突
        T temp;
        temp = a;
        a = b;
        b = temp;
    }
    template <typename T>
    void swap2(T a[], T b[],int n) {
        T temp;
        for (int i = 0; i < n; i++)
        {
            temp = a[i];
            a[i] = b[i];
            b[i] = temp;
        }
    }
    
    const int Size = 5;
    template <class Te>//模板的另一种表示方式
    void show(Te a[]) {
        for (int i = 0; i < Size; i++)
        {
            cout << a[i] << "	";
        }
        cout << endl;
    }
    
    void main()
    {
        int i = 10, j = 20;
        cout << "i=" << i << ",j=" << j << endl;
        swap2(i, j);
        cout << "Now,i=" << i << ",j=" << j << endl;
    
        double x[Size] = { 1,2,3,4,5 };
        double y[] = {6,7,8,9,10};
        show(x);
        show(y);
        swap2(x, y ,Size);
        cout << "Now" << endl;
        show(x);
        show(y);
    
        system("pause");
    }

    程序清单8.13(模板显示具体化)

    #include <iostream>   
    using namespace std;
    
    //模板:交换a、b值
    template <typename T>
    void Swap(T &a, T &b) {
        T temp = a;
        a = b;
        b = temp;
    }
    
    struct job {
        char name[40];
        double salary;
        int floor;
    };
    //显示具体化:交换结构体内部成员值
    template <> void Swap<job>(job &j1, job &j2) {//引用
        double t1;
        int t2;
        t1 = j1.salary;
        j1.salary = j2.salary;
        j2.salary = t1;
    
        t2 = j1.floor;
        j1.floor = j2.floor;
        j2.floor = t2;
    }
    
    void show(job &j) {//引用
        cout << j.name << ":$"<<j.salary<<" on floor "<<j.floor<<endl;
    }
    
    void main()
    {
        cout.precision(2);//指定显示多少位小数(假定处于定点模式下):看有没有set ios::fixed,如果没有的话, 是代表2位有效数字, 不是3位小数
        cout.setf(ios::fixed,ios::floatfield);//ios::fixed设置为定点输出格式,floatfield设置输出时按浮点格式,小数点后有6位数字
        int i = 10, j = 20;
        cout << "i=" << i << ",j=" << j << endl;
        Swap(i, j);
        cout << "Now,i=" << i << ",j=" << j << endl;
    
        job sue = { "S Y",73000.60,7 };
        job sid = { "S T",78060.72,9 };
        show(sue);
        show(sid);
        Swap(sue, sid);
        show(sue);
        show(sid);
        system("pause");
    }

    程序清单8.14

    #include <iostream>   
    using namespace std;
    
    template <typename T>
    void show(T arr[],int n) {
        cout << "template A" << endl;
        for (int i = 0; i < n; i++)
            cout << arr[i] << ' ';
        cout << endl;
    }
    template <typename T>
    void show(T * arr[], int n) {//指针数组:[]比*优先级高
        cout << "template B" << endl;
        for (int i = 0; i < n; i++)
            cout << *arr[i] << ' ';
        cout << endl;
    }
    
    struct debt {
        char name[40];
        double amount;
    };
    
    void main()
    {
        int thing[6] = { 13,31,103,301,310,130 };
        struct debt mr_E[3] = {
            { "I W",2400.0 },
            { "U F",1300.0 },
            { "I S",1800.0 }
        };
        double *pd[3];
        for (int i = 0; i < 3; i++)
            pd[i] = &mr_E[i].amount;
        cout << "Listen:" << endl;
        show(thing, 6);
        cout << "Listen debts:" << endl;
        show(pd, 3);
    
        system("pause");
    }

    如果去掉   template B  ,打印出来的将是地址

    程序清单8.15

    #include <iostream>   
    using namespace std;
    
    //返回小值
    template <typename T>
    T lesser(T a,T b) {
        return a < b ? a : b;
    }
    //先取绝对值,再返回绝对值中的小值
    int lesser(int a, int b) {
        a = a < 0 ? -a : a;
        b = b < 0 ? -b : b;
        return a < b ? a : b;
    }
    
    void main()
    {
        int m = 20, n = -30;
        double x = 15.5, y = 25.9;
        cout << lesser(m, n) << endl;//调用函数
        cout << lesser(x, y) << endl;//调用模板函数
        cout << lesser<>(m, n) << endl;//<>表示调用模板函数
        cout << lesser<int>(x,y)<<endl;//<int>表示 显示实例化,强转xy值
    
        system("pause");
    }

     关键字decltype

  • 相关阅读:
    《程序设计与数据结构》 课程教学
    ISO GPS定位,坐标转换以及如何显示
    iOS_生成pem推送证书(用于百度云推送)
    iOS 基础-----关于UIView 的 frame 与 bounds
    IOS开发之UIScrollVIew运用
    ios 精简日历
    IOS UIView自动调整尺寸
    IOS 实现录音PCM转MP3格式(边录音边转码)
    IOS开发UIImage中stretchableImageWithLeftCapWidth方法的解释
    ios Coredata 关联 UITableView 数据自动更新
  • 原文地址:https://www.cnblogs.com/little-monkey/p/7593281.html
Copyright © 2011-2022 走看看