深入理解指针机制_sd116460的博客-程序员秘密

深入理解指针及指针相关内容
  1.什么是指针:指针是编程语言中的一个对象,利用地址,他的指直接指向存在电脑存储器中另一个地方的值,由于能够通过地址找到所需的变量单元,可以说地址指向变量单元,因此我们可以说:指针就是地址,通过指针可以找到以它为地址的内存单元


  指针是存放地址才出现的,地址是为了表示一块地址空间的,相当于我们给多个完全相同的房间贴上门牌号,来进行区分,方便我们查找


  指针让地址有地方存放,指针让内存的访问更加的方便


  指针的大小在32位平台下是4个字节,64位平台上是8个字节


  我们都知道变量是有类型的,那么指针也是有类型的,指针的类型就是;type + *的方式


  不同类型的指针就是为了存放相对应的类型的变量的地址,例如:char *类型的指针就是为了存放char类型的变量的地址,int *类型的指针就是为了存放int类型的变量的地址


  因为指针是有类型的所以当我们在进行指针的加减运算时对指针的加减一其实是对其所指向类型的大小进行加减。


  指向同一个数组的两个指针相减(前提是类型相同)代表的就是两指针之间经历的元素个数,元素的类型有相减的指针类型决定


  允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较


  对指针解引用就是他所指向的目标变量

  指针变量是变量,开辟的空间里放的是指针。
  变量指针就是变量地址






1.理解函数指针和定义 
  函数指针变量:保存函数地址的变量
  函数名通常代表了函数的地址,函数指针是用来保存函数地址的。
  例如:void (*pfun1)()  函数指针
  函数指针不同于函数的声明: void *pfun2() 为 函数的声明
  代码举例:



程序运行完毕后输出的结果为:


可以看到输出的结果相同,也就是说函数名其实就是函数的地址


函数指针在程序中的调用:
Void (*test) ()当在函数中输出函数指针时,输出的是函数的地址,且与&test相同,说明了:函数指针是用来保存函数的地址的。


2.理解函数指针数组和定义,转移表 
   数组是一个存放相同类型的数据的存储空间,把函数的地址存放到一个数组中,把这个数组就叫做函数指针数组(那我们根据指针的定义,我们是不是可以称他为函数地址数组呢?这样更加的便于我们的理解,当然这只能是我们的书面语言)。
  函数指针数组的定义: int (*p[10])()      p先和[]结合,说明p是一个数组,数组内容是int (*)()类型的函数指针




转移表:
代码示例: #include<stdio.h>
#include<Windows.h>
#pragma warning(disable:4996)


int add(int x, int y){

return (x + y);
}
int sub(int a, int b){
return a - b;
}
int mul(int a, int b){
return a*b;
}
int  div2(int a, int b){
return a / b;
}
int main(){


int ret=0;
int input = 1;

int(*p[5])(int x, int y) = { 0, add, sub, mul, div2 };
while (input){
printf("*****************************\n");
printf("1.add   2.sub   3.mul   4.div\n");
printf("*****************************\n");
printf("请选择:\n");
int select;
scanf("%d", &select);
if ((select >= 1) && (select <= 4)){
printf("请输入需要操作的数字:\n");
int x, y;
scanf("%d%d", &x, &y);
int ret = p[select](x, y);
printf("%d", ret);
break;

}
else{
printf("输入的选择错误!\n");
printf("%d\n", ret);
}
}
system("pause");
return 0;
}


3.理解指向函数指针数组的指针和定义指向函数指针数组的指针:
     指向函数指针数组的指针是一个指针,指针指向一个数组,数组的元素都是函数指针。
定义方式:
  void (*(*p)[10])(const char*)
  顺序:定义一个函数指针,*p
函数指针的数组*p[10]
函数指针的数组的指针:(*(*p)[10])


 
4.理解回调函数的使用 
回调函数是一个通过函数指针调用的函数,如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用指向其所指的函数的时候,我们就说这是回调函数。回调函数不是该函数的实现方直接调用,而是在特定的事件或条件发生时由另一方调用的,用于对该事件或条件进行响应。


 
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sd116460/article/details/80443547

智能推荐

LaTeX表格制作(表格内多行组合数据的输入)_latex表格多行_Uuuuunbelieve的博客-程序员秘密

LaTeX复杂表格制作常用LaTeX表格主要有三个:tabular最基础的表格制作方式,是table的组件,缺点是无法对表格进行排序,如:“表1”。table内含tabular,可以对表格进行计算机自动排序。longtable需要导入longtable宏包,解决表格太大,显示不全的问题。用法与table一致。tabular 1. 内容:列与列之间用“&amp;”隔开,行与行之间用“\\”表示,位于每一行的最后; 2. 对齐方式:左对齐“l”,居中对齐“c”,右对齐“r”,

