C语言中函数与指针的应用总结_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;
}

时间: 2024-08-31 14:27:32

C语言中函数与指针的应用总结_C 语言的相关文章

C语言 函数指针(指向函数的指针)详解_C 语言

一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似.我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数.这种指针就是函数指针. 函数指针的定义形式为: returnType (*pointerName)(param list); returnType 为函数返回值类型,pointerNmae 为指针名称,param list 为函数参数列表.参数列表中

C++指向函数的指针用法详解_C 语言

本文以实例形式展示了C++指向函数的指针用法,是深入学习C++所必须掌握的关键知识点.分享给大家供大家参考之用.具体方法如下: 函数指针 现来看看以下声明语句,看看其含义: float (*h(int, void (*)(int)))(int); 以下是一个变量指针的定义语句: float* pf; 以下是一个普通函数的声明语句: float f(); 请看以下声明语句: float* g(); 因为()的优先级高于*, 所以相当于: float* (g()); g是一个函数, 返回值为floa

C语言中函数 与 指针学习笔记

一.指向函数的指针 函数名可以在表达式中被解读成"指向函数的指针",因此,正如代码清单 2-2 的实验那样,写成 func 就可以取得指向函数的指针. "指向函数的指针"本质上也是指针(地址),所以可以将它赋给指针型变量. 比如有下面的函数原型: int func(double d); 保存指向此函数的指针的变量的声明如下: int (*func_p)(double); 然后写成下面这样,就可以通过 func_p 调用 func, int (*func_p)(dou

详解C++中的this指针与常对象_C 语言

C++ this指针详解 this 是C++中的一个关键字,也是一个常量指针,指向当前对象(具体说是当前对象的首地址).通过 this,可以访问当前对象的成员变量和成员函数. 所谓当前对象,就是正在使用的对象,例如对于stu.say();,stu 就是当前对象,系统正在访问 stu 的成员函数 say(). 假设 this 指向 stu 对象,那么下面的语句中,this 就和 pStu 的值相同: Student stu; //通过Student类来创建对象 Student *pStu = &s

详解C++中的对象指针与对象数组_C 语言

C++对象指针 指向对象的指针 在建立对象时,编译系统会为每一个对象分配一定的存储空间,以存放其成员.对象空间的起始地址就是对象的指针.可以定义一个指针变量,用来存放对象的指针. 如果有一个类: class Time { public : int hour; int minute; int sec; void get_time( ); }; void Time::get_time( ) { cout<<hour<<":"<<minute<<

详解C语言中的#define宏定义命令用法_C 语言

#define命令#define定义了一个标识符及一个串.在源程序中每次遇到该标识符时,均以定义的串代换它.ANSI标准将标识符定义为宏名,将替换过程称为宏替换.命令的一般形式为: #define identifier string 注意: 1.该语句没有分号.在标识符和串之间可以有任意个空格,串一旦开始,仅由一新行结束. 2.宏名定义后,即可成为其它宏名定义中的一部分. 3.宏替换仅仅是以文本串代替宏标识符,前提是宏标识符必须独立的识别出来,否则不进行替换.例如: #define XYZ th

C语言中二维数组指针的简要说明_C 语言

C语言中,指针是一个复杂但又灵活多变的知识点,我们知道,在一维数组中,对于一个数组a[],*a,a,&a,都表示a的首地址,但如果与二维数组混合使用,就显得更为复杂了.例如对于一个二维数组 a[2][4]={{1,2.3},{4,5,6}} a+i,&a[i],*(a+i),a[i], 这四个表达式到底表示什么呢? 先告诉答案吧,其实这几个表达式都是指向同一个地址的,也许你会很诧异,也会很疑惑,怎么会是这样呢!!事实证明就是这样的, C语言中,指针是一个复杂但又灵活多变的知识点,我们知道,

C语言中获取和改变目录的相关函数总结_C 语言

C语言getcwd()函数:取得当前的工作目录头文件: #include <unistd.h> 定义函数: char * getcwd(char * buf, size_t size); 函数说明:getcwd()会将当前的工作目录绝对路径复制到参数buf 所指的内存空间,参数size 为buf 的空间大小. 注: 1.在调用此函数时,buf 所指的内存空间要足够大.若工作目录绝对路径的字符串长度超过参数size 大小,则返回NULL,errno 的值则为ERANGE. 2.倘若参数buf 为

C语言中读取时间日期的基本方法_C 语言

C语言time()函数:获取当前时间(以秒数表示)头文件: #include <time.h> 定义函数: time_t time(time_t *t); 函数说明:此函数会返回从公元 1970 年1 月1 日的UTC 时间从0 时0 分0 秒算起到现在所经过的秒数.如果t 并非空指针的话,此函数也会将返回值存到t 指针所指的内存. 返回值:成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno 中. 范例 #include <time.h> main(){