C/C++之指针(中)

C/C++之指针(中)

接上节。C/C++之指针(上)

文章目录

  • C/C++之指针(中)
    • 6、指针常量
    • 7、二级指针
    • 8、二级指针的用途
    • 9、多级指针
    • 10、数组与指针的关系

6、指针常量

之前详细讲了常量的特点。C++两种类型的常量

  • 指针常量:(都在下面的代码中,需要仔细研究)

    #include   
    
    using namespace std;
    
    int main() {
           
        int a[6] = {
            21, 12, 66, 44, 25, 100 };
    
        //第一种,普通指针,可以随便修改。
        int* p1 = &a[0];
        *p1 = 22;
        printf("a[0] = %d\n", a[0]);
    
        //第二种,能修改指向的对象,不能修改对象的值。
        const int* p2 = &a[1];//或者int const* p2 = &a[1];
        //试图修改a[1]的值,*p2 = 0;会报错,表达式左边必须是可以修改的左值
    
        //改变指向的对象
        p2 = &a[2];
        printf("a[2] = %d\n", *p2);
    
        //第三种,无法修改指向的对象,可以修改对象的值
        int* const p3 = &a[3];
        //试图修改对象p3 = &a[4];报错,表达式左边必须是可以修改的左值
        *p3 = 99;
        printf("a[4] = %d\n", a[3]);
    
        //第四种,既不能修改指向的对象,也不能修改对象的值
        const int* const p4 = &a[5];//无法修改!!
        printf("a[5] = %d", *p4);
    
        return 0;
    }
    

    输出结果:

    a[0] = 22
    a[2] = 66
    a[4] = 99
    a[5] = 100
    

    上面讲了这么多很容易把人搞糊涂。
    总结:看const离谁近,如果constint近就是修饰的int, 如果离变量名近,那是修饰的变量

7、二级指针

  • 顾名思义,二级指针代表它有两个等级实际上它是指向指针的指针。也就是说,它存的是它指向的指针的地址
    例子:

    #include   
    
    using namespace std;
    
    int main() {
           
        int x = 100;
    
        int* p1 = &x;
        int** p2 = &p1;
    
        //二级指针的地址
        printf("二级指针p2的地址为:0x%p\n\n", &p2);
    
        //二级指针指向的指针的地址
        printf("二级指针p2的值为:0x%p\n", p2);
        printf("一级指针p1的地址为:0x%p\n\n", &p1);
    
        //二级指针指向的指针指向的地址
        printf("二级指针p2(间接引用一次)的值为:0x%p\n", *p2);
        printf("一级指针p1的指向的地址为:0x%p\n\n", p1);
    
        //通过一级指针访问x的值
        printf("通过一级指针p1访问(间接引用一次)到x的值为:%d\n", *p1);
        printf("通过二级指针p2访问(间接引用两次)到x的值为:%d\n", **p2);
    
        return 0;
    }
    

    输出结果:

    二级指针p2的地址为:0x005FFDB0
    
    二级指针p2的值为:0x005FFDBC
    一级指针p1的地址为:0x005FFDBC
    
    二级指针p2(间接引用一次)的值为:0x005FFDC8
    一级指针p1的指向的地址为:0x005FFDC8
    
    通过一级指针p1访问(间接引用一次)到x的值为:100
    通过二级指针p2访问(间接引用两次)到x的值为:100
    
    

    分析,和一级指针一样,它本身也有地址,也能指向变量(此处的变量为指针)。
    图表示为:
    C/C++之指针(中)_第1张图片

8、二级指针的用途

  • 引入:一级指针可以将变量带入函数内部,但是不能把函数内部的变量带到外部来。

    #include   
    
    using namespace std;
    
    void test(int* p, int* x) {
           
        int y = 99;
    
        //获取y的地址,在外部访问地址中的变量。
        p = &y;
        //将x传递进入函数
        *x = *x + y;
    
    }
    
    int main() {
           
        int x = 101;
        int* p = NULL;
    
        test(p, &x);
    
        //输出*p的地址
        printf("变量*p的地址为:0x%p\n", p);
    
        //输出x的值:
        printf("x = %d\n", x);
    
        return 0;
    }
    

    结果:y无法传递出来,而x传递进去了。无法访问0x00000000的地址,也就是NULL。所以这样带不出来y的值,具体原因和普通变量传递进入函数一个道理,因为p的值不会变,依旧是NULL。

    变量*p的地址为:0x00000000
    x = 200
    
  • 用二级指针试试:

    #include   
    
    using namespace std;
    
    void test(int** p) {
           
        int y = 99;
    
        //获取y的地址,在外部访问地址中的变量。
        printf("y的地址为:0x%p\n", &y);
        *p = &y;
    }
    
    int main() {
           
        int* p = NULL;
    
        test(&p);
    
        //输出*p的地址
        printf("变量*p的地址为:0x%p\n", &p);
        printf("变量*p的指向对象的地址为:0x%p\n", p);
        printf("变量*p的指向对象的值为:%d\n", *p);
    
        return 0;
    }
    

    输出结果:

    y的地址为:0x0099FB80
    变量*p的地址为:0x0099FC68
    变量*p的指向对象的地址为:0x0099FB80
    变量*p的指向对象的值为:36
    

    大家发现没,y的地址成果的被带出来了,但是结果却不是99,那这是为什么呢。
    由于y在函数结束后就销毁了,所以它对应地址上面的值就不知道是哪个变量的了,随时可能会被别的东西修改。
    解决方案, 在函数中int y = 99的前面加上static这样static int y = 99;这样由于静态变量的生命周期是全局的,这样就能得到正确结果了。
    输出结果:

    y的地址为:0x00AC400C
    变量*p的地址为:0x001FFB88
    变量*p的指向对象的地址为:0x00AC400C
    变量*p的指向对象的值为:99
    

9、多级指针

指针也可以有多级,就和数组一样,但是具体的含义没有改变。三级指针很难见到,不怎么使用,它指向的是一个二级指针。以此类推。

不建议使用二级以上的指针。

10、数组与指针的关系

  • 数组有两种表示方式,一种是指针形式,一种是下标形式

    #include   
    
    using namespace std;
    
    //两种打印方式
    void printA(int a[], int len) {
           
        for (int i = 0; i < len; i++) {
           
            printf("%d ", a[i]); //a[i]可以替换为*(a + i);
        }
        printf("\n");
    }
    
    void printB(int* a, int len) {
           
        for (int i = 0; i < len; i++) {
           
            printf("%d ", *(a + i)); //*(a + i)可替换为a[i];
        }
        printf("\n");
    }
    
    int main() {
           
        int a[12] = {
            1, 9, 2, 8, 3, 7, 4, 6, 5, 0, 11, 99 };
        
        printA(a, 12);
        printB(a, 12);
       
        return 0;
    }
    

    输出结果:

    1 9 2 8 3 7 4 6 5 0 11 99
    1 9 2 8 3 7 4 6 5 0 11 99
    

    两种方式都一样,只是写法不一样。因为数组的传递,本身就是一个地址
    本节到这里,下节继续。

你可能感兴趣的:(C++,指针,c++)