当前位置:文档之家› 指针与数组 函数的组合

指针与数组 函数的组合

指针与数组 函数的组合
指针与数组 函数的组合

指针和数组

?

? 1.指针数组:是其数组元素为指针的数组。记住:是一个存放着指针的数组,而不是一个指针

?定义格式为:数据类型* 数组名[数组长度]

?如:int * a[10] ; [ ]的优先级高于*,意味着使得a是一个指针数组,表示具有10个元素的数组,每个元素是一个指向int 型的指针。

?

?2,指向数组的指针:是一个指针,指向的是一个数组。

?定义格式为:数据类型(*数组名) [数组长度]

?如:int (*a) [10];*先于a 结合,意味着a 是一个指针,指向具有10个int 值的数组,

?

?

?指针与函数

?

?1, 函数的指针:首先它是一个指针,指向函数的入口地址;在C语言中,函数名就是来标识函数的入口地址。

?与指向数组的指针不同,在数组中,可以对数组中的元素访问,可以进行算术运算。

而在函数中,只需考虑函数的入口地址,而不考虑函数中某具体指令或数据所在存

储单元的地址,即不能进行算术运算

?定义格式:存储类型数据类型(*函数名) ( )

?如:static int (*p) ();

?存储类型表示函数在文件中的存储方式

?数据类型表示被指函数的返回值的类型

?最后的空括号表示指针变量所指的是一个函数

?

?如何用指向函数的指针变量的方式来调用相应的函数:

?1), 使用前,必须先定义并赋值

?2), 指向函数的指针定义形式中的数据类型必须和赋给它的函数返回值类型相同

?3), 指向函数的指针只能指向函数的入口,而不能使用*(p+1) 来表示函数的下一命令?4), 在函数指针赋值时,只需给出函数名而不需给参数,如p = max;

?5), 调用时,只需将(*p) 代替函数名即可,在p 后面的括号中根据需要写上实参,如:

c = (*p) (a,b) ;

?如下程序:求直角三角形的斜边

?#include

? #include

?main()

?{

? int a ,b ,c , f() , (*f1)();

? a = 3; b = 4;

?f1 = f;

? c = (*f1) (a,b);

?printf("c = %d\n",c);

?}

? f (int x , int y)

?{

?int z;

?z = sqrt((double)(x*x + y*y));

?return (z);

?}

?

?2, 指针函数:返回指针值的函数称为指针型函数,记住:它是一个函数,只不过返回值是个指针。

?定义一般形式为:类型说明符* 函数名()

? {

? /* 函数体*/

? }

?如:int * ap (int x , int y)

? {

? /* 函数体*/

? }

?()的优先级比* 高,ap先于() 结合,说明ap 是个函数,返回的指针变量为整型。

?main()

?{

?int i;

?char * day_name (int n);

?printf("input Day NO. : \n");

?scanf("%d ",&i);

?if(i < 0)

?exit(1);

?printf("DayNo.: %2d -- >%s\n", i, day_name(i));

?}

?char * day_name(int n)

?{

?static char * name[]={"Illegal day","Mon","Tue","Wed","Thu","Fri","Sat","Sun"};

?return ((n < 1 || n >7)) ? name(0):name[n];

?}

?

?3, 指针型函数与指向函数的指针的区别

?如int (*p)()和int *p()

?1), int (*p)()是一个变量说明,说明p是一个指向函数入口的指针变量,该函数的返回值是整型值,(*p)两边的括号不能少。

?2), int *p()则是函数说明,说明p 是一个指针型函数,其返回值是一个指向整型量的指针,*p两边没有括号

??????????????????

函数指针

方法 指针函数和函数指针的区别 关于函数指针数组的定义 为函数指针数组赋值 函数指针的声明方法为: 数据类型标志符 (指针变量名) (形参列表); 注1:“函数类型”说明函数的返回类型,由于“()”的优先级高于“*”,所以指针变量名外的括号必不可少,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如: int func(int x); /* 声明一个函数 */ int (*f) (int x); /* 声明一个函数指针 */ f=func; /* 将func函数的首地址赋给指针f */ 赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。 注2:函数括号中的形参可有可无,视情况而定。 下面的程序说明了函数指针调用函数的方法: 例一、 #include int max(int x,int y){ return(x>y?x:y); } void main() { int (*ptr)(int, int); int a,b,c; ptr=max; scanf("%d%d",&a,&b); c=(*ptr)(a,b); printf("a=%d,b=%d,max=%d",a,b,c); } ptr是指向函数的指针变量,所以可把函数max()赋给ptr作为ptr的值,即把max()的入口地址赋给ptr,以后就可以用ptr来调用该函数,实际上ptr 和max都指向同一个入口地址,不同就是ptr是一个指针变量,不像函数名称那样是死的,它可以指向任何函数,就看你想怎么做了。在程序中把哪个

