如何用指针访问数组元素
定义指向数组元素的指针
定义与赋值
例:int a[10],*pa;
pa=&a[0];或pa=a;
等效的形式
*pa就是a[0],*(pa+1)就是a[1],...,*(pa+i)就是a[i].
a[i], *(pa+i), *(a+i), pa[i] 四种形式都是等效的
指针数组:数组的元素是指针类型
例:Point *pa[2]; 表示有pa[0],pa[1]两个指针组成
#include<iostream>
using namespace std;
int main() {
int line1[] = { 1,0,0 };
int line2[] = { 0,1,0 };
int line3[] = { 0,0,1 };
//定义整形指针数组并初始化
int* pline[3] = { line1,line2,line3 };
cout << "Matrix test:" << endl;
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;
//将实数x分成整数部分和小数部分,形参intpart,fracpart是指针
void splitFloat(float x, int *intpart, float *fracpart) {
*intpart = static_cast<int>(x);//取x整数部分
* fracpart = x - *intpart;//取x小数部分
}
int mian() {
cout << "Enter 3 float point numbers:" << endl;
for (int i = 0; i < 3; i++)
{
float x, f;
int n;
cin >> x;
splitFloat(x, &n, &f);
cout << "Integer part = " << n << "Fraction Part =" << f << endl;
}
return 0;
}
指向常量的指针做形参
#include<iostream>
using namespace std;
const int N = 6;
void print(const int* p, int n);
int main() {
int array[N];
for (int i = 0; i < N; i++)
{
cin >> array[i];
}
print(array, N);
return 0;
}
void print(const int* p, int n) {
cout << "{" << *p;
for (int i = 1; i < n; i++)
{
cout << "," << *(p + i);
}
cout << "}" << endl;
}
指针类型的函数
如果函数的返回值是指针,则该函数就是指针类型的函数。
指针函数的定义形式:
存储类型 数据类型 *函数名(){
//函数体语句
}
PS:不要将非静态局部地址用作函数的返回值,非静态局部地址离开函数后就失效了,返回的话,让主调函数拿着地址去访问空间是一件很危险的事(就好比一个人住完酒店,还带走了房卡钥匙之类的~)
返回的指针要确保在主调函数中是有效,合法的地址
主函数中定义的数组,在子函数中对该数组元素进行某种操作后,返回其中一个元素的地址,这就是合法有效的地址。
#include<iostream>
using namespace std;
int main() {
int array[10];//主函数中定义的数组
int* search(int* a, int num);
for (int i = 0; i < 10; i++)
{
cin >> array[i];
}
int* zeroptr = search(array, 10);//将主函数中数组的手地址传给子函数
return 0;
}
int* search(int* a, int num) { //指针a指向主函数中定义的数组
for (int i = 0; i < num; i++)
{
if (a[i]==0)
{
return &a[i];//返回的地址指向的元素是在主函数中定义的
}
}
}//函数运行结束是,a[i]的地址任有效
在子函数中通过动态内存分配new操作取得的内存地址返回给主函数是合法有效的,但是内存分配和释放不在统一级别,同时要注意不能忘记释放,避免发生内存泄漏。
#include<iostream>
using namespace std;
int main() {
int* newintvar();
int* intptr = newintvar();
*intptr = 5;
delete intptr;//如果在这里忘记释放,会导致内存泄漏
return 0;
}
int* newintvar() {
int* p = new int();
return p;//返回的地址指向的是动态分配的空间
}//函数运行结束时,p中的地址任有效
指向函数的指针
函数指针的定义
定义新式:存储类型 数据类型(*函数指针名)()
含义:函数指针指向的是程序代码存储区
函数指针的典型用途----实现函数回调
1.通过函数指针调用的函数
例如将函数的指针作为参数传递给一个函数,使得在处理相似事件的时候可以灵活的使用不同的方法
2.调用者不关心谁是被调用者
需知道存在一个具有特定原型和限制条件的被调用函数。
#include<iostream>
using namespace std;
int computer(int a, int b, int(*func)(int, int)) { return func(a, b); }
int max(int a, int b) { return((a > b) ? a : b); }
int min(int a, int b) { return((a < b) ? a : b); }
int sum(int a, int b) { return a + b;}
int main() {
int a, b, res;
cout << "请输入整数a:"; cin >> a;
cout << "请输入整数b:"; cin >> b;
res = computer(a, b, &max);
cout << "Max of" << a << "and" << b << "is" << res << endl;
res = computer(a, b, &min);
cout << "Min of" << a << "and" << b << "is" << res << endl;
res = computer(a, b, &sum);
cout << "Sum of" << a << "and" << b << "is" << res << endl;
}
对象指针
对象指针定义形式
类名 *对象指针名;
例:Point a(5,10);
Point *ptr;
ptr=&a;
通过指针访问对象成员
对象指针名->成员名
例:ptr->getx()相当于(*ptr).getx();
#include<iostream>
using namespace std;
class Point
{
public:
Point(int x = 0,int y = 0):x(x),y(y){}
int getX()const { return x; }
int getY()const { return y; }
private:
int x, y;
};
int main() {
Point a(4, 5);
Point* p1 = &a;//定义对象指针,用a的地址初始化
cout << p1->getX() << endl;//用指针访问对象成员
cout << a.getX() << endl;//用对象名访问对象成员
return 0;
}
this指针
隐含于类的每一个非静态成员函数中
指出成员函数所操作的对象
当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针。
例如,Point类的getX函数中的语句:
return x;相当于return this->x;