复杂指针读法

 
C代码 复制代码
  1. int a;      // 一个整形   
  2.   
  3. int * a;    // 一个指针, 批向一个整形 (整形指针)   
  4.   
  5. int * a();  // 一个函数, 反回一个整形指针   
  6.   
  7. int * a[10];  // 一个数组, 里面存放着整形指针   
  8.   
  9. int (*a)();  // 一个指针, 指向一个函数, 该函数返回整形   
  10.   
  11. int (*a)[];   // 一个指针, 指向一个数组, 数组里放着整形  



上面的问题不大哦, 下面先给出读的方法

左向右看, 找到第一个标识符,上例中就是 a
  1.先往右看, 如果是 [..] 那么 读作"a 是一个数组", 接下来的东西,就是数组元素的类型,和大小了,如果是 "(...)"  那么就是一个函数, 剩下的就是描述函数的参数返回值了。遇到右括号就往左。
  2.再往左看, 如果前缀是 * 那么读作 "a 是一个指针", 接下来分析指向什么

  3.读过的就用XX替换掉,并把XX当做标识符,重复上面的步骤,直到确定变量类型。

 

C代码 复制代码
  1.   
  2. int * a();  // 从左向右看, 找到a, 再向右看, 是(), 那么"a是一个函数",    
  3.             // 参数? 无, 返回值? int *, 哦, 是一个整形指针   
  4.   
  5. int * a[10];  // 从左向右看, 找到 a, 再向右看, 是 [], 那么 "a 是一个数组"   
  6.               // 大小? 10, 类型? int *, 还是整形指针   
  7.   
  8. int (*a)();  // 找到a, 被括号括住, 只能向左看, 是 *, 那么 "a 是一个指针"   
  9.             // 指向什么? 去掉分析过的部分, int XXX(), 哦, 是一个函数   
  10.   
  11. int (*a)[10];  // 同样, "a 是一个指针",    
  12.                // 指向什么? 去掉分析过的部分是? int XXX[10], 指向一个数组  




来几个复杂一点的.

C代码 复制代码

    int * * (*a)();  



从左向右看, 找到第一个标识符, a , 被括号括住了, 往左看, 是 *, 读作"a 是一个指针"

指向什么? int ** XXX(); 哦, 是一个函数

参数是? 空

返回值: int **, 哦~~

合起来就是: a 是一个指针, 该指针指向一个函数, 这个函数返回一个指针(返回的这个指针指向一个整形指针)


再来一个:

C代码 复制代码

char *(*c[10])(int **p);             // 这个例子来自于Expert C Programming  



一眼看过去想晕

没事.

从左到右找到了第一个标识符, c, 再往右看, 是[], 读作 "c 是一个数组" 

数组的元素是什么

先去掉分析过的部分是 char *(*XXX)(int **p)

哦, XXX处开始, 往右看不下去, 往左看, 是*,  那么 "数组的元素是一个指针", 指向什么呢?

再去掉分析过的部分, char *XXX(int **p);  到这一步基本上一眼就能看出了, 就不多废话了

原来是指向一个函数: 这个函数的参数是 int **p, 返回值是 char *


合起来就是: c是一个数组, 这个数组大小是 10, 这个数组里面存放着 指针, 是一个函数指针, 这个函数

指针的参数是 int **p, 返回值是 char *

呵呵。 很容易吧!


等等, 加入const 好像更晕

"const在指针左边修饰类型, 在指会右边,修饰指针"

C代码 复制代码
  1. const int * a;  // 指针指向的整形是 const的   
  2. int * const a;  // 指针a 是 const的  




声明中还可以加typedef哦

一般是

typedef xxxxxxxxxxxxx;

xxxx 的读取方法和上面的一模一样, 但仅仅引入一个新的名字,而不是为变量分配空间

要读的话, 可以读作“a 表示一个...”, 而不是 "a 是一个...."


用 typedef 可以让我们轻松好多, 可以让我们一眼看出申明,或定义的东西

上面看过的这个复杂的东西:char *(*c[10])(int **p);

可以变成这样

typedef char * (*fun_ptr)(int **p);   //fun_ptr 表示一个函数指针, 用上述规则看

那么上面的东东就是:
fun_ptr c[10];      // 一眼就能看出来了,里面是 fun_ptr


最后一个例子:

void (*signal(int sig, void(*func)(int)))(int);   // 这个例子来自于Expert C Programming


从左往右看, 找到 signal, 再往右看, 是(...)   "signal 是一个函数"


参数是什么? 看括号里面的 ( int sig, void(*func)(int) ) 有两个参数, 第一个是 int, 第二个是  void (*func)(int), 是一个函数指针。

返回值是什么? 先去掉分析过的部分, 变成 void (*XXXX)(int) ,  返回值是一个函数指针, 看,上面的第二个参数一样。


合起来就是: signal是一个函数, 参数有两个, 一个是int ,还有一个是 函数指针, 返回值是一个函数指针 。



当然,typedef 后会比较直观


C代码 复制代码
  1. typedef void (*func_ptr)(int);    //给函数指针一个名字   
  2.   
  3. func_ptr signal(int, func_ptr);   // 现在一看就明白了  

总结:首先要确定第一个标识符的类型是什么,基本上有三种情况,是指针就接着分析指向什么类型,是数组就接着分析大小和元素类型,是函数就接着分析参数和返回值类型。把分析过的换乘XX,按照同样的步骤继续分析下去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值