(一)前文问题答案解析
1、代码 int(*pa[10])[5] 的解析
某人:嗯,有*pa,这不很明显是个指针嘛,然后 [5] 说明是个数组指针,int类型,[10]。。。。
这这这,很明显不是指针。
首先:pa和[10]结合说明是个数组!!! 然后去掉数组名剩余 int(* )[5] 这不就是个数组指针的外层吗?所以真相就是类型为数组指针类型的数组
能放十个数组指针,每一个指针又指向一个数组,指向的数组有五个元素
2、二维数组的打印,代码如下
#include<stdio.h>
void print1(int arr[3][4], int x, int y)//形参接收时采用数组的形式
{
int i, j = 0;
for (i = 0;i < x;i++)
{
for (j = 0;j < y;j++)
{
printf("% d", arr[i][j]);
}
printf("\n");
}
}
void print2(int(*parr)[4], int x, int y)//使用数组指针接收
//这是因为二维数组的数组名也是首元素地址,但是其首元素的地址相当于一个有着四个元素的一维数组的地址,所以形参
//必须是数组指针
{
int i, j = 0;
for (i = 0;i < x;i++)
{
for (j = 0;j < y;j++)
{
printf("% d", (*(*parr+i)+j));//*parr+i就是找到第i行,然后加j找到第j列,
//最后*解引用得出第ihang,j列的数值
}
printf("\n");
}
}
int main()
{
int arr[3][4] = { {1,2,3,4},{2,3,4,5},{3,4,5,6} };//首先定义一个二维数组
print1(arr, 3, 4);//使用常规方法来打印
print2(arr, 3, 4);//使用指针
return 0;
}
(二)数组参数
(1)一维数组传参
int main()
{
int arr1[10] = { 0 }; //定义一个数组
int* arr2[20] = { 0 };//定义一个指针类型数组
test1(arr1);//函数test1,实参为arr1
test2(arr2);//函数test2,实参为arr2
return 0;
}思考:那么该如何写这两个函数呢?(无需具体内容,写出形参)
第一种:
void test1(int arr[]) //使用数组当形参,可以不写数组的大小
{
//具体内容;
}
第二种:void test1(int arr[10]) //使用数组当形参,可以写大小
{
//具体内容 ;
}第三种:
void test1(int* arr) //使用指针当形参,指向的是数组首元素的地址
{//具体内容 ;
}
//以上三种传参方式都是可以的第一种:
void test2(int* arr2[])//使用数组当形参,可以写数组大小,也可以不写
{
;
}第二种:
void test2(int** arr)//使用指针,此处为二级指针
{
;
}
(2)二维数组传参
第一种:
void test(int arr[3][5])// 使用数组当形参,只可以省略行不可以省略列,所以三可以省略
{
;
}
void test3(int(*arr)[5])//使用指针当形参,由于二维数组首元素是第一行的地址,其代表的也就是第一行数组的地址
// 所以形参指针需要写为指针数组的形式
{
;
}int main()
{
int arr[3][5] = { 0 };
test3(arr);
return 0;
}
(三)指针传参
void test(int* p)// 一级指针传参使用一级指针来接收
{
;
}
void test2(int** p2)// 二级指针使用二级指针来接收
{
*p2; //取得的就是pa的地址**p2;//取得的就是a的地址
}
int main()
{
int arr[10] = { 0 };
int* p = arr;//定义一个指针指向数组
test(p);
//上述为一级指针传参
int a = 10;
int* pa = &a;//指针指向a的地址int** ppa = &pa;//指针ppa指向pa的地址,所以ppa就是二级指针
test2(ppa);//也可以写为 test2(&pa)
int* arr[10] = { 0 };//定义一个指针数组,每个元素为一个一级指针
test2(arr);// 传参的时候传的就是首元素地址,也就相当于一级指针的地址,需要二级指针来接收
return 0;
}
指针传参简单的来说就是地址的接收,传过去的一级指针就用一级指针来接收