• C++笔记--1


    一、namespace 命名空间

    //定义一个命名空间
    namespace spaceA
    {
        int g_a = 10;
    }
    
    int main(void)
    {
        //调用方式一
        using namespace spaceA;
        cout << g_a << endl;
    
        //调用方式二
        using spaceA::g_a;
        cout << g_a <<endl;
    
        //调用方式三
        cout << spaceA::g_a <<endl;
        
        return 0;        
    }

    二、C++比C语言增强的地方

      1、C++定义变量没有必要再开头就定义,可以随用随定义。
        C语言要在开头就定义所有的变量。

      2、C++语言对全局变量的检测能力增强。

    (C语言合法)
    int g_a;    //bss段
    int g_a = 10;    //data段
    (C++语言非法)
    int g_a;    //bss段
    int g_a = 10;    //data段

      3、C++中三目运算符可以当左值

    int a = 10;
    int b = 20;
    int c = 0;
    c = (a < b) ? a : b;
    //三目运算符可以当左值
    ((a < b) ? a : b) = 50;
    //结果是a = 50;

        C语言中,三目运算符返回的是一个值,也就是一个常量,因此不能作为左值
        C++中,三目运算符返回的是一个变量的引用,可以被修改,因此可以作为左值


      4、const增强

    const int * c;    //指针所指向的空间不可通过解引用的方式修改,但是指针的指向可以修改。
    
    int * const c;    //指针的指向不可修改,但是指针所指向的空间内容可以通过解引用的方式修改。
    
    const int a = 10;
    int* p = (int*)&a;
    *p = 20;
    cout << a <<endl;
    cout << *p <<endl;
    
    //C语言输出 20 20
    //C++输出 10 20
    //C++分析
    const int a = 10;    //a是真正的常量
    int* p = (int*)&a;    //如果对一个常量取地址,编译器就会临时开辟一个空间temp,让这个指针存放这个临时空间的地址
    *p = 20;
    cout << a <<endl;
    cout << *p <<endl;
    
    //所以,在C语言中,const int a = 10;是假常量
    //    在C++中, const int a = 10;是真常量


    三、C++对C语言的拓展
      1、引用
        引用实际上可以理解为一个变量的别名

    1. 引用没有定义,是一种关系型声明。声明它和原有某一变量(实体)的关系。故而类型与原类型保持一致,且不分配内存。与被引用的变量有相同的地址。
    2. 声明的时候必须初始化,一经声明,不可变更。
    3. 可对引用再次引用,多次引用的结果,是某一变量具有多个别名。
    4. &符号前有数据类型,是引用。其他皆为取地址。
    int a = 10;
    int &re = a;    //int & 使用引用数据类型,re就是a的别名
    re = 50;
    cout << a << endl;    //结果是 a = 50;
    re = b;    //也就是给a赋值b,并非把re这个a的引用变更为b的引用
    int &re2 = re;    //re2是re的引用,也就是a的引用
    int &re3;    //非法!引用一定要初始化

        引用作为函数参数传进去的函数的时候,传的是地址,并没有值拷贝过程,因此可以节省内存。

        引用所占用的大小,跟指针是相等的,32位系统时占4个字节。

        const引用

    const int a = 10;    //如果想对一个常量进行引用,必须是一个const引用
    const int &re = a;
    
    int b = 20;
    const int &re2 = b;    //相反,如果一个普通变量,用一个const引用接收是可以的
    re2 = 30;    //非法,因为re2是const类型,不能修改

      2、内联函数
        inline
        ①内联函数声明时inline关键字必须和函数定义结合在一起,否则编译器会直接忽略内联请求。
        ②C++编译器直接将函数体插入在函数调用的地方。
        ③内联函数没有普通函数调用时的额外开销(压栈,跳转,返回)。
        ④内联函数是一种特殊的函数,具有普通函数的特征(参数检查,返回类型等)。
        ⑤内联函数由编译器处理,直接将编译后的函数体插入调用的地方,宏代码片段由预处理器处理,进行简单地文本替换,没有任何编译过程。
        ⑥C++中内联编译的限制:
            不能存在任何形式的循环语句
            不能存在过多的条件判断语句
            函数体不能过于庞大
            不能对函数进行取址操作
            函数内联声明必须在调用语句之前
        ⑦编译器对于内联函数的限制并不是绝对的,内联函数相对于普通函数的优势只是省去了函数调用时压栈,跳转和返回的开销。因此,当函数体的执行开销远大于压栈,跳转和返回所有的开销时,那么内联将无意义。

    inline void printAB(int a, int b)
    {
      cout << "a=" << a << "b=" << b << endl;
    }
    
    int main(void)
    {
      int a = 10;
      int b = 20;
    
      printAB(a, b);
    
      return 0;
    }

        内联函数总结:
            优点:避免调用时的额外开销(入栈与出栈操作)
            代价:由于内联函数的函数体在代码段中会出现多个“副本”,因此会增加代码段的空间。
            本质:以牺牲代码段空间为代价,提高程序运行时的效率。
            适用场景:函数体很“小”,且被“频繁”调用。

      3、函数的默认参数和占位参数

    int get_volume(int len, int width, int height=10)    //默认参数必须从右往左放,在调用传参的时候可以不写具有默认参数的实参
    {
        cout << "len =" << len <<endl;
        cout << "w = " << width <<endl;
        cout << "h = " << height <<endl;
    
        return len * width * height;
    }
    
    void func(int x, int)    //没有形参名的叫占位参数,因为没有参数名,没办法在下面的函数体中进行调用,只起到预留空间的作用,因此没有意义
    {
        cout << "x=" << x <<endl;
    }

      4、函数重载
        函数的返回值类型 函数名(函数形参列表,包括参数个数、参数类型、参数顺序)
        函数重载,函数名相同,参数列表不同,并不关心函数返回值类型
        函数返回值类型并不是构成函数重载的条件
        函数重载尽量不要写默认参数,为了避免调用时出现函数冲突。因为默认参数的出现,调用时就可以缺省那一个参数,从而导致了函数冲突。
        函数重载调用规则:
            如果有严格完全匹配的,就调用完全匹配的;
            如果没有完全匹配的,能通过隐式转换匹配的,就会调用隐式转换匹配的那个函数;
            如果都匹配不到,调用失败

    int func(int a)
    {
        cout << "a=" << a <<endl;
        return 0;
    }
    
    int func(int a, int b)
    {
        cout << "a=" << a << "b=" << b <<endl;
        return 0;
    }
    
    char func(int a, char b)
    {
        cout << "a=" << a << "b=" << b <<endl;
        return 0;
    }

      5、函数指针

    int func(int a, int b)
    {
        cout << "func" <<endl;
        return 0;
    }
    
    //1.定义一种函数类型
    typedef int(MY_FUNC)(int, int);
    
    //2.定义指向一种函数类型的指针类型
    typedef int(*MY_FUNC_P)(int, int);
    
    int main(void)
    {
        //1
        MY_FUNC *fp = NULL;
        fp = func;
        fp(10, 20);
    
        //2
        MY_FUNC_P fp1 = NULL;
        fp1 = func;
        fp1(10, 20);
    
        //3
        int(*fp3)(int, int) = NULL;
        fp3 = func;
        fp3(10, 20);
    
        return 0;
    }
  • 相关阅读:
    图像有用区域--------深搜和广搜的第一次二选一
    24Pointgame-----24点游戏
    CAP定理和BASE理论
    并查集
    七桥问题和一笔画
    组合数问题--------一种新的 搜索 思路
    最少换乘 之简化版
    吝啬的国度 ---用vector 来构图
    WGZX:javaScript 学习心得--1
    eclipse Maven -->web project
  • 原文地址:https://www.cnblogs.com/chuangming/p/8926369.html
Copyright © 2020-2023  润新知