C语言中数组指针在汇编语言寻址方式中的应用

231 1、引言 《汇编语言程序设计》是高等院校计算机及相近专业学生必修的专业基础课程之一,它不仅是《嵌入式开发》、《操作系统》、《单片机》、《接口技术》等基础课程的先修课程,而且也十分有助于学生系 统掌握计算机基础知识和提高编程能力[1] 。作为一门直接控制计算机硬件和cpu结合最为紧密的一门语言,执行起来时最为有效和速度最快的。但是区别于高级语言他又自身的弱点,比如可读性差,需要更深入地熟悉硬件结构,编程和调试过程繁琐,而且没有便捷的开发调试环境。在讲授《汇编语言程序设计》过程中,如果能够结合或者转化为高级语言如C语言的内容那学生接受和学习起来就能增加不少的兴趣,提高学生的学习效率。 2、C 语言数组和指针的使用 2.1 数组 数组是在程序设计中为了处理方便,把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元 素的集合称为数组[2] 。在C语言中,数组属于构造数据类型。一个数组可以分解为多个数组元素,这些数组元素可以是基本数据类型或是构造类型。因在汇编语言中主要把指令系统中的寻址方式转换为一维数组或指针,所以下面就简要介绍一下一维数组和指针的特点 定义一维数组的格式为: 类型说明符 数组名[整型常量表达式],…;例如:int a[10],b[5];说明: (1)它表示定义了两个一维数组,一个数组名为a,另一个数组名为b。数组名是按照“标识符”的规则构成的。(2)a数组含有10个数组元素,即a[0]、a[1]、a[2]、…、a[9];b数组含有5个数组元素,即b[0]、b[1]、b[2]、b[3]和b[4]。注意,不能使用a[10]和b[5],否则即出现数组超界现象,并且需要注意的是数组的小标是从0开始的。(3)类型说明符int 说明a数组和b数组中的每个元素均占2个字节,只能存放整型数据。(4)整型常量表达式可以是整型常量或符号常量。最常见的是整型常量。不允许为变量。(5)C编译程序(如Turbo C)为a数组在内存中分配了10个连续的数组单元(共占20个字节),为b数组在内存中分配了5个连续的数组单元(共占10个字节)。(6)C编译程序还指定数组名a为数组的首地址,即a与&a[0]等价;指定数组名b为b数组的首地址,即b与&b[0]等价。 2.2 指针 指针是一个特殊的变量,它里面存储的数值被解释成为内存里 的一个地址。计算机内存中的每个内存单元,都有相应的内存地址。在程序中对变量进行存取操作有两种方式,一种叫“直接存取”,就是指在程序中对变量进行存取操作时是按变量的地址来存取的方法,另一种叫“间接存取”,就是通过另外定义一个指针变量来保存 需要访问的数据的地址[3] 。 (1)指向简单变量的指针。(2)指向数组的指针。指针所指的数组既可以是一维数组,也可是多维数组。(3)指针数组。数组的元素值为指针,指针数组是一组有序的指针集合。(4)指向指针的指针。如 果一个指针变量存放的是另一个指针变量的地址,则称这个指针变 量为指向指针的指针。(5)指向函数的指针。在C语言中,一个函数总是占用一段连续的内存区,而函数名就是该函数所占内存区的首地址。我们可以把函数的这个首地址赋予一个指针变量,通过指针变量就可以找到并调用这个函数。 3、数组和指针在汇编语言指令系统寻址方式中的应用和转换 3.1 汇编语言指令系统的寻址方式[4] (1)立即寻址。(2)寄存器寻址。(3)直接寻址。(4)寄存器间接寻址:指令中指出一个基址寄存器BX、BP或变址寄存器SI、DI,并以其内容做为操作数的有效地址,ADD AX,[BP]物理地址=10H×(SS)+(BP)。(5)寄存器相对寻址:指令中指出一个基址或变址寄存器,同时给出一个位移量, 寄存器内容与位移之和做为操作数的有效地址。MOV AX,[DI+100H],有效地址EA=(DI)+100H,为物理地址=10H×(DS)+(DI)+100H。(6)基址变址寻址:指令同时指出一个基址寄存器和一个变址寄存器,两寄存器内容的和为操作数的有效地址。ADD AX,[BX][SI],有效地址EA=(BX)+(SI)。物理地址=10H×(DS)+(BX)+(SI)。(7)相对基址变址寻址:指令中给出一个基址寄存器一个变址寄存器和一个位移量。两个寄存器的内容及位移量三者之和做为操作数的有效地址。例:MOV DX,100H [BX] [SI,物理地址=10H×(DS)+(BX)+(SI)+100H。 3.2 间接寻址方式转换为数组或指针 3.2.1 寄存器间接寻址转成一维数组来理解 形式:ADD AX,[BP]物理地址=10H×(SS)+(BP)。我们就可以认为,在此定义了一个数组SS,即SS中的值为这个数组的首地址,当然我们知道这个数组的最大元素个数为64K个。刚才谈到偏移量和数组下标都是从0开始的,所以偏移量BP就可以认为是这个数组的一个下标,在这寻址操作数的时候是要把这个下标作为一个内存地址,其所存储的内容就是我们所要找的操作数。 在数组中形如I=A[10]就是把A数组的第10个元素赋值给I,在ADD AX,[BP]语句中BP也有一个中括号,只是在这个地方省略了数组名;并且也是把SS数组的第BP个元素赋值给AX。 所以无论从形式还是从本质上就把寄存器间接寻址转换成了一个一维数组。 3.2.2 寄存器间接寻址转成指针来理解因为指针和数组有时间是可以相互转换的,所以在这也可以转换成指针来理解。 形式:ADD AX,[BP]物理地址=10H×(SS)+(BP)。BP在汇编语言中本身就定义为一个基址“指针”用来和堆栈段配对使用,其中存放的数据是堆栈段的某一个存储单元地址。这就和指针吻合了,前面说到指针变量名与地址间具有一一对应关系,在存取操作时是按变量的地址来进行的一种“间接存取”的方法。那么这个地方我们可以认为BP是一个指向堆栈段中某一个存储单元的C语言意义上的指针。 这样就把寄存器间接寻址方式可以理解成C语言意义上的指针。对于寄存器相对寻址、基址变址寻址、基址变址寻址我们也都 C语言中数组指针在汇编语言寻址方式中的应用 马耀锋 李红丽 (中州大学信息工程学院 河南郑州 450044) 摘要:因高级语言不需要熟悉低层软件和硬件知识,所以学生有很大的学习兴趣,数组指针是C 语言中的重点内容,学生们都能熟练掌握。而汇编语言因与硬件紧密相连,所以学生学习兴趣不大。为了更好的培养学生的学习兴趣,提高教学效率,本文通过分析数组指针与寻址方式的异同,提出了如何把寻址方式转化成数组指针来学习的方法。 关键词:数组 指针 寻址方式中图分类号:TP312.1-4文献标识码:A 文章编号:1007-9416(2012)04-0231-02 ??????下转第232页

C指针函数习题

C++指针函数习题 一、选择题 1.以下程序的运行结果是()。 sub(int x, int y, int *z) { *z=y-x; } void main() { int a,b; sub(10,5,&a); sub(7,a,&b); cout< #include<>

C语言指针用法详解

让你不再害怕指针 前言:复杂类型说明 要了解指针,多多少少会出现一些比较复杂的类型,所以我先介绍一下如何完全理解一个复杂类型,要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样,所以我总结了一下其原则: 从变量名处起,根据运算符优先级结合,一步一步分析. 下面让我们先从简单的类型开始慢慢分析吧: int p; //这是一个普通的整型变量 int *p; //首先从P处开始,先与*结合,所以说明P是一个指针,然后再与int结合, //说明指针所指向的内容的类型为int型.所以P是一个返回整型数据的指针int p[3]; // 首先从P处开始,先与[]结合,说明P是一个数组,然后与int结合, // 说明数组里的元素是整型的,所以P是一个由整型数据组成的数组int *p[3]; //首先从P处开始,先与[]结合,因为其优先级比*高,所以P是一个数组, //然后再与*结合,说明数组里的元素是指针类型, 然后再与int结合, //说明指针所指向的内容的类型是整型的,所以P是一个由返回整型数据 //的指针所组成的数组 int (*p)[3]; //首先从P处开始,先与*结合,说明P是一个指针,然后再与[]结合 //(与"()"这步可以忽略,只是为了改变优先级), 说明指针所指向的 //内容是一个数组,然后再与int结合, 说明数组里的元素是整型的. //所以P是一个指向由整型数据组成的数组的指针 int **p; //首先从P开始,先与*结合,说是P是一个指针,然后再与*结合, 说明指 //针所指向的元素是指针,然后再与int结合, 说明该指针所指向的元素 //是整型数据.由于二级指针以及更高级的指针极少用在复杂类型中, 所 //以后面更复杂的类型我们就不考虑多级指针了, 最多只考虑一级指针. int p(int); //从P处起,先与()结合,说明P是一个函数,然后进入()里分析,说明该 //函数有一个整型变量的参数,然后再与外面的int结合, 说明函数的 //返回值是一个整型数据 Int (*p)(int); //从P处开始,先与指针结合,说明P是一个指针,然后与()结合,

利用函数指针数组进行的键散转处理(4x4)

单片机 键盘接口电路 简介 Copyleft2009 by高飞电子经营部 P.S. 文档由高飞整理。能力有限,疏漏在所难免!这里说声抱歉了。 若对文档所描述的观点存在疑问,欢迎交流。 QQ:1275701567

键盘是单片机应用系统中不可缺少的输入设备,是实心人机对话的纽带,是操作人员控制干预单片机应用系统的主要手段。如用手机键盘发送短信息、遥控器键盘控制家用电器等。各种仪器仪表的小键盘系统,则可以显示各种信息。例如,数字式频率计、数字式扫频仪、数字式测量仪等。通过键盘向单片机应用系统输入数据和控制命令,实现对应用系统的认为控制,可以提高应用系统的灵活性。每种单片机应用系统的小键盘系统会实现不同的功能。比如,需要按键进行清零、预置值、改变测量范围等。这些功能是由一系列键盘电路通过编程实现的。因此,键盘在控制系统中得到了广泛的应用。本文档介绍了单片机系统中键盘接口电路及其相应的实现方式。 包含以下内容: ●键盘的组成和分类; ●键盘实现的硬件接口电路; ●4x4键盘与单片机的接口实例; ●二进制编码器键盘与单片机的接口实例。 1.1键盘设计的组成和分类 说说键盘的发展史。键盘发展至今,已经有100多年的时间。伴随着材料科学和电子技术的发展,键盘的物理构成和物理构造也不断变化发展。这些不同结构的键盘,各有特点,适用于不同的场合,但是控制方法都是类似的。 1.1.1键盘的物理结构 1.机械式结构键盘 机械式结构键盘,一般使用类似金属接触式开关的原理,实现触点导通或断开。在实际应用中,机械开关的结构形式很多。最常用的是交叉接触式。它的优点是结实耐用,缺点是不防水,敲击比较费力。交叉接触式机械开关,在单片机应用系统中最为常用。轻触开关也属于这一类。 2.电容式结构键盘 电容式结构键盘是一种类似电容式开关原理键盘。它通过按键改变电极的间距而产生电容量的变化,暂时形成震荡脉冲允许通过的条件。电容的容量是由介质、两极间的距离及两极的面积来决定的。当键帽按下时,两极的距离就发生变化,就引起电容容量发生变化。当参数设计合适时,按键时就有输出,而不按键就无输出。这个输出再经过整形放大,去驱动编码器。由于电容器无接触,所以这种按键在工作过程中不存在磨损、接触不良等问题,耐久性、灵敏度和稳定性都比较好。另外,为了避免电极间进入灰尘,电容式按键开关采用了密闭封装,比较便于保养。优良的特性带来的缺点就是代价高昂,标准PC键盘淘宝卖价不低于1500RMB!

C语言第十六讲(指针与函数)

指针与函数 1.掌握指针变量为参数在调用函数和被调用函数之间的数据传递。 2.掌握函数返回地址值的方法。 3.掌握指向函数的指针及其运算。 4.能熟练运用指针变量完成C程序的编写。 1. 指针变量作为参数时实现数据传递 2.指向函数的指针及运算 3.函数返回地址值的方法

(一)导课 在C语言函数调用中,参数传递可以是一般变量的传递,也可以是地址的传递(指针)。 (二)课程要点 一、指针变量作为函数的参数 使用指针类型做函数的参数,实际向函数传递的是变量的地址。【例1】定义一个函数,用指针变量作参数实现两个数据的交换。 #include void main() { void swap(int *pa,int *pb); int a,b; a=15;b=20; printf("before swap a=%d,b=%d\n",a,b); swap(&a,&b); printf("after swap a=%d,b=%d\n",a,b); }

void swap(int *pa,int *pb) { int t; t=*pa; *pa=*pb; *pb=t; } 其数据交换的变化过程如下图所示: 思考:将上面swap 函数作以下修改,a,b 的值是否发生了交换? void swap(int *pa,int *pb) { int *t; t=pa; pa=pb; pb=t; } 程序运行结果: before swap a=15,b=20 after swap a=20,b=15 程序运行结果: before swap a=15,b=20 after swap a=15,b=20

指针数组函数练习(含参考答案).

作业(使用指针、数组、函数完成) 1. 编写一个通用函数,该函数可以实现判断:一个含有五位数字的整数是否是回文数。回文数的含义是从左向右与从右向左看,数是相同的。如:23732是回文数,而23564则不是。编写主程序调用该函数实现求所有5位数字中满足条件的数的个数。 #include int Judge(long num { int m,t,h,s,g; m=num/10000; t=(num-m*10000/1000; h=(num-m*10000-t*1000/100; s=(num-m*10000-t*1000-h*100/10; g=num-m*10000-t*1000-h*100-s*10; if((m==g&&(t==s return 1; else return 0; } void main( { int count=0; long i; for(i=10000;i<=99999;i++ if(Judge(i count++; printf("%d\n",count;

} 2.编写一个通用函数,该函数可以实现对数值型数组的倒序。倒序的含义是把数组的元素值前后颠倒。例数组:20,19,18,15,13,10倒序的结果为:10,13,15,18,19,20。编写主程序,数组初始化方式不限,并输出,然后调用该函数实现倒序后再输出倒序的结果。 #include #define N 6 void Transfer(double *b,int n { double temp; double *i=b; double *j=b+n-1; while(j>i { temp=*i; *i=*j; *j=temp; i++; j--; } } void main( { double array[N]={20,19,18,15,13,10}; int i; for(i=0;i printf("%.0f\t",array[i];

函数指针和指针函数的理解

我知道函数指针是指向函数的指针,指针函数还是指一个函数的返回值是一个指针,但下面的几道题还是感觉很迷惑。各位能否讲的详细点呢? (1)float(**def)[10]def是什么? (2)double*(*gh)[10]gh是什么? (3)double(*f[10])()f是什么? (4)int*((*b)[10])b是什么? 这样老感觉有点乱,有什么窍门可以记得并理解的清楚一点么? (1)def是一个指针,指向的对象也是一个指针,指向的指针最终指向的是10个float构成的数组. (2)gh是指针,指向的是10个元素构成的数组,数组的元素是double*类型的指针. (3)f是10个元素构成的数组,每个元素是指针,指针指向的是函数,函数类型为无参数且返回值为double.下面要讲的窍门的例子跟这个很类似. (4)b是指针,指向的是10个元素构成的数组,数组元素为int*类型的指针. 窍门如下: 如果我们碰到复杂的类型声明,该如何解析它?例如: char(*a[3])(int); a到底被声明为什么东东?指针?数组?还是函数? 分析时,从a最接近(按运算符优先级)处开始。我们看到a最接近符号是[]——注意:*比[]的优先级低。a后既然有[],那么a是数组,而且是包含3个元素的数组。 那这个数组的每个元素是什么类型呢?虽然数组a只含有a[0]、a[1]、a[2]三个元素,a[3]实际上已经越界,但在分析数组a的元素的类型时,我们正好需要形式上的元素a[3]。知道了a[3]的类型,就知道了a的元素的类型。a[3]是什么类型?是指针,因为它的前面有*.由此可知,数组a的元素是指针。 光说是指针还不够。对于指针,必须说出它指向的东东是什么类型。它指向的东东是什么,就看*a[3]是什么(a[3]是指针,它指向的东东当然是*a[3])了。继续按优先级观察,我们看到*a[3]后面有小括号,所以可以肯定*a[3]是函数。即数组a的元素是指向函数的指针。 指向的是什么类型的函数?这很明显,是入参为int、返回值为char的类型的函数。 至此解析完毕。

C语言——指向函数的指针

1函数类型(* 函数指针变量)();//指向函数的入口地址 一个函数是若干语句的集合,经编译后存储在函数代码存储区,并占有一片连续的存储空间,对函数指针只能用函数名赋值而无其他运算 1#include 2 3int max(int x ,int y); 4 5int main() 6{ 7int(* p)() ;//定义p是指向函数的指针变量 8int a , b , c ; 9 10p= max ;//将函数max的入口地址赋给指针变量p 11scanf("%d %d",&a ,&b) ; 12c= (* p)(a , b) ;//用指向函数的指针变量p调用函数 13printf("a = %d , b = %d , max = %d", a , b , c); 14 15return0; 16} 17 18int max(int x ,int y) 19{ 20int k ; 21k= (x> y)? x : y ; 22 23return k ; 24} 函数名作为实际参数: 1 #include 2 3int fun1(int a , int b) 4 { 5return a+b ; 6 } 7 8int fun2(int (*q)() , int x , int y) 9 { 10return (*q)(x , y) ; 11 } 12 13int main() 14 { 15int (*p)() , k ; 16 p = fun1 ;

17 k = fun2( p , 8 , 5 ) ; 18 19printf("k = %d \n" , k); //输出 13 20 21return0 ; 22 } 设置一个函数proc ,每次调用它会实现不同的功能,输入 a , b 两个数,第一次调用proc时,找出两者中最大者,第二次找出最小者,第三次调用求两数之差: 1 #include 2 3int max(int *x , int *y); 4int min(int *x , int *y); 5int a_b(int *x , int *y); 6int proc(int *x , int *y , int(*p)()); 7 8int main() 9 { 10int a , b ; 11 12printf("Enter a and b :"); 13scanf("%d %d" , &a , &b); 14 15printf("a = %d \t b = %d \n" , a , b); 16 17printf("max(%d,%d) = " , a , b); 18 proc(&a , &b , max); 19 20printf("min(%d,%d) = " , a , b); 21 proc(&a , &b , min); 22 23printf("%d - %d = " , a , b); 24 proc(&a , &b , a_b); 25 26return0 ; 27 } 28 29int max(int *x , int *y) 30 { 31int k ; 32 33 k = (*x > *y) ? *x : *y ; 34 35return k ; 36 } 37 38int min(int *x , int *y)

指针与数组 函数的组合

指针和数组 ? ? 1.指针数组:是其数组元素为指针的数组。记住:是一个存放着指针的数组,而不是一个指针 ?定义格式为:数据类型* 数组名[数组长度] ?如:int * a[10] ; [ ]的优先级高于*,意味着使得a是一个指针数组,表示具有10个元素的数组,每个元素是一个指向int 型的指针。 ? ?2,指向数组的指针:是一个指针,指向的是一个数组。 ?定义格式为:数据类型(*数组名) [数组长度] ?如:int (*a) [10];*先于a 结合,意味着a 是一个指针,指向具有10个int 值的数组, ? ? ?指针与函数 ? ?1, 函数的指针:首先它是一个指针,指向函数的入口地址;在C语言中,函数名就是来标识函数的入口地址。 ?与指向数组的指针不同,在数组中,可以对数组中的元素访问,可以进行算术运算。 而在函数中,只需考虑函数的入口地址,而不考虑函数中某具体指令或数据所在存 储单元的地址,即不能进行算术运算 ?定义格式:存储类型数据类型(*函数名) ( ) ?如:static int (*p) (); ?存储类型表示函数在文件中的存储方式 ?数据类型表示被指函数的返回值的类型 ?最后的空括号表示指针变量所指的是一个函数 ? ?如何用指向函数的指针变量的方式来调用相应的函数: ?1), 使用前,必须先定义并赋值 ?2), 指向函数的指针定义形式中的数据类型必须和赋给它的函数返回值类型相同 ?3), 指向函数的指针只能指向函数的入口,而不能使用*(p+1) 来表示函数的下一命令?4), 在函数指针赋值时,只需给出函数名而不需给参数,如p = max; ?5), 调用时,只需将(*p) 代替函数名即可,在p 后面的括号中根据需要写上实参,如: c = (*p) (a,b) ; ?如下程序:求直角三角形的斜边 ?#include ? #include ?main() ?{ ? int a ,b ,c , f() , (*f1)(); ? a = 3; b = 4;

