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莫抹去,是该块内存显示为未用。





  • 相关阅读:
    51nod乘积之和
    Dell服务器安装OpenManage(OMSA)
    Nginx反向代理PHP
    搭建haproxy
    108. Convert Sorted Array to Binary Search Tree
    60. Permutation Sequence
    142. Linked List Cycle II
    129. Sum Root to Leaf Numbers
    118. Pascal's Triangle
    26. Remove Duplicates from Sorted Array
  • 原文地址:https://www.cnblogs.com/gaot/p/7709701.html
Copyright © 2011-2022 走看看