指针

【1】如何理解指针?

指针,就是地址值。强调一点,计算机世界就是对现实的一种精确模拟。那么,既然是模拟,现实中什么是指针呢?嗯,对了,大概你已经想到

了,就是可以等价于你家的门牌号。如果你是一个学生的话,那就是你的座位号;如果你刚买了一座别野(别墅的雅称,其实这个名字更有意义,因

为如果人人都住别墅去了的话,人与人之间就没有那么多的沟通,也就相当于野人了,所以叫“别野”),那么指针就是你家的别野号。

由于现实的地址也是多种多样的,所以在计算机世界里,指针也是很多类别的。

【2】各种指针有何特性?

(1)一般指针

示例代码以及相关分析如下:

 1 #include<iostream>
 2 using namespace std;
 3 
 4 void main()
 5 {
 6     int a = 10;    //定义int型变量a并赋值为10
 7     cout<<"&a="<<&a<<endl;    //输出变量a的地址
 8     int *p = NULL;  //定义指针变量p.此指针变量的类型为int *.也就是指向整型变量的指针。由于暂时不确定指向,赋值空NULL
 9     int *pa = NULL,b;  //这种写法必须要注意:“*”符号只对pa有效,也就是说pa才是指针变量。b是一个整型变量。
10     pa = &a;    //pa这个指针变量指向了a这个整型变量。注意这里有一个类型匹配的问题。即就是:赋值兼容性原则。
11     cout<<"pa="<<pa<<endl;
12     b = 20;
13     *pa = b;
14     //pa的内容就是pa这个指针变量的另外一个值,此句主要是为解释指针的双值性。执行这一句,*pa原来的内容就会变为b变量的值,即就是20。这就是运行结果a=20的依据。
15     cout<<"pa="<<pa<<endl;
16     cout<<"a="<<a<<endl;
17 }
18 //The  result of  this
19 /* 
20 &a=0x0012FF7C
21 pa=0x0012FF7C
22 pa=0x0012FF7C
23 a=20
24 */

(2)函数指针

<1>可以把一个指针声明为一个指向函数的指针。示例代码如下:

1 int   fun1(char *,int);
2 int  (*pfun1)(char *,int);
3 pfun1 = fun1;

声明函数fun1。再声明函数fun1的指针pfun1。注意观察指针的类型以及指针指向的类型。

再给函数指针赋值。注意这里也是必须要遵守赋值兼容原则。

<2>通过函数指针调用函数的两种形式过程说明。示例代码如下:

 1 #include<iostream.h>
 2 int add(int a,int b)
 3 {
 4     return a+b;
 5 }
 6 int max(int a,int b)
 7 {
 8     return a>b? a:b;
 9 }
10 void main()
11 {
12     int (*fun)(int,int);     //函数指针    fun为类型名
13     fun=add;
14     cout<<fun(12,23)<<endl;
15     fun=max;
16     cout<<(*fun)(23,34)<<endl;
17 }
18 /*
19 运行结果:
20 35
21 34
22 */

过程说明:

第十二行:一个函数指针,fun为函数指针变量名。

第十三行:赋值为add函数

第十四行:调用函数fun()。通过指针实现如上所示。

第十五行:赋值为max函数

第十六行:调用函数max()。通过指针实现如上所示。

(3)this指针

面向对象编程的关键是类的设计,而类设计的难处主要在于它是很抽象的,抽象怎么解释呢?

举个生活中的例子。比如说:“XXX,你去给我买两斤水果,回来再给你还钱。”好了,这就是个很具体的例子。

那么,这个水果到底指的是什么东东?是苹果?是梨?是橘子?是......总之,这个概念太抽象了。

但是,水果还真是一个类别,你看大街上什么餐饮店,什么水果超市,什么鞋店。什么书店等等的。

嗯,高度抽象都是有一种共同行为的东西!这就是所有面向对象程序设计书中提到的那个行为的概念。

而所谓的属性是指本身的相关特性。好,既然同一个类中所衍生的对象都是具有相同行为的,只不过属性彼此不同而已。

