【C语言零基础入门篇 - 13】:特殊指针

特殊指针


指针函数和函数指针

指针函数的含义:是一个函数,只不过这个函数的返回值是一个指针。

在这里插入图片描述

函数指针的含义:是一个指针,一个指向函数的指针。

思考:变量有地址,数组也有地址,那函数会有对应的地址么?
指针变量保存的是地址,所以函数指针变量保存的是函数的地址

函数指针变量的定义格式:函数返回值类型 (*标识符)(所指向的函数参数列表);

  • 简单定义一个函数指针
    在这里插入图片描述
  • 实现加法、减法、乘法功能
#include<stdio.h>

//加法
int Add(int x, int y)
{
	return x + y;
}
//减法
int Sub(int x, int y)
{
	return x - y;
}
//乘法
int Mul(int x, int y)
{
	return x*y;
}

//输出计算的功能
void fun(int(*pa)(int, int), int x, int y)
{// pa=函数的首地址
	printf("%d\n", pa(x, y));
}

int main()
{
	//传入函数首地址,根据函数首地址实现相应的功能
	//fun(Add, 5, 5);
	fun(Sub, 10, 5);//Sub函数是回调函数
}

在这里插入图片描述
函数指针变量与回调函数指针:
函数指针变量的一个重要的用途是把函数的地址作为参数传递到其他函数。

回调函数:如果你把函数的地址作为参数传递给另一个函数,当这个指针变量被用来调用其所指向的函数时,我们就称这是回调函数。

使用typedef给函数指针取别名

使用typedef给函数指针取别名:

如:typedef int(*funp)(int,int);

//给int()(int,int)类型的函数指针取一个别名为funp

funp p1;
	
//使用别名funp定义int()(int,int)类型的函数指针p1
  • 将上述代码修改一下
//给函数指针Pa取别名,Pa是类型,是函数指针这个类型
typedef int(*Pa)(int, int);

//输出计算的功能
void fun(Pa p, int x, int y)
{// p是函数指针变量
	printf("%d\n", p(x, y));
}

指针常量和常量指针

指针常量

指针常量就是指针的指向不能够被改变的指针,也就是指针类型的常量,指针中存储的地址不可被改变。

如:int * const p;
它的指向不能改变,但是能改变指向的值

  • 指向不能被修改,但是能改变指向的值
    在这里插入图片描述

常量指针:

常量指针就是指向常量的指针,也就是指针指向的地址内的值不可被改变,其又被称为只读指针。

如:const int *p;
它的能够改变指向,但是不能够改变地址内的值
在这里插入图片描述

指针常量和常量指针一般用于函数参数的传递,为了使在函数使用中不改变值以及指针的指向。

如:常量指针常量

void fun(const int * const p)//指向常量的指针常量
{
	//指针p是一个只读指针,防止篡改
	//既不能改变指针p的指向,也不能改变其指向地址里的值
}

注意:定义指针常量的时候一定要赋初值,不然后面你就不能赋初值了,因为指针常量不能被修改了。

int*const p = &a; //p的值不能被修改  *P可以被修改

const 在c++和c中的应用

在这里插入图片描述
在这里插入图片描述

指针数组

什么是指针数组?
所谓指针数组,其本质上是一个数组,数组中的每一个元素都是指针类型的,都可以指向对应数据类型的地址。

指针数组的定义
定义的一般格式:数据类型 *指针数组名[数组元素个数];

如:int *p[4];
//定义一个指针数组,有4个元素,每一个元素都是int *类型
在这里插入图片描述
在这里插入图片描述

指针数组与字符数组

在这里插入图片描述

数组指针

什么是数组指针?
所谓的数组指针变量,其本质上是一个指针变量,是一个用于保存数组地址的指针变量。

数组指针的定义
定义的一般格式:
所指向数组的数据类型 (*指针变量名)[所指向数组的大小];
如:int arr[2][4]={0};
int (*p)[4];
//定义了一个整型数组指针变量p,用于指向列数为4的整型二维数组
p=arr; //将整型数组指针变量p指向二维数组a

在这里插入图片描述

	int arr[2][3] = { 1, 2, 3, 4, 5, 6 };
	int(*p)[3] = NULL; //方括号里面是指向的二维数组的列数
	//定义了一个数组指针变量p
	p = arr;
	//arr是二维数组的名字,它的值和二位数组的首地址是一样的,与&arr[0][0]的类型不一样
	//int*[3] 是arr的类型,也是数组指针p的类型

#include<stdio.h>
void fun(int arr1[][3]) //接收二维数组的参数,二维数组的列数不能省略
{//arr1 = arr arr1不是二维数组名 是数组指针 int(*arr1)[3]
	//能不能修改主函数中二维数组arr的元素值?
	//可以
	arr1[0][3] = 20;
}
int main()
{
	int arr[2][3] = { 1, 2, 3, 4, 5, 6 };
	fun(arr); //要传一个二维数组,需要把二维数组的名字作为实参
	for (int i = 0; i < 2; i++)
	{
		for (int j = 0; j < 3; j++)
		{
			printf("%d\t", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

街 三 仔

你的鼓励是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值