将0转型为“指向返回值为void的函数的指针” (void (x)())0

(void (*)())0 的含义 (void (*)())0 的含义: 1. fp是一个指针{有*},她指向返回值为void{有(void)}类型的函数{有()}:void (*fp)(); 调用方式简写为:(*fp)(); 2. 制作其对应的类型强制转换符:void (*)() 3. 存储位置为0 的强制转换为一个指向返回值为void类型的函数的指针:(void (*)())0 4. 用上式代替fp,从而实现调用存储位置为0的子例程:(*(void(*)())0)(); 5. 利用typedef简化:typedef void (*funcptr)(); (*(funcptr)0)(); (void (*)())0 的含义:实际上就是将地址0强制转换为一个指向返回值为void类型的函数的指针。 下面将相关基础知识进行介绍,其中参考了网上一些文章,名单不再列出,谢谢各位大虾的贡献: 1、c语言的声明 2、类型转换符的制作 3、signal函数分析 4、typedef用法 5、const用法 6、typedef的好处 1 C语言的声明 声明由两部分组成:类型以及声明符: float f,g; float ((f));//对其求值时,((f))的类型为浮点型,可以推知,f也是浮点型 float *g(),(*h)();//g是函数,该函数的返回类型为指向浮点数的指针 //h是个指针,且是一个函数指针,该指针指向函数返回值,该返回值是一个float型 (*fp)()简写为fp()//函数调用方式,其中fp为函数指针 *((*fp)())简写为*fp()//函数返回值为某个类型的指针 、2 类型转换符制作 类型转换符制作: 1、去掉声明中的变量名、分号; 2、将剩余部分用括号"封装"起来 float (*h)(); --> (float (*)())//指向返回值为float型的函数指针的类型转换符(*0)();//返回值为void类型的函数指针 如果fp是一个指向返回值为void类型的函数的指针,那么(*fp)()的值为 void,fp的声明如下:void (*fp)(); 因此可以用下式完成调用存储位置为0的子例程:void (*fp)(); (*fp)(); 这种写法的代价是多声明了一个哑变量,我们常将0转型为“指向返回值为void的函数的指针”:(void (*)())0 用上式代替fp,从而得到:(*(void(*)())0)(); typedef void (*funcptr)(); 将0转型为“指向返回值为void的函数的指针”-----(void (*)())0 (*(funcptr)0)(); 3 signal函数

