C语言学习笔记(指针3)

101 阅读1分钟

​「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战

数组参数,指针参数

数组传参

void test(int arr[3][5])
{}
void test1(int[][5])
{}
void test2(int arr[3][])//err
int main()
{
	int arr[3][5] = { 0 };
	test(arr);//二维数组传参
	test1(arr);
	test2(arr);
	return 0;
}

二维数组传参,函数形参的设计只能省略第一个[ ]的数字,因为对于一个二维数组,可以不知道有多少行,但是必须知道一行多少元素,这样才更加方便运算。

二维数组首元素地址是数组第一行的地址。

一级指针传参

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

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

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

void test1(int* p)
{}
int main()
{
	int a = 10;
	test1(&a);
	test1(p1);
	return 0;
}

二级指针传参

void test1(int** ptr)
{
	printf("num = %d\n", **ptr);
}
int main()
{
	int n = 10;
	int* p = &n;
	int** pp = &p;
	test(pp);
	test(&p);
	return 0;
}

void test(int**p)
{}
int main()
{
	int *ptr;
	int** pp = &ptr;
	test(&ptr);
	test(pp);
	int* arr[10];
	test(arr);//指针数组也可以

	return 0;
}

可以传:一级指针的地址,二级指针变量本身,存放一级指针的数组的数组名

函数指针

数组指针 - 指向数组的指针
函数指针 - 指向函数的指针- 存放函数地址的一个指针

int Add(int x, int y)
{
	int z = 0;
	z = x + y;
	return z;
}
int main()
{
	int a = 10;
	int b = 20;
	int arr[10] = { 0 };
	printf("%p\n", &Add);
	printf("%p\n", Add);
	//&函数名 和 函数名 都是函数的地址
	return 0;
}

int Add(int x, int y)
{
	int z = 0;
	z = x + y;
	return z;
}
int main()
{
	int a = 10;
	int b = 20;
	//int arr[10] = { 0 };
	//int(*p)[10] = &arr;

	int(*pa)(int, int) = Add;
	printf("%d\n", (*pa)(2, 3));//5
	return 0;
}

看下面两个代码:

代码1:

(*(void)(*)()0)();

(       void()()      )0   ---->  ((      void(*)()      )0) ();

把0强制类型转换成:void(*)()函数指针类型 - 0就是一个函数的地址,调用0地址该处的函数

代码2:

void(*signal(int, void(*)(int)))(int);

void(*)(int)  ---->函数指针类型

void(*                     )(int)  ----->

类比:int Add(int,int)