指针和数组的关系

1.区别a,*a,&a,&a[0]

在一维中
(1)a=p, 将a转化为p去看,a+1,就是指针动一步,指向下一元素
(2)*a相当于计算问题 =>
*(a+0)=>
*(p+0)=>a[ 0 ]为值
(3)&a代表整个数组。&a+1=>跨越整个数组
(4)&a[0]=>首元素的地址

在二维中
(1)之前a是一维是第一个元素,这里升级a是一行,a+1=>到第二行
(2)*a相当于=>
*(a+0)=>a[0],代表第一行,*a+i或者直接a[0]+i第一行第i个元素的地址
(3)&a=>跨越整个二维数组
(4)&a[0]在一维是第一个元素,这里也升级为第一行
在这里插入图片描述

2.二级指针

指针变量是用于存放地址的变量,但是指针变量也是变量,是变量就有地址,那么存放指针变量的地址的变量是什么呢?
存放普通变量的地址的指针叫一级指针,存放一级指针变量的地址的指针叫二级指针。

#include<stdio.h>
int main()
{
	int a = 10;
	int* p1 = &a;//一级指针
	int** p2 = &p1;//二级指针
	return 0;
}

a的值有两种表达:
第一种:对一级指针p1进行一次解引用操作即可得到a的值,即*p1。
第二种:对二级指针p2进行一次解引用操作即可得到p1的值,而p1的值就是a的地址,所以再对p2进行一次解引用操作即可得到a的值,也就是对二级指针p2进行两次解引用操作即可得到a的值,即**p2。

3.二级指针和指针数组

在这里插入图片描述
什么是指针数组?例如

int arr1[4];//数组arr1包含4个元素,每个元素的类型是整型;
char arr2[5];//数组arr2包含5个元素,每个元素的类型是字符型。

在这里插入图片描述

那么指针数组也是数组,只不过是用于存放指针的数组,例如

int* arr3[5];//数组arr3包含5个元素,每个元素是一个一级整型指针。

在这里插入图片描述
再例如:

char* arr4[10];//数组arr4包含10个元素,每个元素是一个一级字符型指针。
char** arr5[5];//数组arr5包含5个元素,每个元素是一个二级字符型指针。

二级指针和指针数组的关系:
在这里插入图片描述
指针数组里面存放的数据是int *型(地址),因此对a,b,c要取地址&。而
*(arr[ i ])=>
**parr => 值

在这里插入图片描述
这里本来也是&a,&b,&c,但由于他们三个是数组,指针不就是指向数组首元素的地址。
在这里插入图片描述
arr[ i ] 是数组,存的是int*,那么*(arr[ i ] + j)=>*(*parr+i)+j) => 值

4.数组指针

什么是数组指针:整型指针是指向整型的指针,字符指针是指向字符的指针,那么数组指针应该就是指向数组的指针了。
在这里插入图片描述

#include<stdio.h>
int main()
{
	int arr[10] = { 1,2,3,4 };
	int(*p)[10] = &arr;//&arr -取出数组的地址
	//arr是数组名,是首元素的地址;p是数组指针,存放数组的地址
	return 0;
}

在这里插入图片描述
&arr就是整个数组,4*10=40字节,(1101 0010 0000 - 1100 1111 1000=0010 1000=40)

数组指针和一维数组
在这里插入图片描述
数组指针和二维数组
用数组指针打印二维数组:
在这里插入图片描述
复杂一点,用函数传址来实现:

#include<stdio.h>
void print2(int(*p)[5], int r, int c)//r为行数,c为列数
{
	int i = 0;
	int j = 0;
	for (i = 0; i < r; i++)
	{
		for (j = 0; j < c; j++)
		{
			printf("%d ", *(*(p + i) + j));
		}
		printf("\n");//打印完一行后,换行
	}
}
int main()
{
	int arr[3][5] = { { 1, 2, 3, 4, 5 }, { 2, 3, 4, 5, 6 }, { 3, 4, 5, 6, 7 } };
	print2(arr, 3, 5);//传二维数组名,即二维数组首元素地址,即二维数组第一行的地址
	return 0;
}

在这里插入图片描述

5.传参

一维数组传参

#include<stdio.h>
void test1(int arr[])//数组接收
{}
void test1(int arr[3])//数组接收
{}
void test1(int *arr)//指针接收
{}
void test2(int *arr[20])//数组接收
{}
void test2(int **arr)//指针接收
{}
int main()
{
	int arr1[10] = { 0 };//整型数组
	int *arr2[20] = { 0 };//整型指针数组
	test1(arr1);
	test2(arr2);
}

数组:
函数传入数组的数组名时:
(1)数组传参数组接收,传入的是整型数组,那可以用数组接收。
(2)使用数组接收有两个表达a[ ]和a[ 3 ]。(一维数组内部可省略)
(3)传入的数组名本质上是数组首元素地址,所以可以用指针接收。

指针数组:
函数传入指针数组的数组名时:

(1)数组传参数组接收,传入的是指针数组,用整型指针数组接收。
(2)指针接收,数组的元素是int * 类型的,我们接收int * 类型元素的地址用二级指针int ** 即可。

二维数组传参

#include<stdio.h>
void test(int arr[][5])//数组接收
{}
void test(int arr[3][5])//数组接收
{}
void test(int(*arr)[5])//指针接收
{}
int main()
{
	int arr[3][5] = { 0 };//二维数组
	test(arr);
}

传入二维数组的数组名时:

(1)二维数组传参就用二维数组接收。
(2)用数组指针接收,二维数组的首元素是二维数组第一行的地址,即一维数组的地址。
(3)([ ][5] 后面的空格不能省略)

一级指针传参

有三种情况:但传入的表达式最终的类型是一级指针类型

#include<stdio.h>
void test(int* p)
{}
int main()
{
	int a = 10;
	test(&a);//可以传入变量的地址
	int* p = &a;
	test(p);//可以传入一级指针
	int arr[10] = { 0 };
	test(arr);//可以传入一维数组名
	//...
	return 0;
}

二级指针传参

有三种情况:但传入的表达式最终的类型是二级指针类型

#include<stdio.h>
void test(int** p)
{}
int main()
{
	int a = 10;
	int* pa = &a;
	test(&pa);//可以传入一级指针的地址
	int** paa = &pa;
	test(paa);//可以传入二级指针
	int* arr[10];
	test(arr);//可以传入一级指针数组的数组名
	//...
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值