一文搞懂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);