zoukankan      html  css  js  c++  java
  • 探讨c/c++的指针

    最近写项目时遇到个指针坑,决定记录一下。

    看下面代码,猜下运行结果

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int number1 = 1;
    int number2 = 2;
    void f(int *a) {
        a = &number2;
    }
    int main() {
        int *p = &number1;
        f(p);
        printf("%d
    ", *p);
        return 0;
    }

    运行结果是1。

    之前用指针有一个误区,指针只是指向某个类型的地址,指针本身也是一个类型,所以当参数传入时,已经不是同一个指针了。可以尝试输出a和p的地址,会发现是不一样的。

    (PS:这坑在java上更明显,因为java对象引用实质和指针一样,所以改变参数的指向不是一个好方法)

    对于上面的代码,可以做如下改进:

    方案一:进行内存赋值操作

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int number1 = 1;
    int number2 = 2;
    void f(int *a) {
        *a = number2;
    }
    int main() {
        int *p = &number1;
        f(p);
        printf("%d
    ", *p);
        return 0;
    }

    方案二:传入指针的地址进行操作

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int number1 = 1;
    int number2 = 2;
    void f(int **a) {
        *a = &number2;
    }
    int main() {
        int *p = &number1;
        f(&p);
        printf("%d
    ", *p);
        return 0;
    }

    这里顺便探讨下指针可以有多少级,其实理论上指针可以无限级。这样可能有个疑惑,那我指针的指针的指针……编译器是如何定义的呢,定义一个指针时如果有那么多地址他又是如何分配内存?我们尝试输出一下。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main() {
        int number = 0;
        printf("%p %p
    ", &number, &(&number));
        return 0;
    }

    发现编译错误,提示error: lvalue required as unary '&' operand。我们换一种写法。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main() {
        int number = 0;
        int *p = &number;
        printf("%p %p
    ", p, &(p));
        return 0;
    }

    好,这样是可以成功编译的。我们再试一下,再开一个指针。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int main() {
        int number = 0;
        int *p = &number;
        int **pp = &p;
        //编译错误
        //printf("%p %p %p
    ", p, &(p), &(&p));
        
        //编译成功
        printf("%p %p %p
    ", p, &(p), &(pp));
        return 0;
    }

    好,得出结论。编译器本身不会管你有多少级指针,这都是你自己分配的,至于能分配多少个取决于内存大小。编译器只负责定义类型,在某个地址的内存存下你的数据。至于指针,则是另一种数据类型,而他存的值就是他所指向的地址。

  • 相关阅读:
    进程调度算法
    附近的人,附近的卖家(geohash+前缀树)
    海量信息库,查找是否存在(bloom filter布隆过滤器)
    继承、虚继承和虚函数表对类的大小的影响
    linux 用户空间与内核空间——高端内存详解
    0-1背包问题入门
    范式
    vue的无缝滚动插件vue-seamless-scroll的安装与使用
    在vue项目中使用swiper2.7.6
    vue项目在IE下报 [vuex] vuex requires a Promise polyfill in this browser问题
  • 原文地址:https://www.cnblogs.com/scaugsh/p/9454245.html
Copyright © 2011-2022 走看看