C语言函数指针分析

C语言中的指针

本篇文章版权多有,抄袭问责。转载注明出处:http://www.cnblogs.com/cnzhao/p/5986283.html。
如有疑问可邮件:zhaogoodwell@gmail.com

前言

  指针到底是什么?很多学的一知半解的人会粗暴的认为指针就是个地址。其实这种认识是极其片面的,首先指针是一个基本数据类型,它存储的内容为指向目标的地址。指针最重要的一个特性就是它所指向的类型。指向的类型不同决定了对它进行同样的操作却获得不同的结果。在本篇中会一步步讲解如何去分析一个函数指针的类型。本篇主要讲函数指针,下一篇讲分析指针和数组之间的关系,分析如何抽丝剥茧的分析指针类型。

变量的声明

  为了保证思维的连贯性我们首先从简单的变量申明开始。我们先声明一个浮点型变量

float f;

  使用它的时候我们会直接 使用它

f=0;

  接下来我们来定义一个指向浮点的指针。

float *g;

  这个g是一个指针,在内存里面它保存的是一个浮点变量的地址,显然我们没法直接运用它,当然如果给它直接强制赋值很难保证程序可以稳定运行。我们需要给他一个值,这个值对应的是另一个变量的地址。我们可以

 g = &f;
        \*g = 100.0f;

  我们将f的地址给了g,同时对它进行解引用,那么我们会的到f里面的值改变了,变成了100.0。
  我们可以定义一个函数

  float f();

  这是一个输入参数未定义,返回值为float 的函数。我们调用它直接使用:
 f();

  至此我们一切都是顺风顺水,接下来的东西可能跳跃性大一点。我先来看一个简单的变量声明,看看它到底是什么东西,是的,我们还在岸上,还没掉到沟里面去。
  float (*p)();

  第一次看到这个符号的人可能会蒙掉,这到底是什么乱七八糟的东西!好的,我们先慢慢来分析它。显然小括号的优先级最高,p优先和*结合。所以这是个指针,在看指针外面,一个括号,说明这是个函数。至此我们可以得出这是一个指针,它指向的是函数。
  我们怎么调用它呢?调用方法有两种,分别是

  p();
(\*p)();

简单的实例代码:

  
\#include 
\#include 
float test()
{
    return 2.1;
}

int main()
{
    float (*p)();
    p = test;
    printf("%f\n",p());
    printf("%f\n",(\*p)());
}

  这两种都是行的通的,因为相对其他变量函数还是有点特殊的,如果我们对代码反汇编会发现函数名就是一个标签,也就是这段代码的起始地址。函数名可以认为是一个指针。
那么两种调用方法是可以说的通的。

  下面来一个略微复杂的函数指针定义。

(\*(void(\*)()0)()

先看左边括号,可以看到0是被强制转化为另一种数据类型了。可以看出0被强制转化为void(*)(),结合上面的可以得出这是一个函数指针,返回值无,参数未定义。我们用p来代替它那么上面的代码可以简化为 (*(p) 0)()。显然这是函数指针的第二种调用方式。也就是我们这句代码的意思是,执行地址0上的一个函数,这个函数未定义输入函数,没有输出值。
  最后留一段程序大家自己来分析。如果能把这段代码看懂应该可以初步掌握分析函数指针的技巧
代码链接地址:https://www.oschina.net/code/snippet_1160401_26309

注:

void * 为无类型指针,我们可以定义无类型的指针,比如 void *p;但不能定义 void a;因为所有的指针占用的内存空间是一样大的,但变量却不一定。

posted on 2016-10-21 23:22  一日二三里  阅读(375)  评论(0编辑  收藏  举报

导航