美文网首页
02_C++笔记_函数

02_C++笔记_函数

作者: 平头哥2 | 来源:发表于2019-05-27 13:51 被阅读0次
    #include <iostream>
    using namespace std;
    
    void func_demo();//函数的原型
    
    /**
     * 函数:要提高编程效率,可以深入学习STL和BOOST C++提供的功能
     * 函数使用三步骤:
     * 1. 函数的原型
     * 2. 函数的定义
     * 3. 函数的调用
     */
    int main() {
    
        //函数的调用
        func_demo();
        return 0;
    }
    
    //函数的定义
    void func_demo(){
        cout << "function demo" << endl;
    }
    

    复习数组和指针的关系:

    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    
    int main(){
    
        int arr[4] = {1,2,3,4};
    
        cout << arr << endl;
        cout << arr+1 << endl;
        cout << "---------------"<< endl;
        cout << &arr[0] << endl;
        cout << &arr[0]+1<< endl;
        cout << "---------------"<< endl;
        cout << &arr << endl;
        cout << &arr+1 << endl;
        cout << &arr+2 << endl;
    
        cout << sizeof(arr) << endl;
    
        cout << "---------------"<< endl;
        cout << arr[1] << endl;
        cout << *(arr+1) << endl;
    
        cout << "---------------"<< endl;
        cout << &arr[1] << endl;//0x61ff04
        cout << arr+1 << endl;//0x61ff04
        return 0;
    }
    

    结果如下:

    0x61ff00
    0x61ff04
    ---------------
    0x61ff00
    0x61ff04
    ---------------
    0x61ff00
    0x61ff10
    0x61ff20
    16
    ---------------
    2
    2
    ---------------
    0x61ff04
    0x61ff04
    

    数组和指针作为参数传递:

    #include <iostream>
    
    using namespace std;
    
    const int ArSize = 4;
    int sum_arr(int arr[], int ArSize);
    int sum_arr(double arr[], int ArSize);
    int sum_arr02(int * arr, int ArSize);
    
    int main(){
    
        cout << sizeof (double *) << endl;
    
        int arr[ArSize] = {1,2,3,4};
    
        /**
         * 这里是将arr的地址传递给了sum_arr函数
         * 并不是将arr的内容 {1,2,3,4} 赋值给了 sum_arr函数的第一个参数
         * 这并不违反C++值传递的方法,这里也是值传递,只是传递的是一个地址,而不是数组的内容。
         * 
         * 而赋值给ArSize是值拷贝
         * */
        cout << arr << endl;
        cout << sizeof arr << endl;
    
        int sum1 = sum_arr(arr, ArSize);
        cout << sum1 << endl;
    
        int sum2 = sum_arr02(arr, ArSize);
        cout << sum2 << endl;
    
        double arr2[ArSize] = {};
        sum_arr(arr2,ArSize);
        return 0;
    }
    
    int sum_arr(double arr[], int ArSize){
         cout << sizeof arr << endl;//4
         return 0;
    }
    
    int sum_arr(int arr[], int ArSize){
    
        //'sizeof' on array function parameter 'arr' will return size of 'int*'
        cout << sizeof arr << endl;//4
    
        cout << arr << "函数中的值" << endl;
        int sum = 0;
        for (int i = 0; i < ArSize; i++)
        {
            sum += arr[i];
        }
        
        return sum;
    }
    
    int sum_arr02(int * arr, int ArSize){
    
        int sum = 0;
        for (int i = 0; i < ArSize; i++)
        {
            sum += arr[i];
        }
        
        return sum;
    }
    

    进一步改进:

    #include <iostream>
    
    using namespace std;
    
    const int ArSize = 4;
    //参数定义数组的开始地址和结束地址
    int sum_arr(const int *begin, const int *end);
    
    int main()
    {
        int arr[ArSize] = {1, 2, 3, 4};
    
        int sum = sum_arr(arr, arr + ArSize);
        cout << sum;//10
        return 0;
    }
    
    int sum_arr(const int *begin, const int *end)
    {
    
        const int *pt;
        int sum = 0;
        for (pt = begin; pt != end; pt++)
        {
            sum += *pt;
        }
        return sum;
    }
    

    const和指针,

    //1. const修饰一个常量对象,防止使用该指针来修改所指向的值
    const int age = 34;
    //age = 23;//assignment of read-only variable 'age'
    //int * p = &age;//invalid conversion from 'const int*' to 'int*' [-fpermissive]
    const int * p = &age;//valid
    //2. const修改一个指针对象,防止改变指针指向的位置
    int main(){
    
        int age1 = 34;
        //*p 为const,不能被修改
        //p 不是const,可以被修改
        // 也就是说不能通过 *p 来修改变量age1的值
        //但是可以通过age1变量来修改
        const int * p = &age1;
    
        //*p += 1;//assignment of read-only location '* p'
        cout << p << endl;//0x63ff08
        cout << *p << endl;//34
    
        age1 = 23;//重新赋值
        cout << *p << endl;//23
        p = p+1;
        cout << p;//0x63ff0c
    
        return 0;
    }
    

    指针指向指针:

    int main(){
    
        //指针指向指针
        int age = 34;
        int * pd = &age;
        int **pt = &pd;
    
        cout << &age << endl;//0x63ff08
        cout << pd << endl;//0x63ff08
        cout << * pd << endl;//34
        // ** pt = pd;
        //*pt  = pd;
        // pd = &age
        // => *pt = &age;
    
        cout << &pd << endl;//0x63ff04
        cout << pt << endl;//0x63ff04 pt指向的是pd的地址
        cout << * pt << endl;//0x63ff08 *pt 保存的是pd指针的内容
        cout << ** pt << endl;//34
        return 0;
    }
    
    int main() {
    
        int sloth = 3;
    
        const int * ps = &sloth;
        cout << ps << endl;//0x63ff04
        //* ps = 23;//assignment of read-only location '* ps'
        cout << ps+1 << endl;//0x63ff08
    
        int * const finger = &sloth;
        cout << finger << endl;//0x63ff04
        * finger = 24;
        cout << * finger << endl;//24
        cout << finger+1 << endl;//0x63ff08
    
        double a = 34.5;
        const double * const pa = &a;
        return 0;
    }
    
    //不能将const修饰的nums赋值给非const修饰的形参
    const int nums[3] = { 1, 2, 3 };
    

    函数和C-风格字符串

    #include <iostream>
    
    unsigned int c_in_str(const char * str, char ch);
    char * build_str(char c, int n);
    
    using namespace std;
    
    int main() {
    
        char mmm[15]="helloworld";
        unsigned int count = c_in_str(mmm,'o');
        cout << count << endl;
        char * pstr = build_str('M', 5);
        cout << &pstr[0] << endl;//MMMMM
        cout << &pstr[1] << endl;//MMMM
        cout << pstr[0] << endl;//M
        cout << pstr[1] << endl;//M
        cout << * pstr << endl;//M
        cout << pstr << endl;//MMMMM
        cout << (int * )pstr << endl;//0x681be8
        cout << &pstr << endl;//0x63fef8
        cout << (int * )(pstr+1) << endl;//0x681be9
    
        cout << ((int *)pstr+1) << endl;//0x681bec
        delete [] pstr;//释放内存,不等于变量销毁。
        return 0;
    }
    
    /**
     * 1. 函数和C-风格字符串
     *  C-风格字符串:一系列字符组成,以空值字符结尾
     *  将字符串作为参数时,意味着传递的是地址,
     *  可以使用const来禁止怼字符串参数进行修改
     * 2. 字符串三种表示:
     *  2.1 char数组(C-风格字符串和char数组重要区别:字符串有内置结束字符)
     *  2.2 用引号括起来的字符串常量
     *  2.3 被设置为字符串的地址的char指针
     *
     */
    
    //处理字符串中字符的标准方式
    unsigned int c_in_str(const char * str, char ch){
    
        cout << *str << endl;
    
        unsigned int count = 0;
        while(*str){ //quit 当是结束字符'\0'时,该表达式为false
            if(*str == ch){
                count++;
            }
            str++;//指针向下移动一位
        }
    
        return count;
    }
    
    //返回C-风格的字符串
    //函数无妨返回一个字符串,但是可以返回一个字符串的地址
    char * build_str(char c, int n){
        char * pstr = new char[n+1];
        cout << "build_str:"<< &pstr << endl;
        pstr[n] = '\0';
    
        while(n-- > 0){
            pstr[n] = c;
        }
        return pstr;
    }
    

    函数和结构:

    #include <iostream>
    using namespace std;
    
    struct travel_time {
        int hours;
        int mins;
    };
    
    const int Mins_per_hr = 60;
    travel_time sum(travel_time t1, travel_time t2);
    void show_time(travel_time t);
    
    struct rect {
        double x;
        double y;
    };
    
    struct polar {
        double r;
        double angle;
    };
    
    const int Rad_to_deg = 57.3;
    polar rect_to_polar(rect r);
    void show_polar(polar p);
    
    void rect_to_polar2(rect * r, polar * pda);
    void show_polar2(const polar * pda);
    
    int main() {
    
        //1.1 传递和返回结构
        travel_time t1 = { 1, 23 };
        travel_time t2 = { 2, 53 };
        travel_time t = sum(t1, t2);
        show_time(t); //hours:4,mins:16
        rect rplace = { 100, 100 };
        polar p = rect_to_polar(rplace);
        show_polar(p); //r:141.421 angel:44.7677degrees
    
        //1.2 传递结构的地址
        polar place;
        rect_to_polar2(&rplace, &place);
        show_polar2(&place); //r:141.421 angel:44.7677degrees
        return 0;
    }
    
    /**
     * 1. 函数和结构
     */
    
    //1.1 传递和返回结构
    travel_time sum(travel_time t1, travel_time t2) {
    
        travel_time total;
        total.mins = (t1.mins + t2.mins) % Mins_per_hr;
        total.hours = (t1.hours + t2.hours) + (t1.mins + t2.mins) / Mins_per_hr;
    
        return total;
    }
    void show_time(travel_time t) {
        cout << "hours:" << t.hours << ",mins:" << t.mins << endl;
    }
    
    #include <cmath>
    
    polar rect_to_polar(rect r) {
        polar answer;
        answer.r = sqrt(r.x * r.x + r.y * r.y);
        answer.angle = atan2(r.y, r.x);
        return answer;
    }
    void show_polar(polar p) {
        cout << "r:" << p.r << endl;
        cout << "angel:" << p.angle * Rad_to_deg << "degrees" << endl;
    }
    
    //1.2 传递结构的地址
    void show_polar2(const polar * pda) {
        cout << "r:" << pda->r << endl;
        cout << "angel:" << pda->angle * Rad_to_deg << "degrees" << endl;
    }
    
    void rect_to_polar2(rect * r, polar * p) {
    
        p->r = sqrt(r->x * r->x + r->y * r->y);
        p->angle = atan2(r->y, r->x);
    }
    

    函数和string

    #include <iostream>
    using namespace std;
    
    void test();
    void display(const string sa[], int n);
    
    int main() {
    
        test();
        return 0;
    }
    
    void test() {
        const int SIZE = 5;
        string list[SIZE]; //数组,存储了5个字符串对象
        for (int i = 0; i < SIZE; i++) {
            cout << i + 1 << ":";
            getline(cin, list[i]);
        }
    
        cout << "your list:" << endl;
        display(list, SIZE);
    }
    
    //函数和string
    void display(const string sa[], int n) {
        for (int i = 0; i < n; i++) {
            cout << i+1 << ":" << sa[i] << endl;
        }
    }
    
    

    函数和array

    #include <iostream>
    #include <array>
    #include <string>
    
    const int Seasons = 4;
    const std::array<std::string, Seasons> Snames = { "Spring", "Summer", "fall",
            "winter" };
    
    //修改array
    void fill(std::array<double, Seasons> * pa);
    //显示array
    void show(std::array<double, Seasons> da);
    
    int main() {
    
        std::array<double, Seasons> expenses;
    
        fill(&expenses);
        show(expenses);
    
        return 0;
    }
    
    //修改array
    void fill(std::array<double, Seasons> * pa) {
        using namespace std;
        for (int i = 0; i < Seasons; ++i) {
            cout << "enter " << Snames[i] << " expenses:";
            cin >> (*pa)[i];
        }
    }
    //显示array
    void show(std::array<double, Seasons> da) {
        using namespace std;
        double total = 0.0;
        cout << "\n expenses: " << endl;
        for (int i = 0; i < Seasons; ++i) {
            cout << Snames[i] << ": $" << da[i] << " expenses:";
            total += da[i];
        }
        cout << "total:" << total << endl;
    }
    
    //结果如下:
    enter Spring expenses:23.4
    enter Summer expenses:45.6
    enter fall expenses:67.8
    enter winter expenses:78.9
    
     expenses: 
    Spring: $23.4 expenses:Summer: $45.6 expenses:fall: $67.8 expenses:winter: $78.9 expenses:total:215.7
    

    函数指针:

    #include <iostream>
    #include <array>
    #include <string>
    
    double a(int lns);
    double b(int lns);
    void estimate(int lines, double (*pf)(int));
    int main() {
    
        using namespace std;
    
        int lines = 5;
    
        estimate(lines, a);//传递函数的地址
        estimate(lines, b);
    
        return 0;
    }
    
    /**
     * 1. 函数指针
     *  1.1  获取函数的地址: 函数名就是函数的地址
     *      process(think);// 将函数think的地址传递给process()
     *      process(think());// 将函数think()的返回值传递给process()
     *
     *  1.2  声明一个函数指针
     *      声明某种类型的指针时,必须指定指针指向的类型。
     *      同样:声明指向函数的指针时,必须指定指针指向的函数类型。
     *
     *      例如:
     *      double pam(int);//函数原型
     *      double (* pf)(int);// pf 指向了一个函数:接收一个int类型参数,并返回一个double类型
     *      这里:pam是函数,(* pf)也是函数,那么 pf 就是函数指针
     *
     *      通常:
     *      声明函数指针,先声明函数原型,然后将(* pf) 替换函数名。这样pf就是这类函数指针
     *
     *      赋值:
     *      double ned(int);
     *      double (* pf)(int);
     *      pf = ned;//赋值
     *
     *  1.3  使用函数指针来调用函数
     *      调用:
     *      形式1:double x = (* pf)(5);--很清晰的看出来在使用函数指针
     *      形式2:double x = pf(5);
     */
    
    double a(int lns) {
        return 0.5 * lns;
    }
    
    double b(int lns) {
        return 0.5 * lns + 0.02 * lns * lns;
    }
    
    void estimate(int lines, double (*pf)(int)) {
        using namespace std;
    
        cout << lines << " lines will take " << (*pf)(lines) << " hours" << endl;
    }
    

    深入理解函数指针:

    #include <iostream>
    #include <array>
    #include <string>
    
    //f1,f2,f3 实质是一样的
    const double * f1(const double arr[], int n);
    const double * f2(const double[], int n);
    const double * f3(const double *, int n);
    
    //声明一个函数指针,并初始化,指向f1
    const double * (*pf)(const double arr[], int n) = f1;
    //C++11 可以使用自动类型推断,声明一个函数指针,并初始化,指向f2
    auto p2 = f2;
    
    //声明一个包含三个函数指针的数组,注意[3]的位置
    //这里不能使用auto.因为自动类型推断只能用于单值初始化,而不能初始化列表
    const double * (*pa[3])(const double *, int n) = {f1,f2,f3};
    //声明pa之后,可以使用auto再声明一个
    auto pb = pa;
    
    //数组名是指向第一个元素的指针,因此pa和pb都是指向函数指针的指针。
    //如何使用它们来调用函数呢?
    //const double * px = pa[0](av,3); 调用第一个函数
    //const double * px = (*pa[1])(av,3); 调用第二个函数
    
    //获取函数返回的double的值
    //double x = *pa[0](av,3);
    //double y = *(*pb[1])(av,3);
    
    
    //创建指向整个数组的指针。
    //1. 用自动类型推断
    auto pc = &pa;
    //2. 使用声明的类型
    const double * (*(*pd)[3])(const double *, int) = &pa;
    
    int main() {
    
        using namespace std;
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:02_C++笔记_函数

          本文链接:https://www.haomeiwen.com/subject/cbqhtctx.html