C++(8):指向不同类型变量或函数的pointer

来源:互联网 发布:淘宝如何导出买家信息 编辑:程序博客网 时间:2024/04/29 11:48

引言


pointer,有时候还是会很让人困扰。简单的还好,int * pt; 复杂一点,int ** pt; 还有什么 void * pt;
本文稍微总结一下,指向不同类型的变量或函数的指针。
如,指向int型变量的,指向int*的,指向char的,char*的,指向void型的,
int * 型数组,char * 型数组,
指向普通函数的,指向成员变量的,指向成员函数的指针…

指向int型的指针


这个不用多说。
int i = 3;int * p1 = &i;int * p2;p2 = &i;
注意。
1. *在声明时出现和后面使用的时候是有区别的。声明时,是说这是个指针;以后使用时,是解引用dereference。
2. &在声明时出现和后面使用的时候,也有区别。声明时,是说这是某个东西的引用;以后使用时,是去取这个东西的地址。
3. i有一个地址,存在了p1和p2里,p1和p2的值即为i的地址。
4. *p1和*p2是解引用,相当于i。可以输出*p1,是3,也可以通过*p1修改i的值。
5. p1和p2本身都有地址,即&p1和&p2。

另外,int * iArray是可以指向一个int型数组的。
int iArray[3] = {1,2,3};int * pt = iArray;*(pt + 2) = 0; // 相当于 iArray[2] = 0;*(pt+3) = 0; // 越界

指向int*型的指针


两重指针,两颗星。
int i = 3;int * p1 = &i;int ** p2 = &p1;
数清楚几颗星就好。
另外, int ** iMat 可以指向一个二维数组。确切地说,是指向一个int *型数组。

int*型数组

int iArray1[4] = {1,2,3,4};int iArray2[3] = {1,2,3};int iArray3[5] = {1,2,3,4,5};int * iMat[3] = {iArray1,iArray2,iArray3};
可以用int*型数组创建一个矩阵。也可以用int ** 创建一个矩阵。

指向char型的指针


char后面跟着一个星星。可以指向一个char型变量。
char ch = 'a';char * pt1 = &ch;
*pt1就是ch了。输出是'a',也可以修改ch的值,e.g. *pt1 = 'c';

另外i,char * pt可以指向一个C语言风格的字符串。(一个char型数组,末尾有'\0')
char * pt2 = "abcd";


char*型数组


和int*数组类似。
char * cPtArray[3] = {"I","love","music"};for (int i = 0;i<3;i++){cout<<cPtArray[i]<<endl;}
屏幕上将输出

I
love
music


指向char*型的指针


两个星星。可以指向一个字符串数组。
char * pt3[3] = {"abc","fudan","university"};char ** pt4 = pt3;for (int i = 0;i<3;i++){cout<<pt4[i]<<endl;}
屏幕上将输出:
abc
fudan
university

指向void型的指针

int i = 3;double d = 4.5;void * pt;pt = &i; // 先指向一个int型变量// cout<<*pt<<endl; // 报错!不能直接解引用!cout<<*(int*)pt<<endl; // 要先强制转型成指向某种类型的指针,才能解引用。pt = &d;  // 再指向一个double型变量cout<<*(double*)pt<<endl;cout<<*static_cast<double*>(pt)<<endl;
屏幕上将输出:
3
4.5
4.5

指向普通函数的指针


在C++中,普通函数的函数名是函数地址。
为什么会有函数指针呢?
以下内容摘自百度百科。

函数指针是指向函数的指针变量。 因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如前所述,C在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在这些概念上是大体一致的。函数指针有两个用途:调用函数和做函数的参数

就我目前的知识储备而言,在windows程序设计,装载完动态链接库(DLL)以后,调用DLL里的函数,函数指针似乎就看出函数指针的作用了。(调用函数)

A function block also occupies memory space
–placed at Code Section
–has its own address
指向普通函数的指针,写法是这样的。
函数返回数据的数据类型 (指针名*) (形参列表);

rtn_type (*pFun)(para_list);

e.g. 一个指向
int fun1(int a, char * c);
的函数指针,在声明的时候,要这样写
int (*fp1) (int a, char * c);
注意:
1. 返回值要对上;
2. *和fp1要用括号括起来;
3. 形参数据类型要一模一样,一一对应;(假设函数调用的时候,参数进栈方式相同)
给fp1赋值的时候,要这样写
fp1 = fun1;// 或 fp1 = &fun1;
两种写法,对于指向普通的函数的函数指针来说,都是可以的。
在通过函数指针调用函数的时候,要这样写成这种形式
fp1(3,"China");// 或 (*fp1) (3,"China");

指向成员变量的指针


指向成员变量的指针,和指向普通的变量的指针,最大的不同之处就在于,指针类型不同。
指向成员变量的指针,在声明的时候,一定要加上类的界定符号!在定义或在赋值,
对该指针即将指向的那个成员变量取地址的时候,也要在&的后面加上类的界定符号!

datatype (CName::* pName);
pName = &CName::data_member;

比如,有个CA类。
class CA { public:    int i;}
指向A中的i的指针,要写为
int CA :: * pt1 = & CA :: i;
好诡异的写法。这是规定。注意,这里的int i还是public修饰的,不然后面点不出来啊…
在解引用的时候,也要通过某个obj一点把它点出来再解引用。
CA obj;obj.*pt1 = 3; //相当于是 obj.i = 3;

指向成员函数的指针


和指向成员变量的指针类似,在声明、定义或引用的时候,都要加上类的界定符号!
class CA {public:   int fun1( int x, int y, char c);}
那指向CA中fun1的函数指针要这么声明
int ( CA :: * fp1)  (int x, int y, char c);
赋值则要这么写
fp1 = & CA::fun1;
注意,这里一定要有取地址的符号!一定要有&符号!!
使用fp1,则要通过某个obj.出来
CA obj;obj.*fp1(3,4,'a');
一点“.”,给人看起来就像是obj的成员,
还要取*,因为是指向函数的指针,要使用这个函数,需要解引用。
member functions are not put at the space of objects but that all class objects share.
尽管某个class的成员函数是该类的所有的obj实例都享有,但是调用class里的成员函数,
除了public修饰外,没有更多的修饰字,现在看起来,似乎,都只能通过具体的对象来获得。
不能通过某个class的类名,直接取出来用。(static修饰的函数,是可以的…)

至于更多详细的关于class的内容,包括this指针、static修饰字等更多细节的内容,我会在以后的文章中总结。
谢谢观赏!











0 0
原创粉丝点击