• 指针难点——数组指针、指针数组、函数指针、指针函数详解


    1.指针

    1.1指针数组和数组指针

    • 指针数组是一个数组,数组里面存放的内容是指针
      在这里插入图片描述

    int *arr[10]

    #include
    int main()
    {
    	int a = 10;
    	int b = 11;
    	int c = 12;
    	int* q = &a;
    	int* p = &b;
    	int* l = &c;
    	int* arr[] = { p,q,l };
    	for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
    	{
    		cout << *(arr[i]) << endl;
    	}
    	return 0;
    }
    
    • 数组指针是一个指针,这个指针指向的对象是一个数组,经常用于二维数组

    int (*arr)[10]

    #include
    int print(int(*arr)[10])
    {
    
    }
    int main()
    {
    	int brr[10][10] = {0};
    	print(brr);
    
    	
    	return 0;
    }
    
    • 注意 其本身是一个运算符优先级问题,可以使用右左法则来分辨两者怕(后文会讲)

    2.右左法则

    • 常用于区分指针数组和数组指针,用法如下
    1. 首先找到变量名,将变量名与右边内容结合,判断是指针还是数组,如果变量名带有括号,先算括号里的。
    2. 右边的看一个,再向左看一个,将内容往前写,直至左右一方没有了,再一次写下另一方
    • 可能比较抽象,我举个例子就好了
      int *(*p[3])(int) 是一个 指针函数指针数组,是一个存放指针的数组,数组中的指针指向的是参数为int类型的函数
    int  *(*p[3])(int)
    1.先找到变量名 p
    2.p右边是[]说明是一个数组                             数组
    3.p左边是一个指针                                  指针数组
    4.右边是一个函数                                函数指针数组
    5.左边是一个指针                            指针函数指针数组
    

    3.函数指针和指针函数

    • 函数指针是一个指针,它指向的是函数的首地址(函数名)
    • 指针函数是一个函数,返回值类型是一个指针

    示例1

    int (*fn(int n))(int,int)
    fn是个函数名,里面有int n参数,fn函数的返回值是个指针,这个指针指向函数int xx(int,int)此类函数

    • 回调函数
      函数指针的一个非常典型的应用就是回调函数。回调函数就是一个通过指针函数调用的函数。其将函数指针作为一个参数,传递给另一个函数。回调函数并不是由实现方直接调用,而是在特定的事件或条件发生时由另外一方来调用的。
    int max(int a,int b)
    {
    	return a > b ? a : b;
    }
    int min(int a,int b)
    {
    	return a < b ? a : b;
    }
    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 (*fn(int n))(int,int)
    {
    	return max;
    }
    void print(int n)
    {
    	cout<<"print n = "<<n<<endl;
    }
    void (*fnn(int n,int (*p)(int,int)))(int)
    {
    	cout<<"fnn : n = "<<n <<","<< p(6,9)<<endl; //max(6,9)
    	return print;
    }
    void main()
    {
    	void (*p)(int)  = fnn(5,max); //p = print
    	p(100);//print(100)
    }
    
    

    上面代码函数有加减乘除,求最大最小值,从主函数开始分析,首先调用fnn函数,fnn函数两个参数分别为一个整形和一个函数指针,所以将max函数名传进去当作参数,形参p指向max函数,比较6,9的大小,返回print函数

    void (*fnn(int n,int (*p)(int,int)))(int)
    {
    	cout<<"fnn : n = "<<n <<","<< p(6,9)<<endl; //max(6,9)
    	return print;
    }
    

    (*p)(int)是一个函数指针,指向刚刚返回的print函数,调用print(100),打印100

    在这里插入图片描述

    void print(int n)
    {
    	cout<<"print n = "<<n<<endl;
    }
    

    示例2

    void main()
    {
    	int (*p[])(int,int) = {max,min,Add,Sub,Mul,Div,Mod};
    	int n = sizeof(p)/sizeof(p[0]);
    	for(int i = 0;i<n;++i)
    		cout<<p[i](4,9)<<endl;
    }
    

    在这里插入图片描述

    • max,min,Add,Sub,Mul,Div,Mod这几个函数都是同一类型的,至少都有两个相同类型的参数,可以定义一个函数指针数组来存放函数指针,分别指向这几个函数,这样在使用是可以当做数组使用非常方便,而且也方便更新。

    示例3(面试题)

    void mymalloc(char *p,int n)
    {
    	*p = (char*)malloc(n);
    }
    void main()
    {
    	char *str = NULL;
    	mymalloc(str,100);
    	strcpy(str,"hello world");
    	puts(str);
    	free(str);
    	str = NULL;
    }
    

    以上代码能否完成malloc函数的功能?
    答案: 不能,要改变一级指针内容传参时候必须传入二级指针,这样才能修改一级指针的内容

  • 相关阅读:
    用一段爬虫代码爬取高音质音频示例
    Springboot 3.0之Spring Native初体验
    求生之路2服务器搭建插件安装及详细的游戏参数配置教程linux
    技术学习:Python(10)|操作Excel
    BBR 数学模型直观展示
    蚂蚁二面,面试官问我零拷贝的实现原理,当场懵了…
    RabbitMQ详情
    解析Flutter应用在iOS环境中的性能优化技巧
    树莓派系统文件解析
    React Hook实现多列picker-view组件
  • 原文地址:https://blog.csdn.net/weixin_57154303/article/details/127095386