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