C语言学习笔记之函数指针

C/C++学习笔记之函数指针 函数指针的概念,在潭浩强先生的《C语言程序设计》这本经典的教程中提及过,在大多数情况下我们使用不到,也忽略了它的存在。函数名实际上也是一种指针,指向函数的入口地址,但它又不同于普通的如int*、double*指针,看下面的例子来理解函数指针的概念:view plain int function(int x,int y); int main(void) { int(*fun)(int x,int y); int a=10,b=20; function(a,b); fun=function; (*fun)(a,b);…… } 第一行代码首先定义了一个函数function,其输入为两个整型数,返回也为一个整型数(输入参数和返回值可为其它任何数据类型);后面又定义了一个函数指针fun,与int*或double*定义指针不同的是,函数指针的定义必须同时指出输入参数,表明这是一个函数指针,并且*fun也必须用一对括号括起来;并将函数指针赋值为函数function,前提条件是*fun 和function的输入参数和返回值必须保持一致,否则无法通过编译。可以直接调用函数function(),也可以直接调用函数指针,二者是等效的。 回调函数(callback)是一个程序员不能显式调用的函数;通过将回调函数的地址传给调用者从而实现调用。简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。要实现回调,必须首先定义函数指针。尽管定义的语法有点不可思议,但如果你熟悉函数声明的一般方法,便会发现函数指针的声明与函数声明非常类似。请看下面的例子: void f();//函数原型 上面的语句声明了一个函数,没有输入参数并返回void.那么函数指针的声明方法如下:void(*)(); 函数存放在内存的代码区域内,它们同样有地址,我们如何能获得函数的地址呢? 如果我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,这一点如同数组一样,数组的名字就是数组的起始地址。 定义一个指向函数的指针用如下的形式,以上面的test()为例: int(*fp)(int a);//这里就定义了一个指向函数的指针 函数指针绝对不能指向不同类型,或者是带不同形参的函数,在定义函数指针的时候我们很容易犯如下的错误。 int*fp(int a);//这里是错误的,因为按照结合性和优先级来看就是先和()结合,然后变成了一个返回整型指针的函数了,而不是函数指针,这一点尤其需要注意! 例如函数原型为: int fun(int*,int); 则函数指针可以声明为:int(*pf)(int*,int);当然从上述例子看不出函数指针的优点,目的主要是想引出函数指针数组的概念。我们从上面例子可以得知,既然函数名可以通过函数指针加以保存,那们也一定能定义一个数组保存若干个函数名,这就是函数指针数组。正确使用函数指针数组的前提条件是,这若干个需要通过函数指针数组保存的函

