C

学习C语言重要的是理解它的设计思想和实现这些思想的原则

指针

指针的本质

指针的值是一块内存的地址,通过指针可以操作那块内存的值。内存的地址是什么?一个整数.
指向指针的指针的…指针
在C语言中,指针是精华,指向指针的指针也比较常用。其实指针的概念扩展开来可以有无限层的指针,但是本质上都指针:其值都是另一块内存的地址。例如下面可以定义4层指针

/* 多重指针并不该被使用,只是为了理解C语言的原则*/
int var = 5;          //存在内存0x23处
int *p = &a;          //指向0x23处的内存,存在内存0x100处
int **pp = &p;        //指向0x100处的内存,存在0x200处
int ***ppp = &pp;     //指向0x200处,存在0x300处
int ****pppp = &ppp;  //指向0x300处,存在0x400处

指向函数的指针

程序中的每个函数都位于内存中的某个位置,所以存在指向那个位置的指针是完全可能的。在实际的函数调用过程中,也是首先把函数名转换成函数指针。

/* 首先要定义好函数原型 */
int compare(void const *,void const *);
//定义指向函数的指针
int (*p_compare)(void const *,void const *);
//指针指向函数
p_compare = &compare;
//起始&是可以省略的,因为函数名在使用时,编译器总是先把它转换成函数指针
p_compare = compare;

如何调用?

  • 直接使用函数名compare(p,q):函数名首先被转换成函数指针,它指向内存中函数的地址,然后执行开始于这个地址的代码
  • 使用函数指针(*p_compare)(p,q):解引用获得函数名,函数名再被转换成函数指针,这种调用方式是不是最慢的?它的效果和使用函数名是一样的
  • 函数指针 p_compare(p,q):直接使用函数指针,这是最直接的方式

注意和普通的函数区分开来:

  • int *p_compare(void const *,void const *)p_compare是函数名,它返回整型指针。它的结合顺序是:p_compare首先跟()结合,表明它使一个指针,然后再和*结合,表明它的返回值是一个指针,int表明它使一个指向int型的指针
  • int (*p_compare)(void const *,void const *)p_compare是指向函数的指针,它的结合顺序是:首先跟(*p_compare)表明它使一个指针,然后跟(void const *,void const *)结合,表明它使指向函数的指针,int表明它的返回值

函数指针数组,首先它使一个数组,它的元素都是指向函数的指针,那么该如何定义它呢?试着用一些原则来逐步定义函数指针数组

  • 它是一个数组,数组的定义:p_function_array[]
  • 元素是指针,指针数组的定义:*p_fuction_array[]
  • 指向的是函数,(*p_function_array[])(void *,void *)
  • 再加上返回值,int (*p_function_array[])(void *,void *)
函数指针的使用

函数指针的作用场景是作为函数的参数,也就是回调函数,看一段代码

通过使用函数指针,可以使用与类型无关的查找方法。
不同的类型有不同的比较方法,但是查找的逻辑都是相同的,
所以可以通过为不同的类型提供不同的比较方法,就可以实现统一的查找逻辑。
p_compare就是回调函数,只要函数的声明符合条件,都可以作为search_list的参数
Java中如何实现回调函数?
Node *search_list(List L,void *value,int (*p_compare)(void const *,void const *)) {
    for(;;)
        if(p_compare(,) == 0)
            do something
    return 节点;
}

函数指针的场景是转移表,它可以实现switch的功能,考虑一个计算器的功能,把加减乘除抽象成函数,根据不同的命令,通过switch来选择相应的函数。转移表就可以完成这个操作:

double add(double a,double b);
double sub(double a,double b);
double mul(double a,double b);
double div(double a,double b);

//函数指针数组
double (*calc[])(double,double) = {add,sub,mul,div};

//使用
calc[0](a,b)

通过分析一些技巧的含义能让我们更好的理解C语言的原则,例如只要把握住指针的本质,在分析多层指针的时就不会有问题。

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值