• 关于C++中的指针、数组


    C++中指针和数组基本等价的原因在于指针算术和C++内部处理数组的方式;将整数变量加一后,其值将增加1;将指针变量加一后,增加的量等于其指向的数据类型的字节数;

    指针中存储的是地址,地址在形式上和整数相似,但是意义完全不同,整数可以加减乘除,但地址相乘等操作完全没有意义;

    Eg:  int *p;

         P = 0xB8000000;

    上面会报类型不匹配的错误,原因在于C++不知道这是一个数字还是一个地址,所以需要先进行强制类型转换

    我们常说数组名就是指针,但这么说只是为了理解,准确的说,两者还是有区别的,由于我有的地方还没有完全弄清楚,所以这里只是说说自己的看法:

    数组名始终存储的是数组中第一个元素的地址,不管多少维它的类型不是指针类型,你可以认为它就是一块内存,里面存储的是地址

    (1)一维的情况:

    int *a;
    int b = 3;
    int c[3] = {1 , 2 , 3};
    
    a = &b;
    a = c;

    上面这么写都是没有问题的,都是给a传入地址;但对于二维的情况就要注意了:

    (2)二维的情况(二维数组在内存中也是按照一维的形式进行存储,存储结构为顺序存储):

    第一种写法:

    int a[2][3] = {1 , 2 , 3 , 4 , 5 , 6};
    int **p;
    p = a; 

    上面这种写法就是错误的,错误原因是我们这里想当然的认为二维数组名a就是二级指针类型,然而这么做要么会报”非法内存的错误“,要么会报”类型不匹配“的错误,我们来分析一下:

    a中存的地址是a[0][0]元素的地址,而p是一个二级指针,现在将a中存放的地址值赋给p,则p指向a[0][0]元素(即1),则*p的值就是1。则**P的值就是”地址为1“的那块内存中存放的值;这么做就会出现两种错误:

    (1)如果这个地址1是计算机内部分配给系统使用的,用户没有权限,则会报”非法内存“的错误;

    (2)如果这块内存用户可以使用,但是注意我在上面的”地址为1“这里打了双引号,就是说明这个”1“是int类型(或者是数组元素类型),我们之前也提过地址和整数类型只是形式相似然而意义完全不同,所以这里C++认为这个”1“是intl欸型而不是地址类型,所以就会报”类型不匹配“的错误;

    综上:二维情况下,我们不能认为数组名就是二级指针;

    后来,在网上看到一种说法,就是二维数组名的类型可以认为其实就是数组指针类型,操作时也没有问题,我觉得可以这么做,也可以推广到多维数组的情况:

    int a[2][3] = {1 , 2 , 3 , 4 , 5 , 6};
    int (*p)[3] = a;

    上面这么做就没有问题,这里,p是一个数组指针类型,它指向的是一个数组,数组类型为Int,数组个数为3,起始就是二维数组第二维的元素个数(对于p,初始化的时候第一维要省略);

    *(*(p + 1) + 2)的值就是a[1][2]的值,其他类似;

    (3)上面可以用p这个一级指针来指向new创建的二维数组,实际操作时我们也可以使用一个二级指针来指向这个二维数组(更加实用),如下:

    void test_pointer(int rows , int cols)
    {
        int **p = new int *[rows];
        for(int i = 0 ; i < rows ; i ++)
        {
            p[i] = new int[cols];
        }
       //这样就使用一个二级指针p指向这个二维数组,下面一般要进行一下初始化 
    //初始化之后,我们可以使用类似p[i][j]的形式指向二维数组中的元素了。
    }

    对于多维的情况应该也是类似,等以后如果遇到了不同点我再补充~

    补充:(1)前面我们说过数组名的类型其实不能算是指针类型,但是在VS环境中,由于工程实现的需要:对于一维数组,可以直接用int *来代替(其实就是把它当成了指针类型)对于二维数组,VS将数组名当成了数组指针类型,当我们进行传递时,我们不能直接用int *进行传递,那样会报类型不匹配的错误,需要我们提前使用(int *)进行强制转换再进行传递;

  • 相关阅读:
    Cannot run program "/home/mohemi/Program/adt-bundle-linux-x86_64-20130729/sdk//tools/emulator": error=2, 没有那个文件或目录
    在Ubuntu里部署Javaweb环境脑残版
    ios 内存管理 心得
    关于Servlet的PrintWriter 中文乱码问题
    流的对拷
    什么是javaBean
    ios 页面传值4种方式(四) 之通过delegate(代理)
    ios 页面传值4种方式(一) 之全局变量
    Block
    UIView动画学习笔记
  • 原文地址:https://www.cnblogs.com/zf-blog/p/7894733.html
Copyright © 2020-2023  润新知