实验一 函数-指针及其应用

实验一函数、指针及其应用 (一)函数的基本应用 一、实验目的 1.掌握函数声明、定义及调用的方法。 2.掌握函数实际参数与形式参数的对应关系以及数据的“值传递”方式。 3.掌握递归的思想和递归调用的一般方法。 4.学习编写简单的递归程序。 二、实验内容 1.验证性实验 (1)下列程序的执行结果是什么? #include "stdio.h" void change(int a,int b) { int t; t=a;a=b;b=t; } void main( ) { int x,y; printf("input x,y: "); scanf("%d,%d",&x,&y); change(x,y); printf("x=%d,y=%d\n",x,y); } 思考:为什么x与y的值没有互换? (2)下列程序的执行结果是什么? #include void exam1(int); void exam2(void); int a=0; void main(void) { int a; a=15; printf("a=%d\n",a); exam1(a); printf("a=%d\n",a); exam2( ); printf("a=%d\n",a); } void exam1( int a) { printf("\ta=%d\n",a);

a++; printf("\ta=%d\n",a); } void exam2(void) { printf("\ta=%d\n",a); a++; printf("\ta=%d\n",a); } 2.程序填空 (1)下列程序的功能是输出100~1000之间所有既能被3整除,又能被7整除的数。 #include void main() {int k; int sele(int n); for(k=100;k<=1000;k++) if( ① ) printf("%5d", ② ); printf("\n"); } int sele(int n) { if( ③ ) return (1); return 0 ; } (2)下列程序的功能是:prime()函数用于判别一个数是否为素数,在主函数输入一个整数,输出是否素数的信息。 #include void main() { int number; int prime(int number); printf("请输入一个正整数:\n"); scanf("%d",&number); if (prime(number)) printf("\n %d是素数. ",number); else printf("\n %d不是素数. ",number); } int prime(int num) /*此函数用于判别素数*/

