zoukankan      html  css  js  c++  java
  • C++基础总结(4)-----指针

    指针是一个变量,其存储的值是地址,而不是值本身。(有点类似于组成原理里面的变址寻址)

    在讨论指针之前,我们先来看看如何寻找常规变量的地址。只需对变量引用取地址符(&)就行了。

    如下面一段代码:

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int dounts=6;
        double cpus=5.6;
    
        cout<<"dounts = "<<dounts<<", address is "<<&dounts<<endl;
        cout<<"cpus = "<<cpus<<", address is "<<&cpus<<endl;
        return 0;
    }
    

    *运算符被称为间接值或者解除引用运算符。将其用于指针,便可以得到该地址存储的值。


    duck变量为int型变量,其分配的地址是1000,里面存储的值是12,而birding是一个int型指针变量它本身的地址是1006,而在它里面存储的值duck的地址1000。

    所谓指针指的是存储的其他变量的地址。


    指针的声明和初始化

    int *ptr;//声明一个int型指针

    *两边的空格是可选的。

    传统上,C程序员使用这种格式。

    int *ptr;//强调*ptr是一个int类型

    C++程序员通常使用下面这种方式

    int* ptr;

    强调int*之一中指向int类型的指针。在哪里添加空格对于编译器没有区别。

    注意:

    int *p1, p2;表示的是创建一个int类型指针p1和一个变量p2。如果要声明两个变量,应该这样做:int *p1, *p2。


    指针的初始化

    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int a=3;
        int *b;
        b=&a;
    
        cout<<"a = "<<a<<" at "<<&a<<endl;//&a表示a的地址
        cout<<"*b = "<<*b<<endl;//<span style="font-family: Arial, Helvetica, sans-serif;">*b 表示b里面存储的地址所指向的位置存储的值,即a的值</span>
        cout<<"the value of b is "<< b<<" at "<<&b<<endl;//b表示的是b里面存储的值,即a的地址
        return 0;
    }
    



    从运行结果可以证明上面的图的正确性。

    注意:C++在创建指针的时候,计算机将会分配用来存储地址的内存,但不会分配用来存储指针所指向的数据的内存。

    如下所示:

             int *a;

             *a=2333;

    上面这段代码并没有为2333分配内存,而是将其随机存放在一个位置,有可能是空闲位置,有可能是一个已经存放了数据的位置从而造成数据损坏。


    使用new申请内存

      int * pn=new int;

    new int 告诉计算机程序要申请一块int类型的内存,new运算符根据类型判断需要多少字节的内存。找到内存之后将地址传回pn。

    还可以使用变量直接赋值。

      int higgens;

      int * pt=&higgens;

    申请数组

    以申请int类型的数组为例:

      int * psome=new int[20];//执行这句的时候,计算机会申请10个int型的连续存储内存,并将首地址返回。


    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        int nights = 1001;
        int * pt = new int; //C-style
        *pt = 1001;
    
        cout << nights << ",location " << &nights << endl;
        cout << "int value " << (*pt) << "location " << pt << endl;
    
        double * pd=new double;
        *pd = 10001;
    
        cout << "value = " << *pd << " location " << pd << endl; //show the location of pd;
        cout << "location of pointer pd " << &pd << endl;
        cout << "size of pt " << sizeof(pt) << endl;//显示申请的地址的大小
        cout << "sizeof *pt " << sizeof(*pt) << endl;//显示存储的地址里面的值的大小
        cout << "size of pd " << sizeof(pd) << endl;
        cout << "size of *pd " << sizeof(*pd) << endl;
    
        /*
        不初始化的话pp里面存的就是未知地址,可能会造成数据损坏、
        */
        double *pp;
        cout<<"pp at "<<&pp<<endl;
    
     //   *pp=3;  //错误的用法
      //  cout<<pp<<endl;
    
        pp=new double();
        cout<<"*pp at "<<pp<<endl;
        return 0;
    }
    



    一半常规变量申请的内存是在栈中的,随着函数的生命周期的结束会自动被回收。但是new申请的内存在堆(heap)或自由存储区中,用完之后必须被回收。不然会造成内存的泄露。所以这里我们需要使用delete来回收new申请的内存。

    delete的用法

    int *ps=new int;
    delete ps;
    int jugs=5;
    int *pi=&jugs;
    delete pi;//wrong
    delete只能用来回收new申请的动态内存,所以第二种用法无效。

    删除数组的用法和上面的类似

    int *a=new int[10];
    delete []a;


    使用new和delete的规则

    1.delete只能用来释放new分配的内存

    2.不要使用delete对同一个内存释放两次

    3.new和delete应该成对出现。

    4.对空指针使用delete是安全的。


    delete删除的是new申请的内存里面的值,而不是指针本身。

    #include<iostream>
    
    using namespace std;
    
    int main()
    {
        int a=3;
        int *b=&a;
        int *c=new int();
        int *d=c;
    
        *c=123;
        cout<<"a = "<<a<<", the address of a is "<<&a<<endl;
        cout<<*b<<" at "<<b<<",the address of b is "<<&b<<endl;
        cout<<"*c = "<<*c<<",the address stored in c is "<<c<<" and the address of c is "<<&c<<endl;
        cout<<"*d = "<<*d<<",and the address stored in d is "<<d<<",the address of d is "<<&d<<endl;
        delete c;//回收内存
        //delete d; 加上之后影响不大
        cout<<*c<<",the address in c is "<<c<<",and c's address is "<<&c<<endl;
         cout<<*d<<",the address in c is "<<d<<",and c's address is "<<&d<<endl;
        return 0;
    }



    从上面的例子可以看出指针c和d是两个不同的指针,但是他们指向的同一块内存。delete删除的只是申请的内存里面的值,而对指针本身的地址以及指针存储的地址并没有影响。系统会为a,b,c,d都分配一个地址,但是b存储的是a的地址,c,d存储的是123在堆里面的地址。delete也就是将123莫抹去,是该块内存显示为未用。





  • 相关阅读:
    zoj2132-The Most Frequent Number
    ant-design getFieldDecorator 无法获取自定义组件的值
    ant-design-pro Login 组件 实现 rules 验证
    js 终止 forEach 循环
    js 终止 for 循环
    vue打包后出现一些map文件的解决方法
    ant font 本地化
    react 设置代理(proxy) 实现跨域请求
    ES6 async 与 await 实战
    {...formItemLayout} 标签布局
  • 原文地址:https://www.cnblogs.com/gaot/p/7709701.html
Copyright © 2011-2022 走看看