关于理解数组与指针

二维数组

    二维数组可看成一维数组,而一维数组的数组名表示数组首元素地址,即一行的地址,二维数组的数组名即表示第一行的地址,若多二维数组的数组名+1即表示第二行第一个元素的地址

对一个三行四列的数组arr

int arr[3][4];

它的数组名即表示第一行的首元素地址,*(arr+1)表示的是第二行首元素的地址(可理解为第二行数组的数组名),*(arr+1)[2]即第二行第三个元素地址即

例1:

int main(int argc,char *argv[])
{
	int arr[3][2] = {(0,1),(2,3),(4,5)};
	int *p;
	p = arr[0];//p=&arr[0][0]
	printf("%d", p[0]);
	system("pause");
	return 0;
}

   逗号表达式将前面的表达式舍弃,执行最后一个表达式,即数组arr[3][2]被初始化为{1,3,5},输出1.

a[0]表示第一行数组首元素地址,p保存第一行首元素地址,即p=&arr[0][0]

p[0]即表示访问第一行第一个元素

例二

int main()
{
	int a[5][5];//可看为一位数组,每个元素又是大小为5的一维数组
	int(*p)[4];
	p =(int(*)[4]) a;//强制转化
	printf("%p,%d\n",
		&p[4][2] - &a[4][2],
		&p[4][2] - &a[4][2]);
	system("pause");
	return 0;
}
输出fffffffe,-4

p[4][2]即表示*(*(p+4)+2)


a[0] a[1] a[2] a[3] a[4]

p每次+1跳过4个空间,a+1跳过5个空间,地址-地址表示同一个数组两个元素之间元素个数


 例三

int main()
{
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int *ptr1 = (int *)(&aa + 1);
	//int(*p)[2][5]=&aa;
	int *ptr2 = (int *)(*(aa + 1));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	system("pause");
	return 0;
}
输出10,5

&aa+1跳过整个数组,ptr1指向数组后面的空间

aa+1即表示第二行,*(aa+1)即相当于aa[1][0]的地址,ptr2指向第二行第一个元素


二级指针

数组传参

 例1 一维数组传参

int fun(int *p)
{

}
int main()
{
    int arr[10];
    fun(arr);//即将数组的地址传进去
    //或者fun(&arr[10]);
}

例二 二维数组传参

int fun(int arr[][4])

int fun2(int *p)

int fun3(int (*p)[4])//数组指针
int main()
{
    int arr[3][4];
    fun(arr);
    fun2(&arr[0][0])
    fun3(arr)//数组名相当于数组首元素地址,而arr首元素又是一个大小为4的一维数组,即一维数             //组的地址,一维数组的地址由一维数组的指针来接收
}

ps.如果想在fun函数内部求数组的大小,需要在main中求出然后传人

例三 参数传递类型

int fun(int *p)
{
}
int fun2(int **p)//二级指针保存一级指针地址
{
}
int main()
{
    int num=0;
    int arr[10];
    int *p=#
    int*arr2[10]
    int **q=&p
   
    fun(&num);
    fun(p);
    fun(arr);
    
    fun2(&p);
    fun2(arr2);
    fun2(q);
    //fun2(&arr);error,数组的地址保存在一级指针中
    return 0;
}

数组的参数与指针的参数

数组参数 指针参数
数组的数组 char a[3][4]  数组的指针(*)[4]
指针数组   char*a[5]  指针的指针 char**

三维

char a[3][4][5]  char[*p][4][5]



你可能感兴趣的:(C语言,数组与指针)