C指针函数习题精编版

C指针函数习题 文件编码(008-TTIG-UTITD-GKBTT-PUUTI-WYTUI-8256)

C++指针函数习题一、选择题 1.以下程序的运行结果是()。 sub(intx,inty,int*z){ *z=y-x;} voidmain() { inta,b; sub(10,5,&a); sub(7,a,&b); cout<

C)p=&a;scanf(“%lf”,*p);D)p=&a;scanf(“%lf”,p); 6.若有语句int*point,a=4;和point=&a;下面均代表地址的一组选项是()。 A)a,point,*&aB)&*a,&a,*pointC)*&point,*point,&aD)&a,&*point,point 7.设char*s="\ta\103bc";则指针变量s指向的字符串所占的字节数是()。 A)9B)5C)6D)7 8.下面程序段的运行结果是()。 char*s="abcde";s+=2;cout< #include<> intmain() { char*s1="AbDeG"; char*s2="Abdeg"; s1+=2;s2+=2;

C++常量指针与指针常量_数组指针与指针数组_函数指针与指针函数

常量指针与指针常量 一) 常量指针。 常量是形容词,指针是名词,以指针为中心的一个偏正结构短语。这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针(变量)。 指针指向的对象是常量,那么这个对象不能被更改。 在C/C++中,常量指针是这样声明的: 1)constint *p; 2)intconst *p; 常量指针的使用要注意,指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改,也就是说常量指针可以被赋值为变量的地址,之所以叫做常量指针,是限制了通过这个指针修改变量的值。例如: int a = 5; constint b = 8; constint *c = &a; // 这是合法的,非法的是对c的使用 *c = 6; // 非法,但可以这样修改c指向的对象的值:a = 6; constint *d = &b; // b是常量,d可以指向b,d被赋值为b的地址是合法的 细心的朋友在使用字符串处理函数的时候,应该会注意到这些函数的声明。它们的参数一般声明为常量指针。例如,字符串比较函数的声明是这样的: intstrcmp(const char *str1, const char *str2); 可是这个函数却可以接收非常量字符串。例如这段程序: char *str1, *str2; str1 = "abcde1234"; str2 = "bcde"; if(strcmp(str1, str2) == 0) {printf("str1 equals str2.");} str1和str2的内容显然是可以更改的,例如可以使用“str1[0] = x;”这样的语句把str1的内容由“abcde1234”变为“xbcde1234”。因为函数的参数声明用了常量指针的形式,就保证了在函数内部,那个常量不被更改。也就是说,对str1和str2的内容更改的操作在函数内部是不被允许的。(就目前的应用来看,我觉得设置常量指针就是为函数参数声明准备的,不然还真不知道用在什么地方呢,呵呵!) 虽然常量指针指向的对象不能变化,可是因为常量指针是一个变量,因此,常量指针可以不被赋初始值,且可以被重新赋值。例如: constint a = 12;

