C语言

指针数组与数组指针

2020-03-11  本文已影响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后指向错误的位置,就造成运行错误。要注意两者指针步长要一致。

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


微信公众号
上一篇下一篇

猜你喜欢

热点阅读