zoukankan      html  css  js  c++  java
  • 一文搞懂C语言中指针、数组、指针数组、数组指针、函数指针、指针函数

    一文搞懂C语言中指针、数组、指针数组、数组指针、函数指针、指针函数

    1.背景

    阅读redis源码,初始化流程-创建并初始化服务器数据结构中(initServer)

    // 设置信号处理函数
    signal(SIGHUP, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    

    signal函数

    #include<signal.h>
    
    // signal函数原型
    void (*signal (int sign,void (*)(int)))(int);
    
    // second version
    typedef void (*sig_t)(int);
    sig_t signal(int sign,sig_t func);
    

    singal函数看着有一点绕,先把基本概念搞清楚,就会发现函数结构很清晰

    先了解一下基本概念

    2.指针 & 数组

    指针: 存放某个变量的地址的变量

    数组: 在内存中分配的连续的"内存块"

    void * // 通用类型指针
    &      // 取地址符号
    *      // 间接或解引用
    

    在c语言中指针和数组存在千丝万缕的关系,数组中的下标操作都可以使用指针实现

    int a[10];
    int *pa;
    pa = &a[0];            // pa指针,指向数组的首地址
    //pa = a;
    //a[i],*(a+i),*(pa+i)  都是相同的表示
    

    数组+下标 = 指针 + 偏移

    当一个数组名被传递给函数时,实际传递的是起始元素的位置

    // 函数定义的形参 , 使用指针和数组是相同的
    int func(char[] temp);
    int func(char *temp);
    

    3.指针数组 & 数组指针

    指针是存放某个变量地址的变量 ----> 指针也是变量,指针也可以存放在数组中

    指针数组:指向指针的指针

    #define MAXLINES 100
    char *linePtr[MAXLINES];   // 指针数组,存放了100个 char* 指针的数组
    

    数组指针:指针存放着一个数组的首地址

    4.指针函数 & 函数指针

    指针函数:某个函数的返回值是某一个类型的指针,本质上是一个函数

    类型说明符 + * + 函数名+ (参数)

    int *func(int a,int b);
    

    函数指针: 指向函数的指针变量,本质上是一个指针

    类型说明符 + (* 函数名)+ (参数)

    int (*func) (int a,int b);
    

    5.再探signal函数

    void (*signal (int sign,void (*)(int)))(int);
    

    先拆分

    void(*)(int);
    

    函数指针的使用

    void func(int a){   // 函数
      a = 5;
    }
    void (*pfunc)(int); // 函数指针
    // pfunc 函数指针 = 它指向的函数就是一个具有void返回值,int参数的函数
    pfunc = func;      // pfunc = &func;
    // 指针调用函数
    pfunc(5);          // (*func)(5)
    
    // 强制类型转换
    pfunc = (void (*)(int)) 0x0002;
    
    #define SIG_DFL         (void (*)(int))0
    #define SIG_IGN         (void (*)(int))1
    #define SIG_HOLD        (void (*)(int))5
    #define SIG_ERR         ((void (*)(int))-1)
    

    返回函数指针的函数声明

    • 定义一个函数func,返回值为函数指针;函数有两个输入参数,一个为int,一个是函数指针。
    // 类型定义typedef
    typedef void(*PFUNC)(int);   // 定义PFUNC为一个  void(*)(int)
    PFUNC func(int,PFUNC);
    
    // 不使用typedef进行定义
    func(int ,void(*)(int))       // void (*pfunc)(int); // 函数指针
    void(* func(int,void(*)(int)))(int)
      
    // void (*signal (int sign,void (*)(int)))(int);
    // 一个返回函数指针的的函数声名
    // 使用函数
    signal(SIGHUP, SIG_IGN);   // #define SIGHUP  1       /* hangup */ ; #define SIG_IGN   (void (*)(int))1
    signal(SIGPIPE, SIG_IGN);
    
    不要用狭隘的眼光看待不了解的事物,自己没有涉及到的领域不要急于否定. 每天学习一点,努力过好平凡的生活.
  • 相关阅读:
    DNS服务器安全之通过ipset对DNS异常解析流量的源IP地址进行管控
    C# Windows Api的一些方法 封装 以及 常用参数
    Java基础—异常(1)
    Java基础——异常(2)
    vb6 wininet
    vb6转16进制
    Java 中与(&)短路与(&&)以及 或(|)短路或(||)的关系
    关于面向对象的简单总结
    javaScript的基本规范
    关于TCP传输的三次握手四次挥手策略
  • 原文地址:https://www.cnblogs.com/GeekDanny/p/15363183.html
Copyright © 2011-2022 走看看