关于指针与函数的几点小结

转载 2007年09月20日 02:28:00
心血来潮, 想对函数指针的几个用法小结一下, 都是平常容易见到的, 如果还有其它不觉的用法也请朋友们不吝赐教.

若有错误之处,还请指正.

1. 首先,在C语言中函数是一种function-to-pointer的方式,即对于一个函数,会将其自动转换成指针的类型.如:

#include<stdio.h>

void fun()
{
}

int main()
{
        printf("%p      %p      %p/n", &fun, fun, *fun);
        return 0;
}

这三个值的结果是一样的. 其实对于最后的那个*fun, 即使前面加上很多个*号, 其结果也不变, 即**fun, ***fun的结果都是一样的. 对于这个问题, 因为之前讲过函数是一种
function-to-pointer方式, 其会自动转换成指针的类型, &fun是该函数的地址, 为指针类型, fun是一个函数, 会转换成其指针类型, 而对于*fun, 由于fun已经变成了指针类型, 指向这个函数, 所以*fun就是取这个地址的函数, 而又根据function-to-pointer, 该函数也转变成了一个指针, 所以以此类推, 这三个值的结果是相同的.

2. 如何调用一个地址上的函数
  如果知道了一个函数所在的地址, 可以将其强制转化成某一种类型的函数指针, 然后再根据这个指针去调用这个地址的函数. 如:

#include<stdio.h>

void f(int i)
{
        printf("i = %d/n", i);
}

int main()
{
        unsigned long add;
        add = (unsigned long)f;
        ((void (*)(int))add)(10);
        (*(void (*)(int))add)(20);
        return 0;
}

使用(void (*)(int))的方式可以将一个地址转换成一个带int参数且没有返回值的函数的指针类型, 然后再去调用, 由于第1点中讲的function-to-pointer, 所以最后两条语句中加与不加那个*号效果都是一样的. 在嵌入式方面经常用到这种方式.

3. 函数指针数组的用法.
有时候需要定义一个数组, 其内容为一系列的函数指针, 然后对其进行调用, 如:

#include<stdio.h>
int max(int v1, int v2)
{
        return (v1 > v2 ? v1 : v2);
}

int min(int v1, int v2)
{
        return (v1 < v2 ? v1 : v2);
}

int sum(int v1, int v2)
{
        return (v1 + v2);
}

int main()
{
        int (*p[3])(int, int);
        p[0] = max;
        p[1] = min;
        p[2] = sum;

        printf("p[0] = %d/n", (p[0])(3, 5));
        printf("p[1] = %d/n", (p[1])(4, 6));
        printf("p[2] = %d/n", (p[2])(1, 2));
        return 0;
}

虽然感觉这种方法有点累赘, 但是也算是一种使用的方式, 所以介绍一下.

4.返回一个指向数组的指针的方式
可以让函数返回一个指向数组的一个指针, 如:

#include<stdio.h>
#include<stdlib.h>
int (*p())[10]
{
        int (*m)[10];
        int i;
        m = (int (*)[10])malloc(10 * sizeof(int));
        if (m == NULL)
        {
                printf("malloc error/n");
                exit(1);
        }
        for (i = 0; i < 10; i++)
                *(*m+i) = i+1;
        return m;
}

int main()
{
        int (*a)[10];
        int i;
        a = p();
        for (i = 0; i < 10; i++)
                printf("%d ", *(*a+i));
        printf("/ndone/n");
        return 0;
}

这种方式中,int (*a)[10]是一个指向一维数组的一个指针, 而p()也是返回一个指向一维数组的一个指针.

5.返回一个函数指针的指针
对这个问题, signal()函数是最好的例子,

void (*signal (int signo, void (*func)(int)))(int);

