http://blog.csdn.net/lwbeyond/article/details/6180640
一. 解读复杂指针声明
右左法则:首先从标识符开始阅读,然后往右看,再往左看。每当遇到圆括号时,就应该调转阅读方向。一旦解析完括号里所有的东西,就跳出括号。重复这个过程直到整个声明解析完毕。
[cpp] view plaincopyprint?
  1. int *a[10]
  2. // 首先 a 右边是[],说明 a 是一个具有10个元素的数组
  3. // 其次 a 左边是 int*,说明 a 的元素是 int 类型的指针
  4. int (*a)[10]
  5. // 首先 a 左边是一个 * 号,说明 a 是一个指针
  6. // 跳出括号,右边是 [], 说明 a 是一个指向具有10个元素的数组的指针
  7. // 左边是 int,说明元素的类型是 int
  8. int (*func)(int *p);
  9. // 首先找到 func,它左边是一个 * 号,这说明 func 是一个指针
  10. // 然后跳出这个圆括号,先看右边,也是个圆括号,这说明 (*func) 是个函数,而 func 是指向这个函数的指针
  11. // 这个函数具有 int* 类型的参数,返回值类型为 int
  12. int (*func[5])(int* p)
  13. // 首先找到 func, 右边是[],说明 func 是一个具有5个元素的数组
  14. // 其次 func 左边有一个 *,说明 func 的元素是指针,要注意 * 不是修饰func的,而是修饰 func[5]的
  15. // 跳出这个括号,右边也是一个括号,说明 func 数组的元素是函数类型的指针
int *a[10]
// 首先 a 右边是[],说明 a 是一个具有10个元素的数组
// 其次 a 左边是 int*,说明 a 的元素是 int 类型的指针
int (*a)[10]
// 首先 a 左边是一个 * 号,说明 a 是一个指针
// 跳出括号,右边是 [], 说明 a 是一个指向具有10个元素的数组的指针
// 左边是 int,说明元素的类型是 int
int (*func)(int *p);
// 首先找到 func,它左边是一个 * 号,这说明 func 是一个指针
// 然后跳出这个圆括号,先看右边,也是个圆括号,这说明 (*func) 是个函数,而 func 是指向这个函数的指针
// 这个函数具有 int* 类型的参数,返回值类型为 int
int (*func[5])(int* p)
// 首先找到 func, 右边是[],说明 func 是一个具有5个元素的数组
// 其次 func 左边有一个 *,说明 func 的元素是指针,要注意 * 不是修饰func的,而是修饰 func[5]的
// 跳出这个括号,右边也是一个括号,说明 func 数组的元素是函数类型的指针
二. 数组首地址 a, &a, &a[0]
int a[10]
1. a 作为右值时,代表数组首元素的首地址,而非数组首地址。
也就是 a[0] 的地址。int i = *(a+1),这里a是右值,所是代表首元素的首地址,a+1代表下一个元素的首地址,即&a[1]。

2. a 是整个数组的名子
所以 sizeof(a) 的值为 size(int) * 10 = 40,代表整个数组的大小。

3. & a 即为取 a 的首地址,也即是整个数组的首地址
所以 sizeof(&a) 的值为 4。
但是在VC6.0里显示的是40,这是不对的。code:block里显示的是4。
int * p = (int*)(&a+1) 中 &a+1 代表下一个数组的首地址,显然是越界的。

4. & a[0] 代表首元素的首地址
所以 sizeof(&a[0]) 的值为 4。

5. &a[10] 很显然,数组越界了,但是他的sizeof是多少呢?
也是4,因为关键字sizeof求值是在编译的时候,虽然并不存在a[10]这个元素,但是这里并没有真正访问a[10],而是根
据数组元素的类型来确定其值。所以sizeof(a[10])不会出错。

6. a[-1]代表什么意思?
首先要明白下标的形式被编译器解析成指针的形式,即a[1] 解析成 *(a+1),那么a[-1]就被解析成*(a-1)。
三. 指针数组 & 数组指针
指针数组首先它是一个数组,数组的元素都是指针,也称为"储存指针的数组"。
数组指针首先它是一个指针,它指向一个数组。也可以理解为"数组的指针。"
int *p1[10]
int (*p2)[10]
各代表什么?要弄清这个问题,首先要知道[ ]优先级比*要高
p1先与[ ]结合,构成一个数组定义,数组名为p1,int*修饰的是数组的内容,即数组的每个元素。
p2中()的优先级比[ ]高,所以*号先与P2构成一个指针的定义,指针变量名为P2,int修饰的是数组的内容,即数组的每个元素。数组在这里没有名子。
四. 函数指针 & 指针函数
函数指针:指向函数的指针变量。
指针函数:带指针的函数,也就是返回指针的函数。
[cpp] view plaincopyprint?
  1. char * fun(char* a, char* b) //定义为 指针函数
  2. {...... }
  3. int main()
  4. {
  5. char* (*p)(char* p1, char* p2); //定义为 函数指针
  6. p = &fun; //把函数地址赋给他
  7. //p = fun; //这样写也行
  8. (*p)("aa", "bb"); //使用函数指针
  9. return 0;
  10. }
char * fun(char* a, char* b)  //定义为 指针函数
{......  }
int main()  
{  char* (*p)(char* p1, char* p2); //定义为 函数指针  p = &fun; //把函数地址赋给他  //p = fun;  //这样写也行(*p)("aa", "bb"); //使用函数指针  return 0;  
}

五. 指针常量 & 常量指针
[cpp] view plaincopyprint?
  1. const char* p1; //常量指针,指向常量的指针
  2. char const* p2;
  3. char* const p3; //指针常量,指针是常量
const char* p1; //常量指针,指向常量的指针
char const* p2;
char* const p3; //指针常量,指针是常量
怎么记?
a. 可以先把类型名去掉,然后看 const 离谁近,就修饰谁。
b. 也可以const 在 * 左边的为常量指针,const 在 * 右边的为指针常量。
六. 野指针
野指针是怎么造成的?
1. 指针变量被创建而没有初始化。
2. 指针 p 被 free 或者 delete 之后, 没有置为 NULL。
指针 C/C++

0

收藏

上一篇:c/c++中typedef详解 下一篇:spriter动画编辑器的coc...
noavatar_middle.gif
zswnet

144篇文章,51W+人气,0粉丝

关注