美文网首页C语言
指针数组与数组指针

指针数组与数组指针

作者: 风情云 | 来源:发表于2020-03-11 15:49 被阅读0次

    指针数组与数组指针

    这两个名词乍一看很相似,很让人分不清什么意思?其实主要看后缀名就可以了。指针数组,后缀为数组,那他就是一个数组,只是里面的元素为指针类型。数组指针,后缀为指针,那他就是一个指针,只是他指向的是数组。明白两个本质是什么了,下面来逐一击破。

    指针数组

    定义一个数组,里面的元素是指针。因为数组里面的元素只要是同一种数据类型就可以。

        int i = 0;
        //定义字符型指针数组
        char* array[5] = {"Tom","Jake","Make","Ludix","Buke"};
        for(i=0;i<5;i++)
        {
            printf("%s\n",array[i]);
        }
    

    结果呈现

    Tom
    Jake
    Make
    Ludix
    Buke
    
    

    也可以定义其他类型指针数组

        int a[5];
        int b[4];
        int c[3];
        //定义指向int*的指针数组
        int *d[] = {a,b,c};
        //获取指针数组的值
        int temp = d[0][0];
    

    数组指针

    这是一个数组类型的指针,可同比联想int类型的指针,就基本明白什么意思。但要怎样定义一个数组指针?

        int *array;
    

    看到上面的代码应该想到要用一个类似int的东西,就是一个数据类型。可以想到用typedef来为数组起别名。
    第一种定义法 (不常用)

        typedef int[10] p;  //error
        //正确的定义
        typedef int P[10];  //true
        //定义数组后,再来看普通类型的的指针定义 int *array
        //大概明白要怎样定义指针数组了
        //p 可类比int
        p *ptr;     
    

    第二种定义法 (常用)

        //直接对指针数组其别名
        //注意别名与*要用()括起来,不然语法出错
        typedef int (*P)[10];
        P ptr;
    

    第三种定义法 (常用)

        //直接定义一个指针数组
        int (*ptr)[10];
        int array[10];
        ptr = array;
    

    数组指针用途

    当我们定义了数组,要将数组当作形参,我们也许会想到直接将定义时是怎样定义的,作为形参也就怎样定义。但是

    void test(int array[2][3])
    {
        printf("fun: sizeof(array) = %d\n",sizeof(array));
    }
    int main(void)
    {
        int array[2][3];
        printf("sizeof(array) = %d\n",sizeof(array));
        test(array);
        return 0;
    }
    

    结果呈现

    sizeof(array) = 24
    fun: sizeof(array) = 4
    
    

    可以看到当数组作为形参时,退化为一个指针,存储的是该数组的地址。因为如果是传递整个数组的话,赋值时间耗费太多,空间也会耗费,为了高效运作,就直接将数组的地址赋值。那就可以把数组指针当形参。

    void test(int (*array)[3],int row)
    {
        //计算指针步长 步长为3*4 = 12
        printf("fun: sizeof(array) = %d\n",sizeof(array));
        printf("fun: array: %u array+1: %u\n",array,array+1);
        int i=0,j=0;
        //打印数组内容
        for(i=0;i<row;i++)
        {
            for(j=0;j<3;j++)
            printf("%d ",array[i][j]);
        }
        printf("\n");
    }
    int main(void)
    {
        int array[2][3] = {1,2,3,4,5,6};
        //数组当形参为指针,不能通过计算数组得到数组元素个数,所以传行数进去
        test(array,2);
        return 0;
    }
    

    结果呈现

    fun: sizeof(array) = 4
    fun: array: 6356728 array+1: 6356740
    1 2 3 4 5 6
    

    数组指针与指针数组辨析

        //指针数组
        int *p1[10];
        //数组指针
        int (*p2)[10];
    

    可以看到两者就一个()的区别,这涉及优先级问题。
    int p1[10]; 没有(),就是int 是一起的,p1为变量名,[10]表明是数组。这就是一个数组指针
    int (
    p2)[10] ; 看到(),先读(),
    p2一起,表明这是一个指针,[10]表明是数组,这就是一个数组指针。
    方法就是判断,看到[ ],表明不是数组,就是数组指针,再判断是不是一个指针,看*与谁在一起,和数据类型一起,就是指针数组,和变量一起,就是指针数组。

    注意事项

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

    指针数组指向的是二维数组每层的首地址,但要是两者之间每层的房间个数不一样,会导致指针步长不一致,就会读取数据出错。

        int array[2][3] = {1,2,3,4,5,6};
        int (*p)[2] = array;
        //打印步长
        printf("p: %u p+1: %u\n",p,p+1);
        printf("array[0]: %u array[1]: %u\n",array[0],array[1]);
        //答应数据
        printf("p[1][2] = %d,array[1][2] = %d\n",p[1][2],array[1][2]);
    

    结果呈现

    p: 6356724 p+1: 6356732
    array[0]: 6356724 array[1]: 6356736
    p[1][2] = 5,array[1][2] = 6
    
    过程

    因为两者指针步长不一致,导致加1后指向错误的位置,就造成运行错误。要注意两者指针步长要一致。

    文章到此结束,谢谢观看。


    微信公众号

    相关文章

      网友评论

        本文标题:指针数组与数组指针

        本文链接:https://www.haomeiwen.com/subject/fowcjhtx.html