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
",p());
printf("%f
",(*p)());
}
这两种都是行的通的,因为相对其他变量函数还是有点特殊的,如果我们对代码反汇编会发现函数名就是一个标签,也就是这段代码的起始地址。函数名可以认为是一个指针。
那么两种调用方法是可以说的通的。
下面来一个略微复杂的函数指针定义。
(*(void(*)()0)()
先看左边括号,可以看到0是被强制转化为另一种数据类型了。可以看出0被强制转化为void(*)(),结合上面的可以得出这是一个函数指针,返回值无,参数未定义。我们用p来代替它那么上面的代码可以简化为 (*(p) 0)()。显然这是函数指针的第二种调用方式。也就是我们这句代码的意思是,执行地址0上的一个函数,这个函数未定义输入函数,没有输出值。
最后留一段程序大家自己来分析。如果能把这段代码看懂应该可以初步掌握分析函数指针的技巧
代码链接地址:https://www.oschina.net/code/snippet_1160401_26309
注:
void * 为无类型指针,我们可以定义无类型的指针,比如 void *p;但不能定义 void a;因为所有的指针占用的内存空间是一样大的,但变量却不一定。