C进阶:指针的进阶(2)

引入:

上一篇博文我们已经学习了字符指针,指针数组,数组指针有关知识,下面我们将对其展开讲一些重要的相关知识,欢迎各位观众老爷的观看。

&数组名VS数组名

这个知识点我可能上篇博文写过了,不过挺重要的,所以我拿出来再讲一下。

对于一个数组:

int arr[5];

arr和&arr分别是啥?

我们之前讲过arr在大部分情况下代表首元素的地址

所以这里还有两个例外:

1.sizeof数组名,这里数组名不是数组首元素地址,而是整个数组,其计算的是整个数组的大小(单位:字节)

2.还有一个就是我们要讲的&arr;

我们来看下面一段代码:

扫描二维码关注公众号,回复: 15794652 查看本文章
#include <stdio.h>

int main()
{
	int arr[5] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", &arr);
	return 0;
}

可见两个结果是相同的。难道说两个是一样的吗?

我们再来看一个代码:

#include <stdio.h>

int main()
{
	int arr[5] = { 0 };
	printf("%p\n", arr);
	printf("%p\n", arr + 1);

	printf("%p\n", &arr);
	printf("%p\n", &arr + 1);
	return 0;
}

 

从上述代码我们显然可见:

1.从arr到arr+1的跨度是四个字节,也就是一个int单位。

2.从&arr到&arr+1的跨度是20个字节,也就是5个int单位。

因此不难得出:

第一种是跨过了数组中的一个单位,第二个而是直接跨过了一个数组。

 数组参数,指针参数

在写代码时我们难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计呢?

下面通过不同情况的几种例子,我们来看一下它们是怎么传参的。

数组的传参

一维数组传参

#include<stdio.h>

void test(int arr[])//ok?
{}
//ok 这种属于直接将数组作为参数,且一维数组中[]中内容可省略

void test(int arr[10])//ok?
{}
//ok 这种属于直接将数组作为参数

void test(int* arr)//ok?
{}
//ok 传过来的数组名是首元素地址,所以可以用一级指针来接收

void test2(int *arr[20])//ok?
{}
//ok 直接用数组指针作参数,类型一致

void test2(int** arr)//ok?
{}
//ok 由于该数组指针每个元素的类型为int*类型,所以我们这里用二级指针接收一级指针取出的地址

int main()
{
	int arr[10] = { 0 };
	int* arr2[20] = { 0 };
	test(arr);
	test2(arr2);
	return 0;
}

二维数组传参

​
#include <stdio.h>

void test(int arr[3][5])//ok?
{}
//ok 直接以二维数组的原形式作为参数

void test(int arr[][])//ok?
{}
//no 行和列都没有提供无法根据参数构建出原来的二维数组

void test(int arr[][5])//ok?
{}
//ok 二维数组传参可以省略行但同时不能省略列

//总结:二维数组传参,函数形参的设计只能省略第一个[]中的数字
//因为对于一个二维数组,可以不知道有多少行,但必须知道一行有多少元素


void test(int* arr)//ok?
{}
//no 该参数表示的是一行的元素

void test(int* arr[5])
{}
//no 该形式参数为指针数组

void test(int (*arr)[5])
{}
//yes 该形参为数组指针,指向一行,每一行有五个元素

void test(int** arr)
{}
//no 二级指针接收的是一级指针的地址,而传来的是二维数组

int main()
{
	int arr[3][5] = { 0 };
    test(arr);
	return 0;
}

​

指针传参

#include <stdio.h>

void print(int* p, int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", *(p + i));
	}
}

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	//一级指针p,传给函数
	print(p, sz);
	return 0;
}

思考:

当一个函数的参数部分为一级指针时,函数能接受什么参数?

1.与它类型相同的指针。

2.一个数组。

3.一个数的地址。

下面是一些例子:

//情况一:(10是另一个随机参数)
int a = 10;
int *p = &a;
print(p1, 10);
//情况二:
int arr[4] = {0};
print(arr, 10);
//情况三:
int a = 10;
print(&a, 10);

二级指针传参

#include<stdio.h>

void test(int** ptr)
{
	printf("%d\n", **ptr);
}

int main()
{
	int n = 10;
	int* p = &n;
	int** pp = &p;
	test(pp);
	test(&p);
    //结果:两个都是10
	return 0;
}

思考:

当函数的参数是二级指针的时候,可以接收什么参数?

1.一级指针的地址

2.与它相同的指针

好啦,这一期就到这里,感谢各位未来的大厂员工观看,谢谢!

猜你喜欢

转载自blog.csdn.net/asdssadddd/article/details/131734974