二维数组和指针

void fun(char **p)
{

}
void test0(void)
{
    char *p[10]; //指针数组 *p[10]=*(p[10]) 即数组里的所有元素皆为指针类型的,例子:表示有10个指针
    char buf[10]="1234567890";

    //p = buf 为错误语句,因为二级指针不能指向一级指针
    //每一个指针都可以指向一段连续的内存空间
    *p=buf; // p[0] = buf;
    for( int i=0;i<strlen(buf);i++ )
    {
        printf(" %c \n",*(p[0]+i));
    }
    printf("********************\n");
    for( int j=0;j<strlen(buf);j++ )
    {
        printf(" %c \n",*(*p+j));
    }
    
    // *p = p[0] 它都指代数组的元素的第一个指针,
    // p是p[10]这个数组的首地址即p=&p[0]
    // 则
    // p+1 = &p[1]
    // p+2 = &p[2]
    // p+3 = &p[3]
    // p+4 = &p[4] 
    // p的自增相当于历遍p[10]这个数组 以此类推
    // 那么*p等于取数组里面的值 即 *p=p[0],
    // 而数组里面的值它是一个指针,它类似于你直接定义了一个 char *ptr 的指针  ptr=p[0]=*p
    // 而数组的元素又指向buf
    // 要想读出 buf 里面元素的值又两种写法
    // buf[0] = *(*p)=*(p[0]) 即再对指针数组的指针再取一次值便可
    // for( int i=0;i<strlen(buf);i++ )
    // {
    //     printf(" %c \n",*(p[0]+i));
    // }
    // printf("********************\n");
    // for( int j=0;j<strlen(buf);j++ )
    // {
    //     printf(" %c \n",*(*p+j));
    // }
    // 往复循环则可以读出buf 数组里面所有的值

    // 若要将指针数组作为实参传递给函数的形参该怎么写呢
    // 其实 p作为实参经过上面分析你应该知道他是个二级指针了
    // p指向数组p[10]
    // p的偏移是在数组p[10]上偏移
    // *p是取数组的值
    // fun(p);

}
void test1(void)
{
    char *p[3]={"11111111","222222222","3333333333"};
    char **q;
    q=p;
    for(int i=0;i<(sizeof(p)/sizeof(int));i++)
    {
        printf("%s \n",*(q+i));
    }
    printf("********************\n");
    for( int i=0;i<strlen(p[0]);i++ )
    {
        printf("%c ",*(*q+i));
    }
    printf("\n");
    for(int i=0;i<(sizeof(p)/sizeof(int));i++)
    {
        printf("%s \n",p[i]);
    }
    printf("********************\n");
    for( int i=0;i<strlen(p[0]);i++ )
    {
        printf("%c ",*(p[0]+i));
    }
    printf("\n");
}

void test2(void)
{
    char array[4][3]={{1,2,3},{4,5,6},{7,8,9},{0,1,2}};
    // char **p=array; //错误的语句

    printf("行数=%d 列数=%d\n",sizeof(array)/sizeof(array[0]),sizeof(array[0]));
    printf("strlen(array[0])=%d strlen(array[1])=%d\n",strlen(array[0]),strlen(array[1]));
    for( int i=0;i<(sizeof(array)/sizeof(array[0]));i++ )
    {
        for( int j=0;j<sizeof(array[0]);j++ )
        {
            printf("%d ",array[i][j]);
        }
        printf("\n");
    }
    printf("********************\n");
    for( int i=0;i<(sizeof(array)/sizeof(array[0]));i++ )
    {
        for( int j=0;j<sizeof(array[0]);j++ )
        {
            printf("%d ",*(*(array+i)+j));
        }
        printf("\n");
    }
    printf("********************\n");
    for( int i=0;i<(sizeof(array)/sizeof(array[0]));i++ )
    {
        for( int j=0;j<sizeof(array[0]);j++ )
        {
            printf("%d ",*(array[i]+j));
        }
        printf("\n");
    }

    // 注意1: array是一个指向数组的行指针,它虽然是一个二级指针,但不等直接等效 **p=array,这是错误的表达
    // 那么二维数组 在语句和参数传递中如何等效
    // char (*p)[3]; //数组指针也叫行指针,即该指针指向一个有三个元素的一维数组
    // p = array;
    // 这里说明了二维数组等效于一个数组指针=行指针

    // 注意2: sizeof(array)=12 计算的是二维数组开辟的存储空间,且数组的类型是char 占一个字节,所以大小为12
    //         sizeof(array[0])=3 计算的二维数组每一行开辟的存储空间,数组有三个元素,char类型,所以大小为3
    //         那么可以用 strlen(array[0]) 计算每行有多少元素吗?
    //         不可以,因为二维数组的元素也是连续的存储的,这样计算的是 strlen(array[0])=12 strlen(array[1])=9

    // 注意3:
    // array   = &array[0]
    // array+1 = &array[1]
    // array+2 = &array[2]
    // array+3 = &array[3]
    // array 该指针表示指向数组的第一个行地址,它的历遍的是array[4]这个数组,这个数组全是行指针,每一个都指向一个一维数组
    // 那么它取值
    // *array = array[1] 表示获得一个列指针
    // *(*array+0)
    // *(*array+1)
    // *(*array+2)
    // 那么*array这个指针历遍的就是列指针指向的一维数组,它的在取值即 *(*array)=表示第一行第一列的值 然后依次类推
}
void fun1( char (*q)[3] )
{
    for(int i=0;i<4;i++)
    {
        for( int j=0;j<sizeof((*q));j++ ) //*q=列指针 q=行指针
        {
            printf("%d ",(*(q+i))[j]);
        }
        printf("\n");
    } 
}

void test3(void)
{
    char array[4][3]={{1,1,1},{2,2,2},{4,4,4},{5,5,5}};
    char (*p)[3]; //数组指针即p是一个指向一个一维数组的指针又称行指针,
    p=array; //array就是二维数组首地址,也是一个行指针 

    for(int i=0;i<(sizeof(array)/sizeof(array[0]));i++)
    {
        for( int j=0;j<sizeof(array[0]);j++ )
        {
            printf("%d ",(*(p+i))[j]);
        }
        printf("\n");
    }   
    printf("********************\n");
    for( int i=0;i<(sizeof(array)/sizeof(array[0]));i++ )
    {
        for( int j=0;j<sizeof(array[0]);j++ )
        {
            printf("%d ",*(*(p+i)+j));
        }
        printf("\n");
    }

    // 注意1: array是一个指向数组的行指针,它虽然是一个二级指针,但不等直接等效 **p=array,这是错误的表达
    // 那么二维数组 在语句和参数传递中如何等效
    // char (*p)[3]; //数组指针也叫行指针,即该指针指向一个有三个元素的一维数组
    // p = array;
    // 这里说明了二维数组等效于一个数组指针=行指针
    fun1(array);
}
void main(void)
{
	 test0();
    test1();
    test2();
    test3();
}

参考链接
二维数组和指针
C/C++二维数组名和二级指针
C语言数组之指针数组和数组指针
C/C++二维数组指针(指向二维数组的指针)详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值