(套娃篇上)C:奇妙的指针 指针类型+指针数组+数组指针+数组和指针的传参

目录

一.什么是指针?

二.指针类型

2.1字符指针

2.2 指针数组

2.3 数组指针

2.3.1数组指针怎么用?

 2.4 数组参数,指针参数

2.4.1一维数组的传参

2.4.2 二维数组的传参


一.什么是指针?

指针其实就是个变量,这个变量里面存放地址。

但是指针是有类型的,不同的指针类型决定了指针加减整数移动的步长。

我们来看一段代码

 如果是char类型呢

 所以,你看,不同的指针类型决定了指针加减整数时候移动的步长

double*改变的则是八个字节,我们可以自己去验证一下。

二.指针类型

2.1字符指针

字符指针的类型一般为“ char* ”。 

这里是打印的结果:

那么我们来验证一下pc里面存放的是不是pc的收元素的地址呢?

那我们接下来,来看两串代码打印的结果如何?

 打印结果:

 为什么呢?

画张图来看看他们之间的关系吧

从图上我们可以看出,arr1和arr2是不同的两块内存,而p1,p2则指向了同一块内存。当然了,这段常量字符穿在内存中存储的时候最后面是‘\0’。

2.2 指针数组

指针数组是个什么鬼东西?

它其实是一个数组,用来存放指针的,而指针也就是一个地址变量嘛。

整型指针数组,用来存放整形指针;字符指针数组,用来存放字符指针。

来看一组代码:

这串代码我们重点要搞清楚,arr1,arr2,arr3是怎么放在parr里面的?

 

 打印的时候,i,j分别控制三行六列,parr[i]找到某一行的首元素地址,+j表示向后移动几个单位,顺利找到arr1-3的地址,解引用操作,并将其打印出来。

2.3 数组指针
 

什么是数组指针?

这里要和指针数组区分开来,指针数组是一个数组,数组里面存放了指针(也就是地址,整形指针,字符指针什么的);

而数组指针它首先是个指针,是一个指向数组的指针,它可以存放一个数组的地址(这是区别)。

	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int(*p) [10] = &arr; //p就是数组指针
    //含义:一个指针p ,指向一个数组,数组里面有十个元素,每个元素的类型是int

这里的p如果不加括号(*p),那么p就会先和[]结合,形成一个数组。

这也是指针数组和数组指针写法上的一个差异,要格外注意,加以区分。

2.3.1数组指针怎么用?

数组指针一般要涉及到二维数组以上使用才会带来便利。

来看一组代码

void Print1(int arr[3][5], int x, int y)
{
	int i = 0, j = 0;
	for (i = 0; i < x; i++)
	{
		for (j = 0; j < y; j++)
		{
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
}

void Print2(int(*p)[5], int x, int y)
{
	int i = 0;
	for (i = 0; i < x; i++)
	{
		int j = 0;
		for (j = 0; j < y; j++)
		{
			//printf("%d ",*(*(p + i) + 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 } };
	Print1(arr, 3, 5);
	printf("\n");
	Print2(arr, 3, 5);
	return 0;
}

 

代码的分析:

接下来我们来看一看这样一组代码是什么意思

int(* pa[10] )[5]

我们来分析一下这个东西~

 2.4 数组参数,指针参数

 

2.4.1一维数组的传参

我们如果想要把数组或者指针传给函数,那么参数部分该怎么正确的书写呢?

来串代码我们一起分析一下。

void test(int arr1[]) //ok?
{}
void test(int arr1[10])  //ok?
{}
void test(int *arr1)  //ok?
{}
void test2(int* arr2[20])//ok?
{}
void test2(int **arr2)    //ok?                
{}
int main()
{
	int arr1[10] = { 0 };
	int* arr2[20] = { 0 };
	test(arr1);
	test2(arr2);

	return 0;
}

先上结论,上面这些参数书写形式,是完全正确滴~

分析一下:

 

 

总结:

        1. 你传来个啥,我就用个啥接待你,你可以省略掉“[]”里面的数字。(数组传参)

        2.指针可以用来存放你传来的首元素地址,通过你首元素的地址找到你的余下元素;同时二级指针存放的是一级指针的地址。(指针传参)

2.4.2 二维数组的传参

上个代码一起看一下:

void test1(int[2][3])
{}

void test2(//这里面怎么写呢?)
{}
int main()
{
	int arr[2][3] = { 0 };

	test1(arr);
	test2(arr);
}

 

 我们一起来看一下test2 的参数怎么写才正确?

这样一跑,没有任何问题

 

 

 为了更好的理解传参,我们来逆向思考一下~

如果函数 的参数是一个一级指针,那我们都可以用什么参数传给它呢?

来一起瞅瞅:

总结:

一级指针参数都可以存放什么呢?

1. 一级指针本身

2. 整型等的地址

 那如果函数 的参数是一个二级指针呢,那我们都可以用什么参数传给它呢?

 那还有没有什么东西可以穿给二级指针呢?

指针数组里面存放的是不是也是地址啊,存放的是数组的地址

int* arr[10];
test(arr)

这里的arr[10]数组里面存放类型都是int*(整型的地址),也就是一级指针的地址,所以它也可以传给二级指针。

总结

二级指针参数都可以接待什么:

1.二级指针本身

2.一级指针的地址

3.指针数组的地址(本质也是一级指针,存放的是数组的地址)

套娃篇 未完待续..

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值