很多朋友刚开始看这个函数定义的时候是不太懂, 其实可以一步一步地慢慢看, 我以前是这样分析的, 希望能对大家有用.
int (*p)();
这是一个函数指针, p所指向的函数是一个不带任何参数, 并且返回值为int的一个函数.
int (*fun())();
这个式子与上面式子的区别在于用fun()代替了p,而fun()是一个函数,所以说就可以看成是fun()这个函数执行之后,它的返回值是一个函数指针,这个函数指针(其实就是上面的p)所指向的函数是一个不带任何参数,并且返回值为int的一个函数.所以说对于

void (*signal(int signo, void (*fun)(int)))(int);

就可以看成是signal()函数(它自己是带两个参数,一个为整型,一个为函数指针的函数), 而这个signal()函数的返回值也为一个函数指针,这个函数指针指向一个带一个整型参数,并且返回值为void的一个函数.
signal函数返回的其实是指向以前的信号处理程序的指针, 所以举一个例子来说明返回指向函数的指针的用法,如:

#include<signal.h>
#include<stdlib.h>
#include<stdio.h>

void sig_fun2(int signo)
{
        printf("in sig_fun2:%d/n", signo);
}

void sig_fun1(int signo)
{
        printf("in sig_fun1:%d/n", signo);
}

int main()
{
        unsigned long i;
        if (signal(SIGUSR1, sig_fun1) == SIG_ERR)
        {
                printf("signal fun1 error/n");
                exit(1);
        }

        (signal(SIGUSR1, sig_fun2))(30);

        printf("done/n");
        return 0;
}

6. 使用函数指针作为参数的情况
在函数的参数中, 可能会带有一个函数指针, 这在signal()函数中是出现了的, 另外再写个例子如:

#include<stdio.h>

int max(int v1, int v2)
{
        return (v1 > v2 ? v1 : v2);
}

int min(int v1, int v2)
{
        return (v1 < v2 ? v1 : v2);
}

int sum(int v1, int v2)
{
        return (v1 + v2);
}

int fun(int a, int b, int (*call)(int, int))
{
        return (call(a, b));
}

int main()
{
        printf("max=%d/n", fun(1, 2, max));
        printf("min=%d/n", fun(3, 4, min));
        printf("sum=%d/n", fun(5, 6, sum));
        return 0;
}

其实在很多排序函数中就是使用的这个参数为函数指针的方式来进行调用的.

草草地总结了一下, 希望能有一些用.  
 

关于指针与函数的几点小结

http://bbs.chinaunix.net/thread-993238-1-1.html 1. 首先,在C语言中函数是一种function-to-pointer的方式,...

C/C++ const几点总结(2)——指针与函数

1.当使用带有指针的const时,有两种选择:const

关于指针变量作函数参数的几点注意

关于指针变量作函数参数的几点注意 题目:输入两个整数,并按从小到大的顺序输出这两个整数。...

C语言学习小结(指针、数组、函数)

C语言学习小结(指针、数组、函数)       v 指针   1. 指针到底是什么?   指针其实也是一种特殊的变量,它与其他普通变量的区别是:普通变量里面是数据本身,而指针变量里面是数...
  • csdnxmj
  • csdnxmj
  • 2017年10月26日 20:24
  • 27

小结 | C++(二)| 默认成员函数、this指针

四个默认成员函数、隐藏的this指针

Unity学习小结4 - NGUI的几点性能问题

NGUI的一些性能问题小结及一些简单的规避方法

指针小结.txt

  • 2008年05月13日 15:57
  • 21KB
  • 下载

excel格式化输出函数 小结例子

  • 2007年04月25日 20:43
  • 80KB
  • 下载

C语言中的“倚天剑”--谈指针的几点见解

昨天回顾了一下C语言的指针这一部分,每一次重新回顾一下

静态或者全局智能指针使用的注意几点

静态或者全局智能指针使用的注意几点 在C++11普及开始后,智能指针才真正的被广大的C++程序员使用,当然一些高手还有大牛还是非常轻视智能指针的,咱们不谈那个。今天只谈一谈智能指针的全局化和静态化后...
  • fpcc
  • fpcc
  • 2017年02月07日 15:25
  • 693
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于指针与函数的几点小结
举报原因:
原因补充:

(最多只允许输入30个字)