美文网首页C++
c++基础(const关键词, 命名空间, 引用, 内联函数)

c++基础(const关键词, 命名空间, 引用, 内联函数)

作者: 前几 | 来源:发表于2018-09-14 16:48 被阅读7次

    title: c++基础(const关键词, 命名空间, 引用, 内联函数)
    date: 2018-09-11 18:09:01
    tags:


    正好这学期在学c++, 打算把自己学习的都记录一下.

    这篇文章主要是c++中的一些不同于c的特性.

    const关键词

    const通常用来表示常量,主要有以下一些用法:

    符号常量

    const type V = value表示V是一个常量.

    在c语言中常量可以用宏定义, 如#define PI 3.14. 这种方式在编译时把代码中的PI全都替换为3.14, 就是说PI这个常量是没有被保存在内存中的. 而用cosnt定义的变量会保存在内存的常量区.

    修饰函数形参

    用cosnt修饰的形参在函数指向过程中不能被修改.

    int func(const int a) {
    //    a++;//error
        return a + 5;
    }
    

    当一个函数的功能明确不能或者不需要修改参数时可以用cosnt修饰该参数.

    修饰指针变量

    const修饰指针变量有以下三种情况:

    指向常量的指针

    指向常量的指针, 也可以指向变量, 但是指针认为它指向了常量, 所以不能通过指针修改.

        cosnt int a = 10;
        int b = 11;
        const int *p_a = &a;//a是常量
        const int *p_b = &b;//ok, 指向常量的指针也能指向变量
    //    *p_a = 5;//error
    //    *p_b = 6;//error虽然指向变量, 但是不能通过指针修改
    

    常指针

    指针变量是个常量, 必须初始化. 不能指向常量(常量只能被指向常量的指针指向), 可以通过指针修改. 其实就相当于一个普通指针, 但是赋初值后不能修改指向的地址.

    //    int *const p = &a;//error
    //    不能指向常量
        int *const p = &b;
        *p = 20;//ok
    //    p = &a;//error
    //    不能被修改
    

    类中的this指针就是个常指针, 只能指向当前对象.

    指向常量的常指针

    只能指向常量, 而且本身是个常量, 是前两者的结合体.

    //      c 指向常量的常指针 什么都不能改
        const int *const p_c = &a;
    

    命名空间(namespace)

    namespace可以用来区别不同文件里的相同名称的函数, 变量等.

    namespace first_space {
        int a = 10;
    
        int func(const int a);
    //    嵌套namespace
        namespace second_space {
            int b = 11;
        }
    }
    
    //不连续命名空间
    namespace first_space {
    //    int a = 10;//error
        int b = 12;
    }
    
    //对命名空间中函数的实现
    int first_space::func(const int a) {
        return a + 10;
    }
    

    要使用命名空间中的成员, 需要使用::运算符, 如first_space::a.

    可以用using namespace space_name;来表示使用的命名空间, 这样可以省略命名空间, 比如要使用c++的标准库, 一般会using namespace std;.

    引用(reference)

    引用相当于给变量取个别名.

    int e = 10;
    int &f = e;
    cout << e << endl;
    f = 11;
    cout << e << endl;
    

    这里f相当于是e的一个别名, 修改两者中的任何一个, 另一个会跟着一起改变.

    按引用传参

    c++的默认传参方式是按值传参, 实参的值会被复制到形参中.

    而按引用传参不会复制, 而是直接引用实参, 不过会给实参取一个别名.

    void add_five(int &a) {
        a += 5;
    }
    

    其实大多数编程语言都是默认都是按值调用(call by value), 比如对于java来说只有call by value, 而c++有两种参数传递方式: 按值调用(call by value), 按引用调用(call by reference).

    指针传递

    c++传递指针作为参数, 还是call by value

    void func(int *p) {
        *p = 10;//通过指针可以修改指向的值
        p = NULL;//但是调用处的指针变量不会因为p变成NULL也变成NULL
        //因为调用处把传递的指针的值复制一份给了p, 修改p不会改变原来指针的值
    }
    

    java call by reference?

    java中的对象变量储存的是对象的应用, 那么把对象变量作为参数传递是call by reference吗? 事实上, 这还是call by value, 不过传递的是引用的备份, 类似于c/c++中传递指针.

    public static void swap(Object a, Object b) {//doesn't work
        Object temp = a;
        a = b;
        b = a;
    }
    //call
    swap(a, b);
    

    调用swap函数处a, b的值并没有变化, 因为函数中只是a, b引用的备份, 并非调用处a, b. 而正真的call by reference 是可以改变调用处实参的值.

    void swap(int &a, int &b) {
        int temp = a;
        a = b;
        b = a;
    }
    //call
    int a = 4, b = 5;
    swap(a, b);
    //a = 5, b =4
    

    好像很多人都没有搞清楚call by reference, 事实上call by reference只存在少数编程语言中. 虽然有时它的应用会简化程序, 不过个人认为call by value更加符合程序设计原则(不负责任偏激的见解).

    修饰函数返回值

    这是个有点变态的操作, 暂时没有搞懂有什么神奇操作

    int &fn(int &b) {
        return b;
    }
    //main
    int n = 9;
    fn(n) = 11;
    //此时n=11
    

    是不是很变态, 我第一看到也一脸懵逼.

    内联函数(inline)

    内联函数, 这是一个很实用的特性. 内联函数并不会真的被调用, 简单来说就是把函数的语句直接复制到执行的地方执行, 但是又不是像宏无脑的替换. 对于一些经常调用的函数, 这样可以减少函数调用的开销.

    inline int max(int a, int b) {
        return a > b ? a : b;
    }
    
    //main
    int a = 10, b = 20;
    int c = max(++a, --b);
    //c = 19
    

    调用max的地方语句会被这样替换:

    ++a;
    --b;
    int c = a > b ? a : b;
    

    对比以下宏定义的方式:

    #define max(a, b) ((a) > (b) ? (a) : (b))
    //main
    int a = 10, b = 20;
    int c = max(++a, --b);
    //c = 18
    //此处语句被替换为
    int c = (++a) > (--b) ? (++a) : (--b);
    //所以最后结果为18
    

    相关文章

      网友评论

        本文标题:c++基础(const关键词, 命名空间, 引用, 内联函数)

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