C - 函数指针 + 多级指针

这篇博客是关于C语言的备忘,重点讨论了函数指针的声明、定义初始化、回调函数的应用,以及多级指针在处理字符串时的作用。通过实例说明了为何需要二级指针以及如何使用它们来交换内存地址,从而实现数据的正确操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言–备忘



一、C 函数指针

1. 声明:

// 形式一:对函数指针取别名叫做 pfunc_t
typedef int (*pfunc_t) (int a,int b);

// 形式二:函数指针 pfunc 就是一种数据类型
int (*pfunc) (int a,int b);

2. 定义初始化:

 // 定义:pfunc就是一个函数指针变量,将来保存函数的地址
pfunc_t pfunc;  

// 初始化:初始化函数指针变量,指向add函数
pfunc_t pfunc=add; 

3. 回调:

  1. 回调函数:一个函数可以当成一个参数传递给其他函数 ,这个函数的 参数 必须是函数指针,但是函数的参数必须是函数指针来保存回调函数的地址(add);
typedef int (*pfunc_t)(int a,int b);//pfunc_t就是函数指针
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 main(void)
{
    pfunc_t func_all[]={add,sub,mul,div,NULL};//函数指针数组
    for(pfunc_t *func_start=func_all;*func_start;func_start++)//函数指针数组指针
    {
            int ret=(*func_start)(100,200);//函数名
    }
    return 0;
}

4. 应用举例:

typedef int (*pfunc_t)(int a,int b);//pfunc_t就是函数指针

int add(int a, int b)
{
    return a+b;
}
//定义调用函数,pfunc_t 为函数指针,请输入函数首地址
int cal(int a,int b,pfunc_t pfunc) 
{
    return pfunc(a,b);//调用pfunc函数
}

int main(void)
{
    int ret=0;
    pfunc_t pfunc=NULL; 	// 声明指针并清空
    pfunc=add;				// 指针直接指向函数
    ret= pfunc(100,200);	// 取代 add 函数名称
    
    ret=cal(100,200,add);//回调函数
    printf("a+b=%d\n",ret);
    return 0;
}

二、C 多级指针【一般字符串使用】

定义:指向一级指针的指针,也就是存放一级指针变量的地址;

int a=250;
int *p=&a;
int **pp=&p;
printf("p的地址是%p,a的地址是%p,a的值是%d",pp,*pp,**pp);

在这里插入图片描述

1. 为什么需要二级指针?

如下:无法交换,因为实参和形参平行;

#include <stdio.h>
//做不到交换,原理如下如,mai声明指针,函数体也为指针时,两者内存空间不同,类似与 main中int,形参int
void swap(char *p1,char *p2) //指针形参,重新在内存申请 区域
{
    char *p3=p1;
    p1=p2;
    p2=p3;
    printf("swap:%s %s\n",p1,p2);    
}//此函数实现了第二层指针的复制

int main(void)
{
    char *pa="hello";
    char *pb="world";//
    swap(pa,pb);
     //若pa、pa与p1、p2并行,都为指针,p1和p2为pa、pb的复制品,无法实现真正的交换
    printf("%s %s\n",pa,pb); 
    return 0;
}

原理图:
在这里插入图片描述

如下:可以交换,因为实参和形参平行;

#include <stdio.h>
//可以做到交换,原理如下如,main声明指针,函数体为指针的指针,可完成指针修改
void swap(char **p1,char **p2) //第三层,可直接操作第二层
{
    char *p3=*p1;
    *p1=*p2;//修改pa指针的值
    *p2=p3;//修改pb指针的值
    printf("swap:%s %s\n",p1,p2);    
}//此函数实现了第二层指针互换

int main(void)
{
    char *pa="hello";
    char *pb="world";//
    swap(&pa,&pb);
     //若p1、p2为pa、pb的下层
    printf("%s %s\n",pa,pb); 
    return 0;
}

在这里插入图片描述

2. 二级指针和字符串数组

char *p[]={"hello","world"}; //p[0]为"hello"的首地址
//或者
char *p1="hello";
char *p2="world";
char *p[]={p1,p2};

printf("%s%s%s%s\n",p[0],*(pp+0),pp[0]); //字符串较为特殊,打印字符串1的首地址 相当于 打印字符串

printf("%c%c%c%c\n",*(*(pp)+0),*(*(pp)+1),*(*(pp)+2)); //打印字符'h' 'e' 'l'

//若a[]="hello",p1=a,操作 字符串数组 指针(*(pp+0)+1),可修改字符
printf("%c%c%c\n",*(pp[0]+0),*(pp[1]+1),*(pp[2]+1));

总结:

  1. 本节主要总结函数指针和二级指针常见用法,C备忘;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值