当前位置:
文档之家› C++ 指针函数和函数指针有什么区别
C++ 指针函数和函数指针有什么区别
C++ 指针函数和函数指针有什么区别
这两个概念都是简称,指针函数是指带指针的函数,即本质是一个函数。我们知道函数都有返回 类型(如果没有返回值,则为无值型) ,只不过指针函数返回类型是某一类型的指针(返回的是 地址) 。 返回类型标识符 *返回名称(形式参数表) { 函数体 } 返回类型可以是任何基本类型和复合类型。 事实上每一个函数,即使它不带有返回某种类型的 指针,它本身都有一个入口地址,该地址相当于一个指针。比如函数返回一个整型值,实际上也 相当于返回一个指针变量的值, 不过这时的变量是函数本身而已, 而整个函数相当于一个 “变量” 。 例如下面一个返回指针函数的例子(VC++ 编译通过) : #include <iostream> using namespace std; int main() { float *find(float(*pionter)[4],int n); static float score[][4]={{60,70,80,90},{56,89,34,45},{34,23,56,45}}; float *p; int i,m; printf("Enter the number to be found:"); scanf("%d",&m); printf("the score of NO.%d are:\n",m); p=find(score,m); for(i=0;i<4;i++) printf("%5.2f\t",*(p+i)); return 0; } float *find(float(*pionter)[4],int n)/*定义指针函数*/ { float *pt; pt=*(pionter+n); return(pt); } 学生学号从 0 号算起,函数 find()被定义为指针函数,形参 pointer 是指针指向包含 4 个元素 的一维数组的指针变量。pointer+1 指向 score 的第一行。*(pointer+1)指向第一行的第 0 个元 素。pt 是一个指针变量,它指向浮点型变量。main()函数中调用 find()函数,将 score 数组的 首地址传给 pointer. 2,“函数指针”是指向函数的指针变量,因而“函数指针”本身首先应是指针变量,只不过该指 针变量指向函数。这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数。如 前所述,C 在编译时,每一个函数都有一个入口地址,该入口地址就是函数指针所指向的地址。 有了指向函数的指针变量后, 可用该指针变量调用函数, 就如同用指针变量可引用其他类型变量 一样,在这些概念上一致的。函数指针有两个用途:调用函数和做函数的参数。 数据类型标志符 (*指针变量名) (参数) 。 下面的程序说明了函数指针调用函数的方法(VC++ 编译通过) : int max(int x,int y){ return(x>y?x:y); } void main() { 1
4
cout<<"Declaration [int (*p2arr)[2]=&arr] type=="<<typeid(p2arr).name()<<endl; return 0; } 运行的结果如下:(前面加了行号#XX) #01 Declaration [int vInt=10] type==int #02 Declaration [arr[2]={10,20}] type==int * #03 Declaration [int *p=&vInt] type==int * #04 Declaration [int **p2p=&p] type==int * * #05 Declaration [int *parr[2]={&vInt,&vInt}] type==int ** #06 Declaration [int (*p2arr)[2]=&arr] type==int (*)[2] #02, 在编译器看来数组只是相对应类型的指针类型。 当把数组传递给函数作为参数的时候,传递的是指针,所以可以利用参数来修改数组元素。这个转化是编 译器自动完成的。也就是说这里编译器自动完成了 int[]类型到 int *的转化, void f(int[]); int a[2]={10,20}; f(a);//这行等价于编译器完成的函数转化 f(int *p) #05:指针数组的编译器内部表示也是对应类型的指针。 #06 数组指针的编译器内部表示就是有一点特别了。 编译器(或者说是语言本身)有数组指针这个内部表示。 由于 c++语言的类型严格检查的语言(当然还有一些是存在隐式类型转化的) 所以我们下面的写法是不能编译通过的。 { int arr[3]={10,20};//注意是 3 个元素数组 int (*p2arr)[2]=&arr;//注意是指向 2 个元素数组的指针 } 小结 关于数组和指针的转化,以及我们使用指针(++,--)等来操作数组,是基于数组在内存中是连续分布的。 看到这里就会明白下面的程序为什么会运行的了。 我这里也把下面的程序作为今天内容的总结: #include <iostream> using namespace std; int main() { int a[2]={10,20}; int *p=a;//根据上面说明,由于编译器的参与,两者类型转化后一致 int vInt=10,vInt1=11; int *parr[2]={&vInt,&vInt1}; int **p2p=parr;//上面分析,类型一致 cout<<*parr[0]<<" "<<*parr[1]<<endl; cout<<*(*p2p)<<" "<<*(*(p2p+1)) <<endl; return 0; } 输出结果 cout<<*parr[0]<<" "<<*parr[1]<<endl; ----------10 11 cout<<*(*p2p)<<" "<<*(*(p2p+1)) <<endl;------10 11
int*p[n]------p 是一个指针数组,它由 n 个指向整型数据的指针元素组成 (含有 n 个指针元素) int (*p)[n]----- p 是一个指针(数组指针),指向 int[n]的数组(它指向一个由 n 个 int 元素构成的数组) #include <iostream> using namespace std; int main() { int *p[4]; int a=1,b=2,c=3,d=4; p[0]=&a; p[1]=&b; p[2]=&c; p[3]=&d; int (*pp)[4]; //pp[0]=&a;//error int aa[4]={5,6,7,8}; pp=&aa; // 换成 aa 是错误的,定义的 pp 元素个数要与 aa 相同才可以赋值 cout<<*(p[0])<<" "<<*(pp[0])<<endl; return 0;
指针函数应用举例:建立链表,插入,删除接点
#include <iostream> using namespace std; #define NULL 0 struct student {long num; float score; student *next; }; int n; int main() { student *creat(void); student *del(student *,long); student *insert(student *,student *); void print(student *); student *head,*stu; long del_num; cout<<"input records:"<<endl; head=creat(); //返回头指针 print(head); //输出全部结点 cout<<endl<<"input the deleted number:"; cin>>del_num; //输入要删除的学号 while(del_num!=0) {head=del(head,del_num); //删除后链表的头地址 print(head); //输出全部结点 cout<<"input the deleted number:"; cin>>del_num; } cout<<endl<<"input the inserted record:"; //输入要插入的结点 stu=new student; //开辟一个新结点 cin>>stu->num>>stu->score; while(stu->num!=0) {head=insert(head,stu); //返回地址 print(head); //输出全部结点 cout<<endl<<"input the inserted record:"; //输入要插入的结点 stu=new student; cin>>stu->num>>stu->score; } return 0; 2
int *p[n] 与 int(*p)[n]区别tream> #include <typeinfo> using namespace std; int main() { int vInt=10; int arr[2]={10,20}; int *p=&vInt; int **p2p=&p; int *parr[2]={&vInt,&vInt}; int (*p2arr)[2]=&arr; cout<<"Declaration cout<<"Declaration cout<<"Declaration cout<<"Declaration cout<<"Declaration [int vInt=10] type=="<<typeid(vInt).name()<<endl; [arr[2]={10,20}] type=="<<typeid(arr).name()<<endl; [int *p=&vInt] type=="<<typeid(p).name()<<endl; [int **p2p=&p] type=="<<typeid(p2p).name()<<endl; [int *parr[2]={&vInt,&vInt}] type=="<<typeid(parr).name()<<endl;