本文迁移自老博客,原始链接为 https://seven.blog.ustc.edu.cn/c%e8%af%ad%e8%a8%80%e7%ac%94%e8%ae%b0/
1.函数指针数组。
double add(double , double);
double sub(double , double);
double (*operate[])(double , double) = {add , sub} ;
a = (*operate[0])(1 , 2);
2.const int *p; p = &i; (值不变,址可变,只读的指针,可用在不需要其改变值的函数中); 不等于
const int i = 5; int * const p = &i;
p是常量,需要初始化,否则矛盾(址不变,值可变)
3.复杂声明: char * const * (next)(); (1)从第一个未定义的符号开始读,next(问题即next是什么) (2)然后从上一步的结果向右看,若第一个看到的是’(‘,则是函数;否则是变量,next事变量 (3)如果看到’)’,则往左看,从next开始,如果又看到一个’(‘,则()处理完,从’)’再向右看,再指出第一个未定义的标示符(重复上述过程) (4)如果往左是const , * , volatile,则再往左。由上面的定义,例子: char * const * f(){} next = f或者next = &f 调用 next()或者(next)() 例子2
char * (* c[10])(int ** p)
例子3
void (*signal (int sig , void (*func)(int)))(int)
分析:signal是函数,返回值是 void (* )(int),即返回值是函数指针,整个式子类似于 void (*f)(int) 例子4
int (*(*func)(char *p))[5];
分析 返回值类型 int (* )[5],即int (*p)[5]中p的类型,指向有5个int值的数组 例子5
(*(void (*)()) 0 )();
分析:强制类型转换 void(f)() == (void ()())f 0是一个被强制类型转换后的函数指针,强制类型转换后必须要用正规方式调用。 调用方法 正规(*p)();简写p()
4.自引用结构
struct node{ int count; struct node * next; };
其中的指针不可去掉,否则不可预测大小。
5.
sizeof() int A[5]; sizeof(A) = 20; int *p = A; sizeof(p) = 4; char *s = "ABCD"; sizeof(s) = 4; char A[] = "ABCD"; sizeof(A) = 5;
6.
if(p = (int*)malloc(sizeof(int))){}
free(p);
不要重复释放一个指针的地址空间。
7.链表判断有无环 两个指针
p = p->next; q = q -> next -> next;
若有环两个指针必定相遇
8.c语言inline函数的使用
9.一条线上的蚂蚁,神奇的ghost算法
10.约瑟夫问题与卡特兰数的关系。证明过程见维基百科
11.c/s不仅指真实的客户关系,app和lib之间的关系也可抽象为此关系。
12.n个节点的不同二叉树种类数(或知道前序,有多少多少中序)是卡特兰数。hint:以根节点左右情况数进行划分,左有0~n-1,则,右有n-1~0