指针
一、内存空间的访问方式
1.通过变量名访问
2.通过地址访问
而通过地址访问内存空间往往与指针密切相关
二、地址运算符:&
eg:int var
则&var表示变量var在内存中的起始地址
三、指针与指针变量的概念辨析
指针:内存地址,用于间接访问内存单元
指针变量:用于存放地址的变量
如下图所示:i_pointer(变量)=2000 (变量i的内存地址)
*i_pointer(指针变量)=3 (变量i的值)
*i_pointer=&i (指向变量i的指针)
四、指针的声明与引用
声明
eg: static int i;
static int *i_pointer=&i;
引用
eg: i=3;
*i_pointer=3;
五、指针变量的初始化
存储类型 数据类型 *指针名 = 初始地址;
eg: int *pa = &a;
Tips:
1.用变量地址作为初值时,该变量必须在指针初始化之前已经说明过,且变量类型应与指针类型一致
2.可以用一个已经初始化的指针去初始化另一个指针
以下是指针的声明、赋值与使用实例
#include<iostream>
using namespace std;
int main()
{
int i;
int *ptr = &i;
i=10;
cout<<"i="<<i<<endl;
cout<<"*ptr="<<*ptr<<endl;
return 0;
}
输出结果是 i=10
*ptr=10
六、 指针变量的算术运算和关系运算
1、指针p加上或减去n,其意义是指针当前指向位置 的前方或后方第n个数据的地址
2、指向相同类型数据的指针之间可以进行各种关系运算
3、指针与一般整数变量之间的关系运算是无意义的
七、指向数组元素的指针
1.声明与赋值
eg:int a[10],pa;
pa=&a[0];或pa=a;
2.通过指针引用数组元素
a[i],{pa+i},*(a+i),pa[i]都是等效的
引用数组元素的实例
//使用数组名和下标
#include<iostream>
using namespace std;
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,0};
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}
//使用数组名指针运算
#include<iostream>
using namespace std;
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,0};
for(int i=0;i<10;i++)
cout<<*(a+i)<<" ";
cout<<endl;
return 0;
}
//使用指针变量
#include<iostream>
using namespace std;
int main()
{
int a[10]={1,2,3,4,5,6,7,8,9,0};
for(int *p=a;p<a+10;p++)
cout<<*p<<" ";
cout<<endl;
return 0;
}
输出结果均为1,2,3,4,5,6,7,8,9,0
八、指针数组
1.指针数组就是指数组的元素是指针型;
eg:point *pa[2](包含了pa[0]和pa[1]两个指针)
以下是一个指针数组运用实例
#include<iostream>
using namespace std;
int main()
{
int line1[]={1,2,3};//矩阵第一行
int line2[]={2,3,4};//矩阵第二行
int line3[]={3,4,5};//矩阵第三行
//定义整型指针数组并初始化
int *pline[3]={line1,line2,line3};
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
cout<<pline[i][j]<<" ";
cout <<endl;
}
return 0;
}
九、指针型函数
当函数的返回值是地址时,该函数就是指针型函数。声明形式如下:
存储类型 数据类型 *函数名()
十、函数指针
声明形式如下:
存储类型 数据类型 (*函数指针名)()
以下是一个函数指针的应用实例
#include<iostream>
using namespace std;
void printStuff(float)
{
cout<<"This is the print stuff function."<<endl;
}
void printMessage(float data)
{
cout<<"The data to be listed is "<<data<<endl;
}
void printFloat(float data)
{
cout<<"The data to be printedis "<<data<<endl;
}
const float PI=3.14159f;
const float TWO_PI = PI*2.0f;
int main()
{
void (*functionPointer)(float);//函数指针
printStuff(PI);
functionPointer=printStuff;//函数指针functionPointer指向了函数printStuff的内存地址
functionPointer(PI);//函数指针调用
functionPointer=printMessage;//函数指针functionPointer指向了函数printMessage的内存地址
functionPointer(TWO_PI);//函数指针调用
functionPointer(13.0);//函数指针调用
functionPointer=printFloat;//函数指针functionPointer指向了函数printFloat的内存地址
functionPointer(PI);//函数指针调用
printFloat(PI);
return 0;
}
运行结果如下
十一、对象指针
1.对象指针的声明形式
类名 *对象指针名
2.通过指针访问对象成员
对象指针名->成员名
eg;ptr->getx()
3.this指针
this指针是隐含于每一个类的成员函数中的特殊指针。当通过一个对象调用成员函数时,系统会将成员函数当前操作的对象的地址赋给this指针,因此在成员函数对对象的数据成员进行操作时,就隐含使用了this指针
4.指向类的非静态成员的指针
A。通过指向成员的指针只能访问公有成员
B。声明指向成员的指针
类型说明符 类名::*指针名;(指向公有数据成员)
类型说明符 (类名::*指针名)(形参表);(指向公有函数成员)
5.指向数据成员的指针
指针名 = &类名::数据成员名;(初始化数据成员)
对象名.*类成员指针名 或 对象指针名->*类成员指针名(访问数据成员的方法)
6.指向成员函数的指针
指针名 = &类名::成员函数名;(初始化成员函数)
对象名.*类成员指针名(参数表) 或 对象指针名->*类成员指针名(参数表) (访问成员函数的方法)
以下是访问对象的共有成员函数的一个实例
int main()
{
Point a(4,5);//声明对象A
Point *p1=&a;//声明对象指针并初始化
//声明成员函数指针并初始化
int (Point::*funcPtr)()=Point::getX;
//1.使用成员函数指针访问成员函数
cout<<(a.*funcPtr)()=endl;
//2.使用成员函数指针和对象指针访问成员函数
cout<<(p1->*funcPtr)()=endl;
//3.使用对象名访问成员函数
cout<<a.getX()<<endl;
//4.使用对象指针访问成员函数
cout<<p1->getX()<<endl;
return 0;
}
7.通过指针访问类的静态成员的实例
通过指针访问类的静态数据成员
#include<iostream>
using namespace std;
class Point //Point类定义
{
public(int x=0,int y=0) : x(x),y(y)
{
count++;
}
Point(const Point &p):x(p,x),y(p,y)
{
count++;
}
Point() {count--;}
int getX() const {return x;}
int getY() const {return y;}
static int count;
private:
int x,y;
};
int Point::count=0;
int main()
{
int*ptr=&Point::count;//定义一个int型指针,指向类的静态成员
Point a(4,5);//定义对象a
cout<<"Point A: "<<a.getX()<<","<<a.getY();
cout<<"Object count="<<*ptr<<endl;
Point b(a);//定义对象b
cout"Point B: "<<b.getX()<<","<<b.getY();
cout<<"Object count="<<*ptr<<endl;
return 0;
}
通过指针访问类的静态函数成员
#include<iostream>
using namespace std;
class Point //Point类定义
{
public:
Point(int x=0,int y=0):x(x),y(y)
{
count++;
}
Point(const Point &p):x(p,x),y(p,y)
{
count++;
}
Point() { count--; }
int getX() const {return x;}
int getY() const {return y;}
static void showCount()
{
cout<<"Object count="<<count<<endl;
}
private:
int x,y;
static int count;
};
int Point::count = 0;
int main()
{
void (*funcPtr)()=Point::showCount;
Point a(4,5);//定义对象A
cout<<"Point A: "<<a.getX()<<","<<a.getY();
funcPtr();//输出对象个数,直接通过指针访问静态函数成员
Point b(a); //定义对象B
cout<<"Point B: "<<b.getX()<<","<<b.getY();
funcPtr();//输出对象个数,直接通过指针访问静态函数成员
return 0;
}