C语言中函数与指针的应用总结
1. 首先,在C语言中函数是一种function-to-pointer的方式,即对于一个函数,会将其自动转换成指针的类型.
#include<stdio.h>
void fun()
{
}
int main(void)
{
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(void)
{
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(void)
{
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(void)
{
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的一个函数.
所以说signal()可以看成是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(void)
{
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()函数中是出现了的.
其实在很多排序函数中就是使用的这个参数为函数指针的方式来进行调用的.比如Quicksort
例如:
#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(void)
{
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;
}
相关文章
- 这篇文章主要为大家详细介绍了C语言实现放烟花的程序,有音乐播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-23
- 本篇文章主要介绍C语言中char的知识,并附有代码实例,以便大家在学习的时候更好的理解,有需要的可以看一下...2020-04-25
- 这篇文章主要介绍了详解如何将c语言文件打包成exe可执行程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-25
- free函数是释放之前某一次malloc函数申请的空间,而且只是释放空间,并不改变指针的值。下面我们就来详细探讨下...2020-04-25
- 这篇文章主要介绍了C语言中计算正弦的相关函数总结,包括正弦和双曲线正弦以及反正弦的函数,需要的朋友可以参考下...2020-04-25
详解C语言中的rename()函数和remove()函数的使用方法
这篇文章主要介绍了详解C语言中的rename()函数和remove()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25- 这篇文章主要介绍了C语言中求和、计算平均值、方差和标准差的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-10
- 本篇文章主要讲解C语言 基本语法,这里提供简单的示例和代码来详细讲解C语言的基本语法,开始学习C语言的朋友可以看一下,希望能够给你带来帮助...2021-09-18
- 这篇文章主要介绍了C语言中send()函数和sendto()函数的使用方法,是C语言入门学习中的基础知识,需要的朋友可以参考下...2020-04-25
- 今天小编就为大家分享一篇C语言实现从文件读入一个3*3数组,并计算每行的平均值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了C语言中memcpy 函数的用法详解的相关资料,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了使用C语言操作文件的基本函数整理,包括创建和打开以及关闭文件的操作方法,需要的朋友可以参考下...2020-04-25
- 这篇文章主要介绍了C语言中查找字符在字符串中出现的位置的方法,分别是strchr()函数和strrchr()函数的使用,需要的朋友可以参考下...2020-04-25
- 很多同学在学习c语言的时候是不是会碰到a++和++a都有甚么作用啊。今天我们就来探讨下...2020-04-25
- 这篇文章主要对C语言中const关键字的用法进行了详细的分析介绍,需要的朋友可以参考下...2020-04-25
- 下面小编就为大家带来一篇C语言实现时间戳转日期的算法(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-04-25
- 这篇文章主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下...2020-04-25
- 本文给大家简单介绍下c实现linux下的数据库备份的方法和具体的源码,十分的实用,有需要的小伙伴可以参考下。...2020-04-25
C语言正则表达式详解 regcomp() regexec() regfree()用法详解
C语言处理正则表达式常用的函数有regcomp()、regexec()、regfree()和regerror(),这里就为大家介绍一下,需要的朋友可以参考一下啊...2020-04-25- 这篇文章主要介绍了c语言实现找最大值最小值位置查找,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-04