go语言-数组指针

1.数组指针
    (1)数组指针与指针数组
        这俩概念原本在c语言中就是一个绕口令般的存在,尽管从类型角度来看两者并没什么相似的地方。
        但是在go语言中对这两个类型的设定做出了一些不同的规定。首先交代一下基本概念:
            数组指针:指的是一个指针,只不过这个指针指向了一个数组
                eg:
                    var arr [5]int = [5]int{1,2,3,4,5};
                    var p *[5]int = &arr;
                    fmt.Println(p);//0xc00006a030
                    //此时p称为是数组arr的指针
                    //此时如果通过p访问数组元素是 (*p)[2],结果是3
            指针数组:指的是一个数组,这个数组里面装满了指针。
                eg:
                    var arr1 [5]int = [5]int{1,2,3,4,5};
                    var arr2 [5]int = [5]int{6,7,8,9,0};
                    var p1 *[5]int = &arr1;
                    var p2 *[5]int = &arr2;
                    var pArr [2]*[5]int = [2]*[5]int{p1,p2};
                    fmt.Println(pArr);//[0xc00006a030, 0xc00006a060]
                    //此时pArr称为是指针数组
                    //此时如果通过pArr访问数组元素是 (*pArr[0])[2],结果是3
    (2)地址相同、类型不同问题
        在go语言中,内存地址相同并不意味着其表示的数据或者数据类型就完全相同。
        eg:
            var arr [5]int = [5]int{1,2,3,4,5};
            p1,p2 := &arr,&arr[0];
            fmt.Println(p1);        //&[1,2,3,4,5] 整个数组的内存地址
            fmt.Println(p2);        //0xc0000180c0 数组第一个元素的内存地址
            fmt.Printf("%T",p1);    //*[5]int    数组指针
            fmt.Printf("%T",p2);    //*int        指针
    (3)*号可以不写问题
        在go语言中通过指针去访问指针所对应的地址处的值时,*允许不写。
        而这个规定又会催生一个由于go运算符优先级问题而催生的指针访问问题。
        eg:
            var arr [5]int = [5]int{1,2,3,4,5};
            p := &arr;
            fmt.Println(*p[0]);
        乍一看这段代码并无任何问题。
            因为p是数组指针,*p就是数组本身,而*p[0]自然就是数组的第一个元素
        但是事与愿违,代码的运行结果是一个错误!
            这是因为在go语言中*寻址运算符和[]中括号运算符的优先级是不同的!
                []中括号是初等运算符
                *寻址运算符是单目运算符
            初等运算符的优先级是大于单目运算符的,因此先参与计算的是p[0];
                p[0]其实就是数组的第一个元素,就是数字1
            数字1必然是int类型,而不是一个地址,因此针对数字1使用*寻址运算符自然也就发生了错误。
        解决问题的办法很简单,就是添加一个小括号就可以了。
            即:
                (*p)[0]
        不过因为*在go语言中,建立了 p:=&arr 这种类似地址关系后,*允许不写。
        所以,访问时候可以直接携程p[0]。事实上在工作开发过程中,这种写法反而更加常见。
        ps:
            仅对访问下标时,*寻址运算符允许不写!
 

展开阅读全文

没有更多推荐了,返回首页