zoukankan      html  css  js  c++  java
  • 指针、引用、引用和函数参数、引用和const、const 和 #define、#define的特殊用途

    一、const

    •const可以限定一个变量的值不允许被改变,使用const在一定程度上可以提高程序的安全性和可靠性
    •const int a = 10;
    Ø变量a的值是不能被修改的,永远都是初值10
    Øint const a = 10;跟上述写法是等价的
    Ø
    •void sum(const int a, const int b)
    Ø上面的函数可以防止别人篡改形参的值
    Ø
    •可以看出,const可以用来定义一个常量。作用跟enum、#define类似
    •下面的例子表示p是个常量,不能再给p赋值,不能让p再指向其他变量

    int a = 10;

    int * const p = &a;

     
    •下面的例子表示*p是个常量,不能通过*p来修改变量a的值

    int a = 10;

    const int *p = &a;

    •下面的例子可以防止test函数的形参a指针修改外面age变量的值

    void test(const int * a);

    int age = 10;

    test(&age);

    •下面的例子表示*p和p都是常量

    int a = 10;

    const int * const p = &a;

    二、const习题

    1)下面的代码编译器会报一个错误,请问,哪一个语句是错误的呢?

    typedef char * pStr;

    char string[4] = "bbc";

    const char *p1 = string;

    const pStr p2 = string;

    p1++;

    p2++;

    2)判断下列p1、p2的变量类型 和 常量性
    Øint const * p1, p2;
    Øint const * const p1,p2;
    Øint * const p1,p2;
     

    3)判断最后2句代码是否合理

    3.1指针指向的变量的值不能变,指向可变

    int x = 1;

    int y = 2;

    const int* px = &x;

    px = &y;

    *px = 3; 

    3.2 指针指向的变量的值可以改变,指向不可变

    int x = 1;

    int y = 2;

    int* const px = &x;

    px = &y;

    *px = 3; 

    3.3指针指向的变量的值不可变,指向不可变

    int x = 1;

    int y = 2;

    const int* const px = &x;

    px = &y;

    *px = 3; 

    三、const 和 #define

    •const和#define都能用来定义常量,可以造成一改全部跟着一起改的效果
    •实际上,更推荐使用const或者enum来定义常量
    Øconst推出的初始目的,正是为了取代预编译指令,消除它的缺点,同时继承它的优点
    Øconst可以节省空间,避免不必要的内存分配。举例:

    #define PI1 3.14159 // 常量宏

    const double PI2 = 3.14159; // 此时并未将Pi放入RAM中

    double a = PI2; // 此时为PI2分配内存,以后不再分配!

    double b = PI1; // 编译期间进行宏替换,分配内存

    double c = PI2; // 没有内存分配

    double d = PI1; // 再进行宏替换,又一次分配内存!

    四、#define的副作用

    •#define有时候会产生一些不好的副作用,比如下面的例子:

    // MAX宏返回两个数值中的最大值

    #define MAX(x, y) ((x) > (y) ? (x) : (y))

    int a = 10;

    int b = 6;

    int c = MAX(++a, b);

    cout << "c = " << c << ", a = " << a << endl;

    这时候的输出结果是:c = 12, a = 12

    如果将变量b的初值改为15,也就是int b = 15;

    这时候的输出结果是:c = 15, a = 11

     五、#define的特殊用途

    •#define还是有它无可取代的地方,比如
    Ø传入一个参数,然后生成字符串

    #define TO_STR(x) #x

    cout << TO_STR(abcd) << endl;

    Ø连接多个参数,合成一个完整的标识符

    #define CONCAT(x, y) x##y

    int myage = 20;

    cout << CONCAT(my, age) << endl;

    六、引用

    •引用:其实就是给变量起一个别名
    •引用的特点:
    Ø引用没有独立的存储空间,跟被引用的变量共享存储空间
    Ø对引用所做的改变,就是对所引用变量所做的改变
     
    七、引用的定义
    •引用的定义格式:类型 &引用名称 = 变量名; 
    •比如下面的af就是变量a的一个引用

    int a = 10;

    // 引用必须在定义的时候就进行初始化

    int &af = a;

    // 引用af 和 变量a 的内存地址一致

    cout << &af << ", " << &a << endl;

    // 变量a的值被改为了20

    af = 20;

    cout << af << ", " << a << endl;

    程序的输出结果是:

    0x7fff5fbff89c, 0x7fff5fbff89c

    20, 20

    八、下面的例子表示bf、af同时引用着变量a

    int a = 10;

    int &af = a;

    int &bf = af;

    cout << &bf << ", " << &af << ", " << &a;

    打印出来的内存地址是一致的

    九、引用的使用注意

    •在定义的时候就进行初始化。下面的是错误写法:

    int &af;

    •引用一旦在定义的时候确定好引用哪个变量,以后都不能再引用其他变量

    int a = 10;

    int &af = a;

    int b = 20;

    af = b;

    最后一行代码af = b;并不代表af引用了变量b,而是将变量b的值赋值给了af引用,也就是将变量b的值给了a

    十、const 与 引用

    •称af为const引用

    int a = 10;

    const int &af = a;

    •下面的代码是不能编译通过的。因为ref引用的类型和变量d的类型不匹配

    double d = 1.78;

    int &ref = d;

    •但是将ref改为const引用,就能编译通过

    double d = 1.78;

    const int &ref = d;

    编译能通过的原因是const int &ref = d;等价于下面2句:

    int temp = d;

    const int &ref = temp;

    也就是说ref引用 跟 变量d 并不共享同一块存储空间

    十一、引用 与 函数参数

    •引用可以作为函数的形参,修改了引用形参,能影响外面实参变量的值
    •如果要在函数内部修改外面实参的值,尽量使用引用作为形参,不要使用指针作为函数形参,原因如下:
    Ø引用不占用额外的存储空间
    Ø使用引用修改实参显得更自然、易懂
     
    十二、引用 与 函数返回值
    •用也可以作为函数的返回值,主要目的是:可以将函数调用放在赋值运算符(=)的左边

    int ages[] = {20, 15, 36, 17, 28};

    int & ages_index(int i)

    {

        return ages[i];

    }

    // 相当于ages[0] = 30;

    ages_index(0) = 30; 

    十三、引用 与 函数返回值

    •注意:不能返回对局部变量的引用

    int & add(int a, int b)

    {

        int sum = a + b;

        return sum;

    }

    int n = add(10, 20);

    int &nf = add(10, 10);

    cout << "n = " << n << endl;

    cout << "nf = " << nf << endl;

    上面的程序会造成nf引用的值是不确定的,并不是20

    十四、引用 与 指针 的区别

    •引用没有独立的存储空间,指针有自己独立的存储空间
    •引用只能在定义时被初始化一次,之后不可变;而指针的值是可变的
    •引用不能为空,指针可以为空
    •“sizeof 引用”得到的是所引用变量的大小;”sizeof 指针”得到的是指针的大小
    •引用和指针的自增++自减--运算含义不一样 
     
  • 相关阅读:
    上一张作业day16
    python 函数递归,三元表达式解读,匿名一次性函数,模块略解
    迭代器,生成器与内置函数
    闭合函数和装饰器
    函数的其他关键点*与**,函数的对象可以当做变量去使用,函数的嵌套,名称空间
    python函数,应用与讲解
    文件处理方式
    html-04 html骨架
    html-03 Web标准
    html-02 浏览器内核
  • 原文地址:https://www.cnblogs.com/changxs/p/3484941.html
Copyright © 2011-2022 走看看