IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C语言】指针 函数指针变量调用 函数指针数组 只读指针变量和只读变量指针 特殊指针 -> 正文阅读

[C++知识库]【C语言】指针 函数指针变量调用 函数指针数组 只读指针变量和只读变量指针 特殊指针

1.通过函数指针变量调用
?? ?定义一个函数指针,这个指针指向的函数返回值是int型,入参是两个int型
?? ?相同类型的指针可以相互赋值?

	int a = 20;
	int b = 10;
	int (*p)(int,int);//定义一个函数指针,这个指针指向的函数返回值是int型,入参是两个int型
	int (*q)(int ,int);//相同类型的指针可以相互赋值 
	p = add;//函数名表示函数的首地址 
	printf("%p\n",p);
	printf("%d\n",p(a,b)); 
	p = sub;
	printf("%p\n",p);
	printf("%d\n",p(a,b)); 

函数指针最常用的地方在于将一个函数作为参数传递给另一个函数的时候要用函数指针
?? ?将一个函数作为参数传递给另外一个函数,将这个函数称为回调函数。

#include<stdio.h>
//两数相加
int add(int a,int b)
{
	return a+b;
} 
//两数相减
int sub(int a,int b)
{
	return a-b;
} 
//两数相乘
int cheng(int a,int b)
{
	return a*b;
}
//两数相除
int ave(int a,int b)
{
	return a/b;
}
//两数取余
int yu(int a,int b)
{
	return a%b;
}
 int caculator(int (*p)(int,int),int a,int b)//将函数指针作为一个函数的入参,这是回调函数 
 {
 	return p(a,b);
 }
int main()
{
	int a = 20;
	int b = 10;
	int (*p)(int,int);//定义一个函数指针,这个指针指向的函数返回值是int型,入参是两个int型
	int (*q)(int ,int);//相同类型的指针可以相互赋值 
	p = add;//函数名表示函数的首地址 
    //两数相加返回的函数
	int ret = caculator(add,a,b);
	printf("%d\n",ret);
    //两数相减返回的函数
	 ret = caculator(sub,a,b);
	printf("%d\n",ret);
    //两数相乘返回的函数
	ret = caculator(cheng,a,b);
	printf("%d\n",ret);
     //两数相除返回的函数
	ret = caculator(ave,a,b);
	printf("%d\n",ret);
     //两数取余返回的函数
	ret = caculator(yu,a,b);
	printf("%d\n",ret);
	return 0;
 } 

例:用函数指针实现三个数相加

	int ret = add(a,b);
	int sum =  caculator(add,ret,c); 
	printf("%d\n",sum);

2.指针函数数组
?? ?本质是一个数组,数组里面的每一个元素都是函数一个函数指针
?? ?返回值类型 ? (*函数指针变量名[函数指针的个数]) (形参列表)?
?? ?int (*p[10])(int,int)?
?? ?定义了一个函数指针数组,数组中有5个元素p[0]~p[4],每个元素都是函数指针变量,该函数指针变量指向的函数必须有整形的返回值和两个整形参数。(有两种做法均在下方)

#include<stdio.h>
//函数指针数组
//本质是一个数组,数组里面的每一个元素都是一个函数指针
//返回值类型   (*函数指针变量名[函数指针的个数]) (形参列表) 
//int (*p[10])(int,int) 
 int add(int a,int b)
{
	return a+b;
} 
int sub(int a,int b)
{
	return a-b;
} 
int mul(int a,int b)
{
	return a*b;
}
int div(int a,int b)
{
	return a/b;
}
int mod(int a,int b)
{
	return a%b;
}
int main()
{
	int a = 20;
	int b = 10;
	int c = 30;
	//定义一个函数指针数组 
	//数组有5个元素,数组中的每一个元素都是函数指针,指针指向一个函数的首地址
	//函数的返回值是int型,有两个int型入参
	//第一种方法
//	int (*p[5])(int,int) = {add,sub,mul,div,mod};
	//等价于上面函数初始化 
	//第二种方法定义指针数组并给各个数组赋值数组赋值 
	int (*p[5])(int,int);
	p[0] = add;
	p[1] = sub;
	p[2] = mul;
	p[3] = div;
	p[4] = mod; 
	//第一种方法的循环 
//	int i;
//	for(i = 0;i<5;i++)
//	{
//		printf("%d\n",p[i](a,b)); 
//	}
	//第二种方法:实现三位数相加的打印,(加减乘除取余的方法均可以用这种方法) 
	printf("%d\n",p[0](p[0](a,b),c));
	return 0;
 } 