C语言之指针数组函数

C语言之指针、数组和函数 基本解释 1、指针的本质是一个与地址相关的复合类型,它的值是数据存放的位置(地址);数组的本质则是一系列的变量。 2、数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。 3、当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。问题:指针与数组 听说char a[]与char *a是一致的,是不是这样呢? 答案与分析: 指针和数组存在着一些本质的区别。当然,在某种情况下,比如数组作为函数的参数进行传递时,由于该数组自动退化为同类型的指针,所以在函数内部,作为函数参数传递进来的指针与数组确实具有一定的一致性,但这只是一种比较特殊的情况而已,在本质上,两者是有区别的。请看以下的例子: char a[] = "Hi, pig!"; char *p = "Hi, pig!"; 上述两个变量的内存布局分别如下: 数组a需要在内存中占用8个字节的空间,这段内存区通过名字a来标志。指针p则需要4个字节的空间来存放地址,这4个字节用名字p来标志。其中存放的地址几乎可以指向任何地方,也可以哪里都不指,即空指针。目前这个p 指向某地连续的8个字节,即字符串“Hi, pig!”。 另外,例如:对于a[2]和p[2],二者都返回字符‘i’,但是编译器产生的执行代码却不一样。对于a[2],执行代码是从a的位置开始,向后移动2两个字节,然后取出其中的字符。对于p[2],执行代码是从p的位置取出一个地址,在其上加2,然后取出对应内存中的字符。 问题:数组指针 为什么在有些时候我们需要定义指向数组而不是指向数组元素的指针?如何定义? 答案与分析: 使用指针,目的是用来保存某个元素的地址,从而来利用指针独有的优点,那么在元素需要是数组的情况下,就理所当然要用到指向数组的指针,比如在高维需要动态生成情况下的多维数组。 定义例子如下: int (*pElement)[2]。 下面是一个例子: int array[2][3] = {{1,2,3},{4,5,6}}; int (*pa)[3]; //定义一个指向数组的指针 pa = &array[0]; // '&'符号能够体现pa的含义,表示是指向数组的指针printf ("%d", (*pa)[0]); //将打印array[0][0],即1 pa++; // 猜一猜,它指向谁?array[1]?对了! printf ("%d", (*pa)[0]); // 将打印array[1][0],即4 上述这个例子充分说明了数组指针—一种指向整个数组的指针的定义和使用。

相关主题
文本预览
相关文档 最新文档