C++中的指针、数组指针与指针数组、函数指针与指针函数
本文从刚開始学习的人的角度,深入浅出地具体解释什么是指针、怎样使用指针、怎样定义指针、怎样定义数组指针和函数指针。并给出相应的实例演示。接着,差别了数组指针与指针数组、函数指针与指针函数;最后。对最常混淆的引用传递、值传递和指针传递做了区处。
1、指针
程序中全部的变量和常量都存在一个内存地址中,当然,函数也有相应的内存地址,内存地址的不同会导致程序运行时有所不同。
2、怎样定义指针、数组指针、函数指针
常见的指针定义有3种:变量指针、数组指针和函数指针的定义。
(1)、变量指针的定义
int* p=0; //定义指针p。并初始化指针为0。即指向的地址为0000 0000 或 int a=0; //定义初始化常量a int* p; //定义指针p p=&a; //指针p指向a的地址,即指针获取地址
(2)、数组指针的定义
int a[]={0,1,2,3,4,5,6,7,8,9}; //定义数组 int* p=a; //定义并赋值数组指针,即获得数组的首地址
(3)、函数指针的定义
int f(); //定义函数 int (*p)(); //定义函数指针 p=f; //赋值函数指针。即获得函数代码的首地址
差别变量指针、数组指针和函数指针的定义的演示样例代码例如以下。
#include<iostream> using namespace std; int f() //定义一个函数 { cout<<"測试函数指针的使用"<<endl<<endl; return 0; } void main() { cout<<"==========变量指针的使用=========="<<endl; int a=5; int* p=0; //初始化指针为0 int* q; //定义指针 q=&a; //赋值指针 cout<<"a = "<<a<<endl; //变量a的值 cout<<"a = "<<*q<<endl; //变量a的值 cout<<"p = "<<p<<endl; //指针p的地址为0000 0000 cout<<"&a = "<<&a<<endl; //获取a的地址 cout<<"&a = "<<q<<endl; //获取a的地址 cout<<"==========数组指针的使用=========="<<endl; int b[]={0,1,2,3,4,5,6,7,8,9}; int* pb=b; //直接指向第一个元素的地址 cout<<pb<<endl //第1个元素的地址,即数组的首地址 <<b<<endl //第1个元素的地址,即数组的首地址 <<*pb<<endl //第1个元素的值 <<(*pb+2)<<endl; //第3个元素的值 cout<<"==========函数指针的使用=========="<<endl; int f(); //定义函数 int (*pf)(); //定义函数指针 pf=f; //赋值函数指针,即将函数的首地址赋值给指针pf (*pf)(); //通过函数指针调用函数 }
结果例如以下图:
3、数组指针与指针数组
4、函数指针与指针函数
5、引用传递、值传递和指针传递
(1)、值传递
从被调用函数的角度来说,值传递是单向的(实參->形參)。參数的值仅仅能传入,不能传出。当函数内部须要改动參数,而且不希望这个改变影响调用者时。採用值传递。
(2)、指针传递
(3)、引用传递
形參相当于是实參的“别名”,对形參的操作事实上就是对实參的操作。在引用传递过程中,被调函数的形式參数尽管也作为局部变量在栈中开辟了内存空间,可是这时存放的是由主调函数放进来的实參变量的地址。被调函数对形參的不论什么操作都被处理成间接寻址。即通过栈中存放的地址訪问主调函数中的实參变量。
正由于如此,被调函数对形參做的不论什么操作都影响了主调函数中的实參变量。
最后,总结一下指针和引用的同样点和不同点:
同样点:
不同点:
指针是一个实体,而引用仅是个别名;
引用仅仅能在定义时被初始化一次,之后不可变。指针可变。引用“从一而终”,指针能够“见异思迁”;
引用没有const,指针有const,const的指针不可变;(详细指没有int& const a这样的形式,而const int& a是有的,前者指引用本身即别名不能够改变,这是当然的,所以不须要这样的形式。后者指引用所指的值不能够改变)
引用不能为空。指针能够为空;
“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小。
指针和引用的自增(++)运算意义不一样;
引用是类型安全的,而指针不是(引用比指针多了类型检查)。