为了节省空间,方法也就是所谓的成员函数在内存中也就只有一份拷贝。

那么,这也就存在一个问题,各个对象公用一份拷贝的成员函数,到底是哪个对象调用成员函数?就取决于对象的this指针。

其实,在每个成员函数【除过静态的】的参数部分,都有一个隐藏的this指针,而且它是这样子定义的:class * const this

示例代码如下:

 1 #include<iostream.h>
 2 class Test
 3 {
 4 private:
 5     int value;
 6 public:
 7     Test(int x=0):value(x)
 8     {}
 9     ~Test()
10     {}
11     void fun()
12     {      // void fun(Test * const this)
13         cout<<this->value<<endl;
14     }
15 };
16 
17 void main()
18 {
19     Test t1(10),t2(100);
20     t1.fun();
21     // fun(&t1);本质上应该是这样的过程
22     t2.fun();
23     // fun(&t2);本质上应该是这样的过程
24 }
25 //The  result  of  this  
26 /*
27 10
28 100
29 */

【3】关于指针的以下应用分析:

从变量名处起,根据运算符优先级结合,一步一步分析

 1 int   p;  //这是一个普通的整型变量
 2 
 3 int  *p;  //首先从P 处开始,先与*结合,所以说明P 是一个指针,然后再与int 结合,说明指针所指向的内容的类型为int 型.所以P是一个返回整型数据的指针
 4 
 5 int  p[3];  //首先从P 处开始,先与[]结合,说明P 是一个数组,然后与int 结合,说明数组里的元素是整型的,所以P 是一个由整型数据组成的数组
 6 
 7 int  *p[3]; //首先从P 处开始,先与[]结合,因为其优先级比*高,所以P是一个数组,然后再与*结合,说明数组里的元素是指针类型,然后再与int 结合,说明指针所指向的内容的类型是整型的,所以P 是一个由返回整型数据的指针所组成的数组
 8 
 9 int  (*p)[3]; //首先从P 处开始,先与*结合,说明P 是一个指针然后再与[]结合(与"()"这步可以忽略,只是为了改变优先级),说明指针所指向的内容是一个数组,然后再与int 结合,说明数组里的元素是整型的.所以P 是一个指向由整型数据组成的数组的指针
10 
11 int  **p; //首先从P 开始,先与*结合,说是P 是一个指针,然后再与*结合,说明指针所指向的元素是指针,然后再与int 结合,说明该指针所指向的元素是整型数据.由于二级指针以及更高级的指针极少用在复杂的类型中,所以后面更复杂的类型我们就不考虑多级指针了,最多只考虑一级指针.
12 
13 int  p(int); //从P 处起,先与()结合,说明P是一个函数,然后进入()里分析,说明该函数有一个整型变量的参数然后再与外面的int 结合,说明函数的返回值是一个整型数据
14 
15 int (*p)(int); //从P处开始,先与指针结合,说明P 是一个指针,然后与()结合,说明指针指向的是一个函数,然后再与()里的int 结合,说明函数有一个int 型的参数,再与最外层的int 结合,说明函数的返回类型是整型,所以P是一个指向有一个整型参数且返回类型为整型的函数的指针
16 
17 int *(*p(int))[3]; //可以先跳过,不看这个类型,过于复杂
18 //从P 开始,先与()结合,说明P 是一个函数,然后进
19 //入()里面,与int 结合,说明函数有一个整型变量
20 //参数,然后再与外面的*结合,说明函数返回的是
21 //一个指针,,然后到最外面一层,先与[]结合,说明
22 //返回的指针指向的是一个数组,然后再与*结合,说
23 //明数组里的元素是指针,然后再与int 结合,说明指
24 //针指向的内容是整型数据.所以P 是一个参数为一个
25 //整数据且返回一个指向由整型指针变量组成的数组
26 //的指针变量的函数.

 

备注:2012-12-31

posted @ 2012-12-31 18:23  kaizenly  阅读(293)  评论(0编辑  收藏  举报
打赏