精华内容
下载资源
问答
  • 指针数组 首先从名字就可以知道这是一个数组,是存放指针的数组。 先看几种指针数组: int * 数组指针 函数指针 函数指针数组 指向函数指针数组的指针

    指针数组

    首先从名字就可以知道这是一个数组,是存放指针的数组。
    先看几种指针数组:
    int *arr1[10];
    char *arr2[5];
    char **arr3[6];
    因为 [ ] 的优先级是高于 * 的,所以数组名会先于 [ ] 相结合组成数组。 再于 int * / char *类型结合,组成存放该类型的数组。



    指针数组因为存放的都是指针所以不管是 int *   char * 还是 char ** 其大小都是四个字节。

    数组指针

    从名字看就知道是指针,是指向一个数组的指针。

    int (*p)[10];
    char (*p)[10];
    由数组指针知道 [ ] 的优先级是高于 *  的,所以用()来提升指针先结合。

    int (*p)[10];  //  是一个指向10个整形的一维数组的指针
    char (*p)[10]; //  是一个指向10个字符型的一维数组的指针

    数组的存储方式



    因为指向的是一个数组,所以大小由数组决定


    函数指针

    指向函数的指针,通俗的说也就是函数的地址
    void(*pfun)();
    pfun 先和*结合,说明pfun是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void
    也就是说 其可以保存函数的地址



    函数指针数组

    int (*parr[3])();
    parr先与 [ ]结合,说明是一个数组,再与*结合,说明数组存放的是指针,指针都指向的是函数
    函数指针数组的使用(转移表)
    例子:计算器
    #include<stdio.h>
    
    int add( x, y)
    {
    	return x + y;
    }
    int sub(x,y)
    {
    	return x - y;
    }
    int mul(x,y)
    {
    	return x * y;
    }
    int div(x,y)
    {
    	return x / y;
    }
    int main()
    {
    	int x, y;
    	int input = 1;
    	int ret = 0;
    	int(*parr[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
    	while (input)
    	{
    		printf("*******************************\n");
    		printf("***** 1.add         2.sub *****\n");
    		printf("***** 3.mul         4.div *****\n");
    		printf("*******************************\n");
    		printf("请选择:");
    		scanf("%d", &input);
    		if ((input > 0 && input < 5))
    		{
    			printf("输入你要计算的数:\n");
    			scanf("%d  %d", &x, &y);
    			ret = (*parr[input])(x, y);
    		}
    		else
    			printf("输入有误!\n");
    		printf("%d\n", ret);
    	}
    	return 0;
    }
    输出结果:


    指向函数指针数组的指针 

    这是一个指针,指向一个数组,这个数组是一个函数指针数组,数组中的元素都是函数指针

    定义方式:

    #include<stdio.h>
    void test(const char *str)
    {
    	printf("%s\n", str);
    }
    int main()
    {
    	void (*pfun)(const char*) = test;
    	//函数指针pfun
    	void (*pfunArr[5])(const char* str);
    	//函数指针的数组pfunArr
    	void (*(*ppfunArr)[10])(const char* str) = &pfunArr;
    	//指向函数指针数组pfunArr的指针ppfunArr
    	return 0;
    }




    展开全文
  • 函数指针的作用

    千次阅读 2018-11-02 18:30:58
    函数指针的作用二: 一是作为参数传递给另一个函数; 二是转换表。 1、函数指针作为参数传递给另一个函数 回调函数:将一个函数指针作为参数传递给其它函数。后者将“回调”用户函数。 实例:实现一个与类型无关的...

    函数指针的作用

    函数指针的作用有二:
    一是作为参数传递给另一个函数;
    二是转换表。

    1、函数指针作为参数传递给另一个函数
    回调函数:将一个函数指针作为参数传递给其它函数。后者将“回调”用户函数。

    实例:实现一个与类型无关的查找函数(单链表)

    思考:单链表的元素类型可能是字符串或者数组,数组和字符串无法作为参数传递给函数,但是指向他们的指针却可以。
    要求:需要查找函数作用于任何类型的值
    解决办法:把参数类型声明为 void * , 表示“一个指向未知类型的指针”。

    回调函数如下:

    int compare(void const *a, void const *b){
    	if ( *(int *)a == *(int *)b )return 0;//相等,返回0
    	else return 1;//1:表示 a>b
    }
    

    单链表查找函数如下:

    // 回调函数(比较函数)的完整的原型声明: int(*compare)(void const *, void const *))
    Node *search_list(Node *node, void const *value, int(*compare)(void const *, void const *)){
    	while (node != NULL){
    		if ( compare( &node->value, value) == 0) break;// 调用回调函数compare()
    		node = node->next;
    	}
    	return node;
    }
    

    测试中可以使用我的另一个博客: “C++使用数组构造链表” 来实现 链表的构造和显示
    测试结果:
    在这里插入图片描述
    字符串为链表元素:未完待续…

    2、函数指针作为转换表

    包括两步:
    step1:声明状态转移函数、声明并初始化函数指针数组
    step2:调用 函数指针数组

    (1)声明状态转移函数、声明并初始化函数指针数组
    (1.1)声明 状态转移函数

    double add(double, double);
    double sub(double, double);
    double mul(double, double);
    double div(double, double);
    double xiebianchang(double, double);
    

    (1.2)声明并初始化一个函数指针数组
    pfunc:数组
    数组元素:函数指针
    返回值:double型数据

    double(*pfunc[])(double, double) = { add, sub, mul, div, xiebianchang };//5个转移状态
    

    (2)调用 函数指针数组

    double result= pfunc[i](a,b);
    // i:表示 add(0),sub(1),mul(2),div(3),xiebianchang(4); 
    // a:形参1,b:形参2
    

    测试代码:

    #include<iostream>
    #include<cmath>
    using namespace std;
    
    // 转换表
    // 转换表 step1:
    //(1.1)声明 转台转移函数
    double add(double, double);
    double sub(double, double);
    double mul(double, double);
    double div(double, double);
    double xiebianchang(double, double);
    //(1.2)声明并初始化一个函数指针数组    pfunc:数组   数组元素:函数指针  返回值:double型数据
    double(*pfunc[])(double, double) = { add, sub, mul, div, xiebianchang };//5个转移状态
    
    //状态转移函数的实现
    double add(double a, double b){	return a + b;}
    double sub(double a, double b){ return a - b; }
    double mul(double a, double b){ return a*b; }
    double div(double a, double b){ return a / b; }
    double xiebianchang(double a, double b){ return sqrt(pow(a, 2) + pow(b, 2)); }
    
    void test(){
    	//转换表 step2:调用 函数指针数组
    	int n = sizeof(pfunc) / sizeof(pfunc[0]);//转移表中 包含的元素个数(状态转移函数个数)
    	for (int i = 0; i < n; ++i){
    		cout << pfunc[i](3, 4) << endl;
    	}
    }
    int main(){
    	test();
    	return 0;
    }
    

    在这里插入图片描述

    展开全文
  • 函数指针和指针函数用法和区别

    万次阅读 多人点赞 2018-05-24 08:11:10
    函数指针和指针函数,在学习 C 语言的时候遇到这两个东西简直头疼,当然还有更头疼的,比如什么函数指针函数、指针函数指针、数组指针、指针数组、函数指针数组等等,描述越长其定义就越复杂,当然理解起来就越难,...

    前言

    函数指针和指针函数,在学习 C 语言的时候遇到这两个东西简直头疼,当然还有更头疼的,比如什么函数指针函数、指针函数指针、数组指针、指针数组、函数指针数组等等,描述越长其定义就越复杂,当然理解起来就越难,特别是刚开始学习这门语言的童鞋,估计碰到这些东西就已经要崩溃了,然后好不容易死记硬背下来应付考试或者面试,然后过了几天发现,又是根本不会用,也不知道该在哪些地方用,这就尴尬了。
    今天这里只讲两个相对简单的,其实上面说那些太复杂的东西也真的很少用,即便是用了理解起来很麻烦,所以莫不如先深刻理解这两个比较容易的,并且项目中比较常用到。

    正文

    先来看看两者的定义以及说明。

    指针函数

    定义

    指针函数,简单的来说,就是一个返回指针的函数,其本质是一个函数,而该函数的返回值是一个指针。
    声明格式为:*类型标识符 函数名(参数表)

    这似乎并不难理解,再进一步描述一下。
    看看下面这个函数声明:

    int fun(int x,int y);
    

    这种函数应该都很熟悉,其实就是一个函数,然后返回值是一个 int 类型,是一个数值。
    接着看下面这个函数声明:

    int *fun(int x,int y);
    

    这和上面那个函数唯一的区别就是在函数名前面多了一个*号,而这个函数就是一个指针函数。其返回值是一个 int 类型的指针,是一个地址。

    这样描述应该很容易理解了,所谓的指针函数也没什么特别的,和普通函数对比不过就是其返回了一个指针(即地址值)而已。

    指针函数的写法

    int *fun(int x,int y);
    int * fun(int x,int y);
    int* fun(int x,int y);
    

    这个写法看个人习惯,其实如果*靠近返回值类型的话可能更容易理解其定义。

    示例

    (由于本人习惯于 Qt 中进行开发,所以这里为了方便,示例是在 Qt 工程中写的,其语法是一样的,只是输出方式不同)
    来看一个非常简单的示例:

    typedef struct _Data{
        int a;
        int b;
    }Data;
    
    //指针函数
    Data* f(int a,int b){
        Data * data = new Data;
        data->a = a;
        data->b = b;
        return data;
    }
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        //调用指针函数
        Data * myData = f(4,5);
        qDebug() << "f(4,5) = " << myData->a << myData->b;
    
        return a.exec();
    }
    
    

    输出如下:

    f(4,5) =  4 5
    

    注意:在调用指针函数时,需要一个同类型的指针来接收其函数的返回值。
    不过也可以将其返回值定义为 void*类型,在调用的时候强制转换返回值为自己想要的类型,如下:

    //指针函数
    void* f(int a,int b){
        Data * data = new Data;
        data->a = a;
        data->b = b;
        return data;
    }
    
    调用:
    Data * myData = static_cast<Data*>(f(4,5));
    

    其输出结果是一样的,不过不建议这么使用,因为强制转换可能会带来风险。

    函数指针

    定义

    函数指针,其本质是一个指针变量,该指针指向这个函数。总结来说,函数指针就是指向函数的指针。
    声明格式:类型说明符 (*函数名) (参数)
    如下:

    int (*fun)(int x,int y);
    

    函数指针是需要把一个函数的地址赋值给它,有两种写法:

    fun = &Function;
    fun = Function;
    

    取地址运算符&不是必需的,因为一个函数标识符就表示了它的地址,如果是函数调用,还必须包含一个圆括号括起来的参数表。

    调用函数指针的方式也有两种:

    x = (*fun)();
    x = fun();
    

    两种方式均可,其中第二种看上去和普通的函数调用没啥区别,如果可以的话,建议使用第一种,因为可以清楚的指明这是通过指针的方式来调用函数。当然,也要看个人习惯,如果理解其定义,随便怎么用都行啦。

    示例

    int add(int x,int y){
        return x+y;
    }
    int sub(int x,int y){
        return x-y;
    }
    //函数指针
    int (*fun)(int x,int y);
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        //第一种写法
        fun = add;
        qDebug() << "(*fun)(1,2) = " << (*fun)(1,2) ;
    	//第二种写法
        fun = &sub;
        qDebug() << "(*fun)(5,3) = " << (*fun)(5,3)  << fun(5,3);
    
        return a.exec();
    }
    
    

    输出如下:

    (*fun)(1,2) =  3
    (*fun)(5,2) =  2 2
    

    上面说到的几种赋值和调用方式我都分别使用了,其输出结果是一样的。

    二者区别

    通过以上的介绍,应该都能清楚的理解其二者的定义。那么简单的总结下二者的区别:

    定义不同

    指针函数本质是一个函数,其返回值为指针。
    函数指针本质是一个指针,其指向一个函数。

    写法不同

    指针函数:int* fun(int x,int y);
    函数指针:int (*fun)(int x,int y);
    可以简单粗暴的理解为,指针函数的*是属于数据类型的,而函数指针的星号是属于函数名的。
    再简单一点,可以这样辨别两者:函数名带括号的就是函数指针,否则就是指针函数。

    用法不同

    上面已经写了详细示例,这里就不在啰嗦了。

    总而言之,这两个东西很容易搞混淆,一定要深入理解其两者定义和区别,避免犯错。

    另外,本文都是针对普通函数指针进行介绍,如果是C++非静态成员函数指针,其用法会有一些区别,在另外一篇博客中单独介绍,文章在这里

    展开全文
  • 什么函数指针?(理解及使用)

    万次阅读 多人点赞 2019-05-09 18:36:17
    思维导图 1. 定义: char* fun1(char* p1, char* p2)// 1 char** fun2(char* p1, char* p2);...很简单,char*是返回类型,fun1是函数名,括号内是参数 和1相似,char** 是返回类型 ...

    思维导图

    在这里插入图片描述

    1. 定义:

    	char* fun1(char* p1, char* p2)// 1
    	char** fun2(char* p1, char* p2);// 2
    	char*(*fun3)(char* p1, char* p2);// 3
    

    1,2,3分别是什么意思呢?

      1. 很简单,char*是返回类型,fun1是函数名,括号内是参数
      1. 和1相似,char** 是返回类型
      1. 就是我们要讲的函数指针,看下面的例子:
    	int (*) [10]p//数组指针
    

    是不是和数组指针特别的相似?这里的fun3不是函数名,是指针变量,它指向一个函数。
    函数指针的定义就是,一个指向函数的指针

    2. 例子

    我们上面定义了一个函数指针,那我们该如何使用它呢?

    int Add(int a, int b)
    {
    	return a + b;
    }
    
    int main()
    {
    	int(*fun1)(int a, int b);
    	fun1 = &Add;
    	cout << (*fun1)(1, 2) << endl;//使用函数指针
    	cout << fun1(1, 2) << endl;//可以直接使用fun1
    
    	system("pause");
    	return 0;
    
    }
    

    我们在使用指针的时候,需要通过钥匙“ * ”来取其指向的内存的值,函数指针使用也如此。通过用(*fun1)取出该地址的函数然后调用他。也可以直接使用fun1,因为函数名被编译后其实就是一个地址。

    3.(* (void(*))()0)()

    让我们来看看 《C的陷阱与缺陷》中的经典例题

    • 1.void(*),可以明白这是一个函数指针类型。这个函数没有参数,没有返回型
    • 2.(void(*)())0,这是将0强制类型转换为函数指针类型,0是一个地址,也就是说函数存在首地址为0的一段区域内。
    • 3.(* (void(*)())0)这里是取0地址开始的一段内存的内容,其内容就是保存在首地址为0的一段区域的函数
    • 4.(* ( void(*))()0)() 这里是函数调用

    4.函数指针数组

    	char* (*fun[3])(char* p);//函数指针数组
    

    它是一个数组,数组名是fun,数组内存了3个指向函数的指针。这些指针指向的一些返回值类型为指向字符的指针,参数为一个指向字符指针的函数。

    5.函数指针数组的指针

    我一开始看到这东西我脑子里都是???,然后查了些博客啥的就弄清楚了。我们都知道什么事数组指针,套用数组指针的理解来理解函数指针数组不就好了吗?

    char* (*(*fun)[3]))(char* p);
    
    • 1.(*fun),是一个指针。
    • 2.(*fun)[3],表示这个指针指向一个包含三个元素的数组
    • 3.去掉(* fun)[3],看上面的例子,char* (* )(char* p),可以知道数组中的三个元素是返回类型为char*型的,参数为指向字符串的函数。
    展开全文
  • 指针函数和函数指针

    万次阅读 多人点赞 2019-03-30 16:21:36
    很多人因为搞不清这两个概念,干脆就避而远之,我刚接触C语言的时候对这两个概念也比较模糊,特别是当指针函数、函数指针函数指针变量、函数指针数组放在一块的时候,能把强迫症的人活活逼疯。 其实如果理解了这些...
  • 分析函数指针及其两个主要用途

    万次阅读 多人点赞 2018-05-22 22:02:27
    0.基本的函数指针的声明与初始化 首先我们来声明一个函数。int Max_Int(int a, int b) { return (a&gt;b)?a:b; }  把函数名替换成指针表达式是创建指向函数指针最简单的方式:int (*pFun)(int a, int b); //...
  • 1.通过函数名调用函数和通过函数指针调用函数有什么区别呢? 首先函数名、函数指针都表示代码段的起始地址。 1)调用函数的时候必须指定函数名,可是当时候不确定具体调用哪个函数,当某些事件发生后才确定...
  • 详解C语言指针函数、函数指针函数指针数组

    万次阅读 多人点赞 2018-07-09 11:08:24
    而在指针中,指针函数、函数指针、指针函数数组、函数指针数组、指向函数指针数组的指针等等概念看着又绕又头疼。本问总结了一下以上一些概念以及用法,并给出例程深化理解。 1. 指针函数 指针函数就是返回指针值...
  • 函数指针的作用以及好处

    千次阅读 2016-08-21 00:44:35
    //函数指针使用的例子#include #include char * fun(char * p1,char * p2) {  int i = 0;  i = strcmp(p1,p2);  if (0 == i)  {  return p1;  }  else  {  return p2;  } } int main() {  char *...
  • C++函数指针、指针函数、返回值为函数指针的函数浅谈 引言 函数指针、指针函数是C中重要而容易混淆的概念,博主将通过两个实例来说明这两个...定义了一个函数指针add,用于指向返回值为int,并且两个int参数的函数...
  • C++函数指针的使用和好处

    千次阅读 2018-11-16 17:12:08
    的通用函数中要涉用到另一个函数,但函数名称未定,是让用户编的, 当然要做成函数指针, 如果通用定积分计算,被计算函数是待定的,是由调用者确定的函数; 通用排序函数也是,比较函数与交换函数也是让用户...
  • 函数指针的好处、作用

    万次阅读 多人点赞 2013-12-06 00:29:00
    C中函数指针的作用  项目中用到了很多封装在struct中的函数指针,以前在MFC里面经常用到则个作为回调函数,还以为是微软设计的特色呢。在网上查了一下它的用法,做个总结。   1)提供调用的灵活性。设计好了...
  • c语言的函数指针和void *指向函数

    千次阅读 2018-08-22 14:52:12
    /* 首先要先理解两个类型的... 这个也是一个函数指针,函数参数个int 来看看void*类型: void *fun; 这样定义看起来很抽象,没有,对于没有过空类型的同学来说, 这样定义确实会让人一脸...
  • 如何用函数指针调用函数

    千次阅读 2020-07-10 09:23:48
    先举一个用函数指针调用函数的例子 int Func(int x); /*声明一个函数*/ int (*p) (int x); /*定义一个函数指针*/ p = Func; /*将Func函数的首地址赋给指针变量p*/ int Func(int x); 这一句是声明一个函数,使我们...
  • 函数指针函数指针类型

    千次阅读 2018-09-29 08:48:59
    每一个函数都占用一段内存单元,它们一个起始地址,指向函数入口地址的指针称为函数指针。 注意:函数指针的本质是一个指针变量,且指针指向的函数的入口地址 2. 语法 指向函数的指针变量的一般定义形式为: ...
  • 函数指针

    千次阅读 2019-06-05 17:21:03
    函数指针指向的函数而非对象。与其他指针一样,函数指针也指向特定的类型。函数的类型是由返回值和参数列表决定,与函数名无关。例如: //比较两个字符串的长度 bool lenghtCompare(const string &s1, const ...
  • 函数指针
  • C++虚函数指针虚函数表

    千次阅读 多人点赞 2017-07-10 22:25:57
    实现函数的动态联编其本质核心则是虚表指针与虚函数表。   1. 虚函数与纯虚函数区别 1)虚函数在子类里面也可以不重载的;但纯虚必须在子类去实现 2)带纯虚函数的类叫虚基类也叫抽象类,这种基类不能直接生成对象...
  • 详解函数指针和类成员函数指针

    千次阅读 多人点赞 2017-11-12 21:35:56
    我觉得要理解这个问题,以及要理解后面的函数指针和类成员函数指针,没有什么比从计算机原理的角度来理解更容易了。这里就简要回顾一下相关知识。 众所周知,计算机(图灵机)执行程序的基本流程就是:取指令->执行...
  • C++类成员函数指针使用介绍

    万次阅读 多人点赞 2019-09-21 16:07:49
    在之前写过的博客中介绍过函数指针和指针函数的区别和简单用法(文章在这里),当时的Demo非常简单,都是C语言的写法,但是当在C++中直接像C那样使用类成员函数指针时就会报错:reference to non-static member ...
  • 使用 typedef 定义函数指针,更优雅的使用函数指针

    万次阅读 多人点赞 2018-08-24 09:23:56
    关于函数指针的介绍,这里就不做过多说明了,不了解的同学可以看看这篇博客: https://blog.csdn.net/afei__/article/details/80549202   使用 typedef 定义函数指针 通过下面这个例子,我们看看 typedef 是...
  • c语言函数指针_指针函数_返回值是函数指针

    千次阅读 多人点赞 2019-03-06 17:38:43
    用函数指针作为函数的返回值 1.指针函数的定义 顾名思义,指针函数即返回指针的函数。其一般定义形式如下: 类型名 *函数名(函数参数表列); 其中,后缀运算符括号“()”表示这是一个函数,其前缀运算符星号“*”...
  • C++ 类成员函数的函数指针

    万次阅读 多人点赞 2018-08-23 18:40:17
    当我们在 C++ 中直接像 C 那样使用类的成员函数指针时,通常会报错,提示你不能使用非静态的函数指针: reference to non-static member function must be called 两个解决方法: 把非静态的成员方法改成静态的...
  • 指针函数和函数指针的理解与应用

    千次阅读 多人点赞 2019-02-11 13:11:01
    指针函数 指针函数, 即返回值为指针函数, 本质上是一个函数, 我们先看下面实例: #include &amp;lt;stdio.h&amp;gt; #include &amp;lt;time.h&amp;gt; int year; int mon; int day; ...
  • 一个函数名为fun的函数,它两个形参x1和x2,并且定义x1和x2为指向函数指针变量。在调用fun函数时,实参的两个函数名为f1和f2,这样给fun形参传递的就是f1和f2函数的入口地址。如此在fun函数中就可以调用f1和f2...
  • 就像自定义数据类型一样,我们也可以先定义一个函数指针类型,然后再这个类型来申明函数指针变量。 我先给你一个自定义数据类型的例子。 typedef int* PINT; //为int* 类型定义了一个PINT的别名 int main
  • 函数指针函数指针数组,函数指针数组的指针

    千次阅读 多人点赞 2017-11-27 11:39:51
    数组指针 概念:数组指针指针,只要是指针他就占4个字节; 例如: 整形指针:int *p;能够指向整形数据的指针  浮点型指针:float *p;能够指向浮点型的数据的指针 那么数组指针,同样的理解就是指向数组的指针...
  • C语言 函数指针和指针函数用法

    千次阅读 2020-04-03 13:43:36
    函数指针和指针函数,在学习 C 语言的时候遇到这两个东西简直头疼,当然还有更头疼的,比如什么函数指针函数、指针函数指针、数组指针、指针数组、函数指针数组等等,描述越长其定义就越复杂,当然理解起来就越难,...
  • C语言中函数指针和回调函数的详解

    万次阅读 多人点赞 2019-05-18 23:10:01
    函数指针:指向函数的指针变量。 因此“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如指针变量可指向整型变量、字符型、数组一样,这里是指向函数。...函数指针有两个用途:调用函数和做函数...
  • 因为函数的类型由它的返回类型和形参类型共同决定,与函数名无关,所以想要声明一个函数指针,只需要指针替换函数名即可,例如:比较字符串长度的函数:bool LengthCompare(const string &amp;, const string ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,384,228
精华内容 553,691
关键字:

函数指针有什么用