3.只读指针变量
?? ?只读指着变量不能被重新赋值,地址不能被修改,但是值可以被修改
?? ?定义:类型 ? *const ? 变量名

用const修饰的指针变量地址不能被修改,但是它所对应的地址的值可以被修改?

#include<stdio.h>
//只读指针变量 ,他这个地址只能被读不能被修改 
int main()
{
//	int *p;
	int a = 20;
	int b = 10;
	int * const p = &a;
	printf("%p\n",p);
	printf("%d\n",*p); 
	
//	p = &b; //用const修饰的指针变量地址不能被修改,但是它所对应的地址的值可以被修改 
//	printf("%p\n",p);
//	printf("%p\n",*p); 
    //只读指针的值可以被修改
	*p = 100;
	printf("%d\n",a);
	printf("%p\n",p);
	printf("%d\n",*p); 
	return 0;
}

4.只读变量指针
?? ?只读变量指针,地址可以被修改,值不能被修改
?? ?定义:类型 ?const ?* 变量名

//只读变量指针,与只读指针变量相反
//它的地址可以被修改,但是值只能读不可以改 
#include<stdio.h>

int main()
{
	int a = 20;
	int b = 10;
//只读变量指针,从const往左看,休先结合int,说明是只读指针变量
	int const * p = &a;  //定义一个只读变量的指针
	printf("%d\n",*p);
	printf("%p\n",p);
	printf("%d\n",a);
		
	p = &b;//用const修饰的指针变量地址可以被修改,但是它所对应的地址的值被修改 
	printf("%d\n",*p);
	printf("%p\n",p);
	printf("%d\n",b);
	printf("%d\n",a);
		
//	*p = 200;    // 不能修改只读变量指针的值
//	printf("%d",*p);
//	printf("%p",p);
//	printf("%d",a);
	return;
 } 

5.特殊指针
?? ?1.硬编码赋值给指针
?? ??? ?指针变量是指向变量的地址
?? ??? ?这个没有意义,无法确定数值这个地址被占用,编译器会警告

int *p;

? 2.空指针
?? ?一般用于初始化,不确定什么时候使用,所以先将他指向空值(NULL)

	int *p = NULL; 

?3.野指针
?? ??? ?像上面2所说,如果定义了一个指针没有将他先指向空值(NULL),他会随机指向一个区域,通常将这个称为野指针。
?? ??? ?指针被释放时没有将他置空,也会在下一步随机指向一个区域也称为野指针。比如:再用malloc( )函数开辟空间时,要检查返回值是否为空,如果为空,则开辟失败,如果不为空,则指针指向的是开辟的内存空间的首地址。指针指向的内存空间再用free()释放后,如果没有对释放后的指针进行置空,就会称为野指针。

#include<stdio.h>
#include<stdlib.h>
int main()
{
//	int a = 10;//系统自动分配,申请空间在栈上 
	p = malloc(512);//需要程序员自己分配,用完释放掉,申请的空间在堆上 
	if(p == NULL)
	{
		return -1;
	 } 
	 *p = 100;
	 printf("%d\n",*p);
	 free(p);
	 p = NULL;
	return 0;
 } 

4.万能指针 ?void *(也称空类型指针)
?? ??? ?void *指针可以指向任意变量的内存空间

#include<stdio.h>

int main()
{
	int a = 10;
	char ch = 'a';
	float b = 1.2;
	
	void *pp;
	pp = &a;
	pp = &ch;
	pp = &b;
	
//	printf("%p\n",pp);
//printf("%d\n",*pp);//直接打印pp的值,会报错,因为pp是一个void型 的指针 
//	printf("%d\n",*((int *)pp));//将void *指针pp强制转换成某个数据类型的指针,再取值
	//需要将void型的指针转换成int型指针在打印值
	//通过万能指针修改变量内容值,需要指定变量对应的指针类型
	*((int *)pp) = 100;
	printf("%d\n",*((int *)pp));
	
	
	*((char *)pp) = 'e';
	printf("%c\n",*((char *)pp));
	
	*((float *)pp) = 59.9;
	printf("%f\n",*((float *)pp));
	return 0;
}

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 00:51:43  更:2022-09-04 00:52:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/13 5:51:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码