首先从简单的例子讲起, 你至少需要知道这是一个函数指针:
1 | void (*fp)(int); |
整个声明有三个部分, fp是我们给它的名字, 左边那个”*”说明它是一个指针, 右边(int)是接受的参数类型, 前面void是返回类型.
但对于这个
1 | void* (*(*fp))(int))[10]; |
很多人即使大概能看懂, 也没法自信的说就是这样, 更没法给别人解释了. 其实知道规则以后, 会非常易读. 我管这个规则叫右摇左摆法则, 非常滑稽的名字, 但实际使用就是从中间看起, 然后看它的右边, 再看它的左边, 再看右边, 再看左边, 直到结束.
所欲上面的这个例子, 我们从fp也就是中间开始看,
- 看中间, fp, fp是一个什么呢?
- 看右边, 右边什么也没有, 遇到括号表示告一段落.
- 看左边, 是一个*, 也就是pointer, 所以fp1是一个函数, 是什么样的函数呢?
- 看右边, (int), 是一个接受一个int为参数的函数指针.
- 看左边, 是一个*, 也就是返回值是一个函数, 是一个什么样的函数呢?
- 看右边, 是[10], 也就是返回一个指针指向一个数组, 这个数组包含10个, 10个什么呢?
- 看左边, 是void*, 哦, 原来是包含10个void*的数组.
that’s it! 用英文更好理解, 因为英文的从句可以让上面这么多步连成一整句话.
(middle) fp1 is → (right, nothing) → (left) a pointer to → (right) a function that takes an int → (left) and returns a pointer to → (right) an array of 10 → (left) void pointers.
连起来就是:fp1 is a pointer to a function that takes an int and returns a pointer to an array of 10 void pointers.
const char *
对于const char* s来说, const char*是指向常数的指针, 而不是指针本身为常量, 不可以被初始化, 该指针可以指向常量也可以指向变量, 只是从该指针的角度而言, 它指向的是常量. s是不变的, s是可以改变的, const 限定的s. s被一个解引用运算符修饰, 故是一个普通的指针, 可以修改, 但是s所指向的数据由于const的修饰不可通过指针s去修改.
char *const
char *const s声明(*const s), (*const s)是char类型的, s被一个解引用运算符和一个const关键词修饰, 故是个不可修改的指针, 但可以通过指针s去修改s所指向的数据