Struts2中的值栈与OGNL2 的使用_China2010pan的博客-程序员秘密

访问属性名字属性获取:地址属性获取: 访问方法调用值栈中对象的普通方法: 访问静态属性和方法调用Action中的静态方法:调用JDK中的类的静态方法:调用JDK中的类的静态方法(同上):调用JDK中的类的静态方法:调用普通类中的静态属性: 访问构造方法调用普通类的构造方法:

(56)组件之paper2D组件_ue apaperspriteactor类_zl908760230的博客-程序员秘密

纸张 2D 组件用于添加(或修改)2D Sprites 或 Flipbooks 以作为 Actor 的子对象。Paper Sprite Component (Paper Sprite 组件)PaperSpriteComponent 用于处理 UPaperSprite 资产的单个实例的渲染和碰撞。 当您将精灵资产从 Content Browser 拖放到 Blueprint 时,将创建该

RAC 集群 连接的时候报错 ora-12541_有趣是好的的博客-程序员秘密

首先 监听的信息Listening Endpoints Summary... (DESCRIPTION=(ADDRESS=(PROTOCOL=ipc)(KEY=LISTENER))) (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=10.100.21.205)(PORT=1521))) (DESCRIPTION=(ADDRESS=(PROTOCOL=t

idea报错Module Project1 must not contain source root "...\Project1\src". The root already belongs to ._gblfy的博客-程序员秘密

idea报错Module Project1 must not contain source root “…\Project1\src”. The root already belongs to m选择你的根模块选择modules,选择根模块,删除add content root 下面不直接属于根模块的目录即可。...

Intellij IDEA快捷键与使用小技巧_idea回到上次编辑的地方_pan_junbiao的博客-程序员秘密

IntelliJ Idea 常用快捷键列表:Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Shift+Click,可以关闭文件Ctrl+[ OR ],可以跑到大括号的开头与结尾Ctrl+F12,可以显示当前文件的结构Ctrl+F7,可以查询当前元素在当前文件中的引用,然后按 ...

随便推点

thingsboard成功下载完美启动_thingsboard下载_w.pan的博客-程序员秘密

tb的启动 -- 如这篇文章看完之后,还是不能解答你心中的疑惑;关注我 后续文章肯定会为你解答

CSS_学习java需要(笔记)_sout("w.");的博客-程序员秘密

CSS1.基本介绍1.基本介绍* 1.概念: Cascading Style Sheets 层叠样式表 * 层叠:多个样式可以作用在同一个html的元素上,同时生效2. 好处: 1. 功能强大 2. 将内容展示和样式控制分离 * 降低耦合度。解耦 * 让分工协作更容易 * 提高开发效率...

android-java 面试题搜集_weixin_30641465的博客-程序员秘密

1、注册广播有哪几种方式,有什么区别1-1.常驻型广播 注册方式就是在应用程序的AndroidManifast.xml中进行注册,这注册方式通常又被称作静态注册action android:name="android.provider.Telephony.SMS_RECEIVED"/&gt;1-2、非常驻形广播··非常驻型广播,当应用程序结束了,广播自然就没有了, 比如在 Activ...

斐波那契输出第n项(递归 非递归)_斐波那契使用递归输出第n项_junmoxiaoyhc的博客-程序员秘密

#include&lt;stdio.h&gt;#define M 100//递归法int Fibo1(int n){ if(n==1||n==2){ return 1;//递归终止条件} else { return Fibo1(n-1)+Fibo1(n-2);//递归 }}//非递归法in...

SPRING--Spring中IOC(反转控制) 和 AOP(面向方面编程)_ioc面向对象编程_xiaoxiaocoder的博客-程序员秘密

一、IOC基本注入和集合注入实体类Bean--配置文件(applicationContext)--测试类(Test)1.1 实体Bean:属性+getter()方法+setter()方法public class MyBean {private String url;private String name;private String pwd;private int

Mysql之InnoDB中线程详解_mysql purge线程_才放一花天地香的博客-程序员秘密

InnoDB存储引擎是多线程的模型,因此其后台有多个不同的后台线程,负责处理不同的任务。主要分为:Master Thread、IO Thread、Purge Thread和Page Cleaner Thread。Master Thread通过名字就可以看出,Master Thread是非常重要的线程,维护着InnoDB存储引擎中的大多数的操作,因为此线程的效率也直接影响着InnoDB的整体性能。所以,不同InnoDB版本的改进也主要针对此线程的功能进行的。InnoDB1.0.x版本之前 Master T

推荐文章

热门文章

相关标签