Chinaunix首页 | 论坛 | 博客
  • 博客访问: 142003
  • 博文数量: 25
  • 博客积分: 100
  • 博客等级: 中士
  • 技术积分: 310
  • 用 户 组: 普通用户
  • 注册时间: 2011-05-03 18:56
文章分类

全部博文(25)

文章存档

2012年(4)

2011年(21)

分类: C/C++

2011-06-20 22:26:57

一)声明的解析顺序
====================================================================
C编译器对于变量、数组、函数的声明有一个比较健壮的解析子函数,在很多C的文献里都有流程图,但是这个么一个复杂的流程图一来是记不住,二来是就算记住了用这个流程图来分析声明岂不是慢死了。其实我们只需要结合括号参照最简单的格式,一点点分解,同时记住几个特别的规律就可以了:
1.第一步是找符号,也就是变量或者函数名。
2.然后就是根据最外层括号的格式判断是变量、函数还是数组。
3.分析所有*的作用对象(遵循最大一口原则,也就是尽可能的作用于右边的符号)
4.static 和 类型符号如int 等等始终是连在一起的
5.最后是volatile 和 const 关键字的作用对象,他们优先作用于左边的类型符号或者*符号

下面结合两个例子来分析一下:

例子1:char * const *(*next)();

1.首先找出符号是next;
2.然后根据整体结构判断这是一个函数声明,无参数,返回值是char * const *;
3.然后分析*符号,发现next是指向函数的指针。返回值是指向char类型的指针的指针;
4.最后分析const关键字,发现左边有*,于是表示指向char的这个指针是个常量,而指向该指针的指针和char本身都不是常量。

例子2:char *(* c[10])(int **p);

1.首先找出符号是c;
2.然后判断这是一个函数声明,根据c[10]判断这是一个函数数组声明;
3.分析* 符号发现c是函数指针数组;函数参数是指向指向int指针的指针,返回值char *类型;
4.没有volatile或者const 需要分析。

有了这两个例子基本就能指导所有的分析了,下面尽可能多的列出各种声明的组合:
  1. int a; // 整型
  2. int *a; // 指向整形的指针
  3. int **a; // 指向整形指针的指针
  4. int a[10]; // 整型数组
  5. int *a[10]; // 整数指针的数组
  6. int (*a)[10]; // 整型数组,a为指向该数组的指针

  7. int (*a)(int); //指向函数的指针
  8. int (*a[10])(int); // 指向函数的指针数组

  9. int orange = 0;// 整型变量
  10. const int apple = 1;// 整型常量
  11. int const banana = 2;//整型常量
  12. const int *cherry = &apple;//指向整型常量的指针
  13. int const *lichee = &apple;//指向整型常量的指针
  14. int * const melon = &orange;//指向整型变量的指针常量
  15. int const * const nut = &apple;//指向整型常量的指针常量
二)const 和 static的陷阱
====================================================================
static在不同的语境下有两种不同的含义:
1.在函数内部,static的变量在多次调用函数是不会重新分配空间、初始化,也就是说下一次调用时变量值还是上一次函数返回时的变量值;
2.在函数体外部声明的函数或变量仅在该源文件文本中的函数才能引用。例如:

  1. static1.c

  2. #include <stdio.h>
  3. static int apple;
在其他文件中就不能使用extern来引用apple,确切的说是apple不可见。如果声明extern int apple,会得到一个警告: undefined reference to `apple'。但是这并不意味着其他文件中的函数完全无法访问apple这个变量,apple还是一个全局变量,声明为static只是为了让编译器限制外部引用的行为。如果其他文件中的函数获得了apple的地址,依然可以访问他。如下示例:
  1. static1.c
  2. #include <stdio.h>
  3. static int apple;

  4. int *func(){
  5.     apple = 1;
  6.     printf("func : the value of int is %d\n",apple);
  7.     return &apple;
  8. }
  1. static2.c
  2. #include <stdio.h>

  3. extern int *func();

  4. main(){
  5.     int *papple = func();
  6.     printf("main : the value of int is %d\n",*papple);
  7. }
输出结果:
func : the value of int is 1
main : the value of int is 1

同样对于const也存在这样的情况,只要获取一个const变量的指针,并对其相应地址赋值,就能改变所谓常量的值。例如:
  1. #include <stdio.h>

  2. void main(void)
  3. {
  4.     const int apple = 1;
  5.     int * pApple = (int *)&apple;

  6.     *pApple = 2;
  7.     printf("%d\n",apple);
  8. }
结果apple = 2

PS:参考《C专家编程》

阅读(1204) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~