第十九章、C 语言高级语法
本章我们来学习 C 语言中为了提高软件开发效率和运行效率等给出的一些语法规范。
1. 指针的类型总结
本节我们总结一下 C 语言中常用数据类型以及指向它们的指针的类型以及书写方法。
详见见如下表格
变量或函数
指向变量或函数的指针
说明
char c;char *pc = &c;pc 指向字符型数据short s;short *ps = &s;ps 指向短整型数据int i;int *pi = &i;pi 指向整型数据long int l;long int *pl = &l;pl 指向长整型数据long long int ll;long long int *pll = ≪pll 指向长长整型数据float f;float *pf = &f;pf 指向浮点型数据double d;double *pd = &d;pd 指向双精度浮点型数据struct stu stustruct stu * pstupstu 是指向 结构体的指针union pkg gunion pkg *gpg 是指向联合体的指针enum color cenum color *pcpc 是指向枚举的指针int *p;int **pp = &p;pp 是指向整型指针的二级指针int a[100];int(*pa)[100] = &a;pa 是指向指向整型一维数组的指针int ar[3][4];int(*par)[3][4] = &ar;par 是指向指向整型二维数组的指针int* ap[100];int*(*pap)[100] = ≈pap是指向一维整型指针数组的指针void fn(void);void(*pfn)(void) = &fn;pfn 是指向 void(void) 型函数的函数指针,表达式 &fn 等同于 fnint fn(int x, int y);int(*pfn)(int, int) = &fn;pfn 是指向 int(int,int) 型函数的函数指针void fn(int x, int(*fx)(float));void(*pfn)(int, int(*)(float)) = &fn;函数的参数是函数指针
int *fn(int x);int *(*pfn)(int);pfn 是指向返回值是指针的函数指针void (*fn(int x))(int);void (*(*pfn)(int))(int) = &fn;返回值是函数指针函数的函数指针
最后一条看似很复杂,我们后面再解释。
上述我们分别声明了变量、数组和函数,也分别声明了指向变量、数组和函数的指针。此时你是否能否发现规律呢?
- 声明指向变量的指针在变量名处前加一个
*然后把变量名改成指针名。 - 声明指向数组的指针在是将数组名用括号括起来,然后在数组名前加一个
*然后把数组名改成指针名。 - 声明指向函数的指针在是将函数名用括号括起来,然后在函数名前加一个
*然后把函数名改成指针名(函数的形参名可以去掉,也可以保持不变)。
上述指针在解引用后得到的就是指向的数据对象。类型也和指向的对象类型相同。
指针的运算
基本数组类型的指针、指针类型的指针和指向数组的指针可以进行运算加、减运算。函数指针通常不进行加、减运算。
- 基本数据类型的指针加 n 或减 n 则先前或向后移动一个n 个指向数据类型的长度。
- 指向数组的指针也是如此,如: 指针
int(*pa)[100],则pa+1则向后移动 400 个字节;指针int(*par)[3][4],则par+1则向后移动 48 个字节。
函数指针的使用
函数指针可以(*函数指针)(实际调用参数)的方式解引用后调用,也可以使用 函数指针(实际调用参数) 的方式直接调用。
返回函数指针的函数
我们来看 void (*fn(int x))(int); 这个声明。这个是声明一个函数 fn(int x), 它有一个 形参变量 x,该函数返回值是一个 void(*)(int) 类型的函数指针。即该函数 fn 能够返回一个函数的地址。
如果想让返回函数指针的函数 写起来更容易理解,我们需要使用 C 语言的 typedef 关键字来为复杂类型起别名。
实验:
如下是 Linux/UNIX 操作系统信号设置函数的声明,分析该函数是怎样一个函数,该函数如何调用,实参是什么类型?返回值是什么类型?
#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);