十四、返回指针的函数与指向函数的指针 - M了个J - 博客园
十四、返回指针的函数与指向函数的指针
说明: 这个C语言专题,是学习iOS开发的前奏。也为了让有面向对象语言开发经验的程序员,能够快速上手C语言。如果你还没有编程经验,或者对C语言、iOS开发不感兴趣,请忽略
前言
前面我们花了接近3个章节学习指针,应该都感受到指针的强大了吧。指针可以根据地址直接操作内存中的数据,使用得当的话,不仅能使代码量变少,还能优化内存管理、提升程序性能。关于指针的内容还非常多,比如指针数组、指向数组的指针、指向指针的指针,呵呵,看到这些名字是否都觉得头大了,不过我就暂时不在博客中讲解这些内容了,我只讲述在iOS开发中指针的最常见用法,比如这一章的内容---- 返回指针的函数 与 指向函数的指针
一、返回指针的函数
指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的。
返回指针的函数的一般形式为: 类型名 * 函数名(参数列表)
比如下面这个函数,返回一个 指向char类型变 量的指针
1 // 将字符串str中的小写字母变成大写字母,并返回改变后的字符串 2 // 注意的是:这里的参数要传字符串变量,不能传字符串常量 3 char * upper( char * str) { 4 // 先保留最初的地址。因为等会str指向的位置会变来变去的。 5 char *dest = str; 6 7 // 如果还不是空字符 8 while (*str != ' \0 ' ) { 9 // 如果是小写字母 10 if (*str >= ' a ' && *str <= ' z ' ) { 11 // 变为大写字母。小写和大写字母的ASCII值有个固定的差值 12 *str -= ' a ' - ' A ' ; 13 } 14 15 // 遍历下一个字符 16 str++ ; 17 } 18 19 // 返回字符串 20 return dest; 21 }里面的代码我就不详细解释了,重 点看第2行的定 义形式。
调用这个函数也非常简单:
int main() { // 定义一个字符串变量 char str[] = " lmj " ; // 调用函数 char *dest = upper(str); printf( " %s " , dest); return 0 ; }输出结果:
二、指向函数的指针
看到这个标题,你可能觉得很诧异,指针竟然可以指向一个函数,那我就先解释一下 为什么指针可以指向一个函数 ?
1. 为什么指针可以指向一个函数 ?
函数作为一段程序,在内存中也要占据部分存储空间,它也有一个起始地址,即函数的入口地址。函数有自己的地址,那就好办了,我们的指针变量就是用来存储地址的。因此,可以利用一个指针指向一个函数。其中, 函数名就代表着函数的地址 。
2.指向函数的指针的定义
定义的一般形式: 函数的返回值类型 (*指针变量名)(形式参数1, 形式参数2, ...);
注意: 形式参数的变量名可以省略,甚至整个形式参数列表都可以省略
1 #include <stdio.h> 2 3 int sum( int a, int b) { 4 return a + b; 5 } 6 7 int main() 8 { 9 // 定义一个指针变量p,指向sum函数 10 int (*p)( int a, int b) = sum; 11 // 或者 int (*p)(int, int) = sum; 12 // 或者 int (*p)() = sum; 13 14 // 利用指针变量p调用函数 15 int result = (*p)( 1 , 3 ); 16 // 或者 int result = p(1, 3); 17 18 printf( " %d " , result); 19 return 0 ; 20 }* 首 先在第3行定义了一个sum函数,接收2个int类型的参数,返回值类型为int
* 然后在第10行定义了一个 指向sum函数 的指针变量p。注意p的定义形式: int (*p)( int a, int b),第1个 int 代表sum函数的返回值是 int 类型,然后*p是用括号()包住的,后面的 int a和 int b代表着sum函数的形参,其实完全可以省略。第10行、11行、12行都是可行
* 在第15行,先利用*p取出指向的函数,再传入参数调用函数。也可以采用第16行中的做法,这样就跟调用普通函数没什么区别
最后的输出结果: ,毫无意外
3.使用注意
1> 由于这类指针变量存储的是一个函数的入口地址,所以对它们作加减运 算(比如p++) 是无意义的 。难道p++就会指向下一个函数了?可笑至极!!没这回事。
2> 返回指针的函数的定 义 char *upper( char *str) 和 指向函数的指针的定义 int (*p)( int a, int b)非常相似,使用时特 别注意区分
3> 指向函数的指针变量主要有两个用途:
调用函数
将函数作为参数在函数间传递。我这么一说,可能还不是很明白,举个例子。
1 #include <stdio.h> 2 3 // 减法运算 4 int minus( int a, int b) { 5 return a - b; 6 } 7 8 // 加法运算 9 int sum( int a, int b) { 10 return a + b; 11 } 12 13 // 这个counting函数是用来做a和b之间的计算,至于做加法还是减法运算,由函数的第1个参数决定 14 void counting( int (*p)( int , int ) , int a, int b) { 15 int result = p(a, b); 16 printf( " 计算结果为:%d\n " , result); 17 } 18 19 int main() 20 { 21 // 进行加法运算 22 counting(sum, 6 , 4 ); 23 24 // 进行减法运算 25 counting(minus, 6 , 4 ); 26 27 return 0 ; 28 }如果以后想再增加一种乘法运算, 非常简单,根本不用修改counting函数的代码,只需要再增加一个乘法运算 的函数
int mul( int a, int b) { return a * b; }然 后counting(mul, 6, 4);就可以进 行乘法运算了