zoukankan      html  css  js  c++  java
  • 【C语言】-返回指针的函数与指向函数的指针

    说明:这个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 != '') {
     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
    ", 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);就可以进行乘法运算了

  • 相关阅读:
    UVa 12174 (滑动窗口) Shuffle
    UVa 1607 (二分) Gates
    CodeForces ZeptoLab Code Rush 2015
    HDU 1525 (博弈) Euclid's Game
    HDU 2147 (博弈) kiki's game
    UVa 11093 Just Finish it up
    UVa 10954 (Huffman 优先队列) Add All
    CodeForces Round #298 Div.2
    UVa 12627 (递归 计数 找规律) Erratic Expansion
    UVa 714 (二分) Copying Books
  • 原文地址:https://www.cnblogs.com/vijozsoft/p/5113906.html
Copyright © 2011-2022 走看看