• 指针总结


    1.指针的地址和指针上储存的地址。

    指针是储存地址的变量,而指针自身也有自己的地址。

    #include <iostream>
    using namespace std;
    
    int main()
    {
    	int *p, a;
    	p = &a; //将a的地址赋值给p,此时p储存a的地址
    	cout << "指针p的地址:" << &p << endl;
    	cout << "指针p储存的地址:" << p << endl;
    	cout << "a的地址:" << &a << endl;
    	return 0;
    }

    运行结果:

    指针p的地址:0012FF44
    指针p储存的地址:0012FF40
    a的地址:0012FF40


    2.给指针动态分配/回收内存:

    通过new可以给指针p动态分配一片内存空间,此时p储存的地址就是该片内存空间的首地址。通过delete可以回收该空间。这些是简单的问题,值得注意的是,通过new给指针p动态分配一片内存空间会修改p的值(p的值即p储存的地址)。

    #include <iostream>
    using namespace std;
    
    int main()
    {
    	int *p1, a;
    	p1 = &a; //将a的地址赋值给p,此时p储存a的地址
    	cout << "p1储存的地址:" << p1 << endl;
    	p1 = new int;
    	cout << "p1储存的地址:" << p1 << endl;
    	return 0;
    }

    运行结果:

    p1储存的地址:0012FF40
    p1储存的地址:00320708

    所以在编程时要留意,当为指针p动态分配一片内存空间时,p原来所储存的值会丢失!比如上面例程中如果还利用p去获得a的值就会出错!

     

    3.程序:

    #include <iostream>
    using namespace std;
    
    struct A
    {
    	int x;
    	A *link;
    };
    
    int main()
    {
    	struct A *a = new A, *b = new A;  //分别记a,b分配得的内存空间为ma,mb
    	cout << "原地址:" << endl;
    	cout << "a:" << a << " " << &(a ->x) << " " << a ->link << endl;
    	cout << "b:" << b << " " << &(b ->x) << " " << b ->link << endl;
    	a = b;  //此时a和b储存的地址一样,都是mb的首地址
    			//而a原来储存的地址丢失,也就是说a不再指向ma这片内存空间,而指向mb
    	cout << "更新后地址对比:" << endl;
    	cout << "a:" << a << " " << &(a ->x) << " " << a ->link << endl;
    	cout << "b:" << b << " " << &(b ->x) << " " << b ->link << endl;
    	return 0;
    }


    运行结果:

    原地址:
    a:003606D0 003606D0 CDCDCDCD
    b:00360708 00360708 CDCDCDCD
    更新后地址对比:
    a:00360708 00360708 CDCDCDCD
    b:00360708 00360708 CDCDCDCD

    可以看到,b的地址始终没有变,但a变了。而且观察还可以发现,其实a、b储存的地址(亦即ma,mb的首地址)就是各自的x的地址。

     

    4.当使用new为指针p申请一片内存空间时,可以同时初始化这片内存区域。典型的方式如下:

    #include <iostream>
    using namespace std;
    
    int main()
    {
        int *i;
        char *c;
        bool *b;
        i = new int(1);
        c = new char('#');
        b = new bool(0);
        cout << *i << " " << *c << " " << *b << endl;
        return 0;
    }
    

    运行结果:

    1 # 0

    这种方式对于int,char等基本数据类型是可以直接使用的,但如果指针类型是结构体类型,就要使用拷贝构造函数。


    5.动态分配内存时指针本身所占空间不变

    #include <iostream>
    using namespace std;
    
    int main()
    {
        int *p;
        cout << sizeof(p) << endl;
        p = new int[100];  //开辟一段可以存放一维整型数组(大小为100)的内存空间并返回其首地址
        cout << sizeof(p) << endl;
        return 0;
    }
    运行结果:

    4

    4

    p = new int[100]这一步操作只是让p指向一片大小为100*sizeof(int)的内存空间,就是说让指针p储存这一段空间的首地址,而p本身所占用的空间大小是不会变的。


    6.对于指针p1和p2,给p1动态分配一段内存空间,再令p2 = p1,那么p2和p1指向同一片内存空间,相当于给p2也动态分配一片内存空间。

    #include <iostream>
    using namespace std;
    
    struct Pos
    {
        int x;
        Pos(){x = 3;}
    };
    
    int main()
    {
        Pos *p1, *p2;
        p1 = new Pos;
        cout << "初状态:" << endl;
        cout << "p1储存的地址:" << p1 << endl;
        cout << "p2储存的地址:" << p2 << endl;
        cout << "p2->x = " << p2->x << endl;
        p2 = p1;
        cout << endl << "赋值后:" << endl;
        cout << "p1储存的地址:" << p1 << endl;
        cout << "p2储存的地址:" << p2 << endl;
        cout << "p2->x = " << p2->x << endl;
        return 0;
    }
    

    输出:

    初状态:
    p1储存的地址:0x3e3e58
    p2储存的地址:0x4134e6
    p2->x = 1527825539


    赋值后:
    p1储存的地址:0x3e3e58
    p2储存的地址:0x3e3e58
    p2->x = 3



  • 相关阅读:
    Regular进阶: 几点性能优化的建议
    总结常见的违背Rest原则的接口设计做法
    如何进行用户访谈更容易获得全面而有效的信息
    关于以太坊智能合约在项目实战过程中的设计及经验总结(2)
    关于以太坊智能合约在项目实战过程中的设计及经验总结(1)
    字节码执行方式--解释执行和JIT
    Redis数据库结构与读写原理
    移动端工程架构与后端工程架构的思想摩擦之旅(2)
    类文件结构与javap的使用
    JVM垃圾收集器(1)
  • 原文地址:https://www.cnblogs.com/cszlg/p/2910455.html
Copyright © 2020-2023  润新知