C 指针和函数

其实C真的是基础


 

      今天在看iOS中关于Block的一些东西的时候,看到关于Block底层实现的一些东西的时候,涉及到C的函数和指针方面的东西,C真的是基础,关于C的内容也全都在复习和加深理解当中,这理先把指针和函数部分的理解自己再总结一下,看了下面的内容,相信你一定能懂指针型函数和函数指针是什么。

 

      一: 指针型函数

      在C语言中,一个函数可以返回一个整形、字符型或者是实型值等等,当然也可以返回一个空值,也可以返回指针型的数据,即地址,所谓的指针型函数就是指函数的返回值是指针型数据的函数!

      真的这个"指针型函数"和“函数指针”很容易混淆掉,这些细节可能平时接触的C代码多了也就没什么问题,但要是接触的C代码不多的话,很容易出现混淆,得多注意。

      1、指针型函数的定义形式:

          函数数据类型   *  函数名 (形式参数列表)

          解释: 函数名前面的 * 表示函数的返回值就是一个指针类型, “函数的数据类型”是指针所指向的目标变量的类型,在指针型函数中,使用return语句返回的可以是变量的地址,数据的首地址或者指针变量,还可以是结构体,共用体,等构造数据类型的首地址。

          比如: int * function (int a, int b);

          函数的返回值是 int 型指针或者地址,

          下面一个简单的例子,找到两个数的最大值:

         

 

      2、 指针型函数定义是应该注意的问题:

          (1): 指针函数中return的返回值必须是与函数类型一致的指针

            (2): 返回值必须是函数外部或者静态存储类别的变量地址或数组地址,以保证主调函数能正常的使用数据。因为在函数调用结束时,自动存储类型的变量或者数组所占有的村塾单元已经被释放掉,操作系统可能会重新分配这些存储单元。

  

二:函数指针

 

     <1>定义以及注意事项

       在C语言中,可以让指针指向函数,一个函数包括一些列的指令,在内存中占据一篇存储单元,它必然有一个指向函数第一条指令的地址,就是函数的入口地址。如同数组名可以表示数据的首地址一样,C语言同样用函数名表示函数的入口地址,而且是地址常量,通过这个地址可以找到函数,这个地址就是我们要说的函数的指针。

        要让指针指向函数,只要把函数名复制给指针变量,则该指针变量的内容就是函数的入口地址。

        定义形式如下:  数据类型  (* 函数指针变量名)();

        说说上面内容中的一些注意点:

        (1): * 函数指针变量名这部分必须写成(* 函数指针变量名),由于优先级的关系,不然这里就成我们前面写的指针型函数了,

        (2): 和数据型指针一样,程序中不能使用指向不明的函数指针,使用前必须赋值!

        (3): 赋值是可以只给出函数名不必给出参数

 

      <2>函数指针的使用

         这部分的内容也比较重要,不然知道什么是函数指针不会用也尴尬,函数指针与一般的指针之间的共同之处是都可以间接的访问,但是变量指针指向内存中的数据存储区域,通过间接存储运算访问的是目标变量,而函数指针指向内存的程序代码存储区域,通过间接存储运算时程序流程转移到指针所指向的函数入口。

         用函数指针变量调用函数的一般形式是: (* 函数指针变量名)(实参);

         注意点就是:必须用()包含* 函数指针变量名,表示间接调用指针变量所指向的函数,这里其实就是间接取地址运算。

         比如下面这个例子:利用函数指针调用求一个数组的和

        

 

三:用指向函数的指针做函数的参数

      下面这个例子,把我们前面说的两者结合起来看看。

      比如:我们输入1,就求已知数组元素的最小值,输入2就求已知数组元素的最大值,输入3就求数组元素之和,代码如下,能帮助我们理解上面说的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stdio.h>
void process(int *x,int n,int (*fun)()){
 
   int result;
   result = (*fun)(x,n);
   printf("%d\n",result);
}
 
/*求数组的和*/
int  arr_sum(int x[],int n){
 
   int sum = 0;
   for(int i=0;i<n;i++){
     
      sum += x[i];
   }
   return sum;
}
 
/*求数组最大的元素*/
int  arr_max(int x[],int n){
 
   int max = x[0];
   for(int i=0;i<n;i++){
        
      if(max < x[i])
       
         max = x[i];
   }
   return max;
}
 
/*求数组最小元素*/
int  arr_min(int x[],int n){
 
   int min = x[0];
   for(int i=0;i<n;i++){
     
      if(min > x[i])
       
         min = x[i];
   }
   return min;
}
 
 
int main(){
     
     int a[]={1,2,3,4,5,6,7,8}, choice;
     printf("请输入你的选择:");
     scanf("%d",&choice);
      
     switch(choice){
       case 1:
            process(a,8,arr_min);     
       break;
       case 2:
            process(a,8,arr_max);
       break;
       case 3:
            process(a,8,arr_sum);
       break;
     }
}

 

posted @   MrRisingSun  阅读(499)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示