以指针操作二维数组非常典型,可检验我们的“指针功力”。本文介绍分别使用 单个指针变量(T *p
)、二维数组指针变量(即专有指针,T (*p)[N]
)、指针数组(T *p[N]
)、二级指针(T **p
)操作二维数组——以打印输出为例。
1 辅助函数
本文涉及的辅助函数为:将十六进制地址转化为十进制地址,其函数原型为extern int hex2dec(int *p);
,实现细节如下:
#include <sstream>
#include "func.h"//头文件
using namespace std;
namespace MySpace
{
extern int hex2dec(int *p)
{
stringstream ss;
ss << p;
string s = ss.str();
int count = s.length(), sum = 0;//十进制地址
for (int i = count - 1; i >= 0; i--)//个位开始转换
{
if (s[i] >= '0'&&s[i] <= '9')//数字
{
sum += (s[i] - 48)*pow(16, count - i - 1);
}
else if (s[i] >= 'A'&&s[i] <= 'F')//字母
{
sum += (s[i] - 55)*pow(16, count - i - 1);
}
}
return sum;
}
}
注意:由于涉及储存地址,每次程序运行结果可能不同。
2 指针变量操作二维数组
程序如下:
#include <iostream>
#include "func.h"
using namespace std;
using namespace MySpace;
int main()
{
/*
@指针变量操作二维数组
*/
int a[2][3] = { 1,2,3,4,5,6 };
cout << "行址a(hex):" << a << ";行址a(dec):" << hex2dec(*a) << endl;
cout << "列址a[1](hex):" << a[1] << ";a[1](dec):" << hex2dec(a[1]) << endl;
cout << "元素址&a[1][2](hex):" << &a[1][2] << ";元素址&a[1][2](dec):" << hex2dec(&a[1][2]) << endl;
cout << "————————————————————" << endl;
cout << "所有元素所占空间(字节):" << sizeof(a) << endl; //所有:4*6=24(字节)
cout << "一行元素所占空间(字节):" << sizeof(a[0]) << endl; //一行:4*3=12
cout << "一个元素所占空间(字节):" << sizeof(a[0][0]) << endl; //一个:4*1=4
cout << "————————————————————" << endl;
int *p = a[0]; //p为单个指针,元素级变化,应赋列址
cout << "p+3:" << p + 3 << endl; //&a[1][0]
cout << "a[0]+1:" << a[0] + 1 << endl; //&a[0][1]
cout << "p+3-&a[0][1](十六进制):" << (p + 3) - (&a[0][1]) << endl; //2元素
cout << "p+3-&a[0][1](十进制):" << hex2dec(p + 3) - hex2dec(&a[0][1]) << endl; //8字节
cout << "————————————————————" << endl;
//单个指针变量输出二维数组
for (int i = 0; i < 2; i++)
{
//指针使用的本质:首地址+空间偏移量
for (int j = 0; j < 3; j++)
cout << "地址:" << hex2dec(p + i * 3 + j) << " " << "值:" << *(p + 3 * i + j) << endl; //也证明了“行优先”
//cout << "地址:" << hex2dec(p++) << " " << "值:" << *(p - 1) << endl; //指针自增
cout << endl;
}
getchar();
return 0;
}
结果如下:
3 二维数组指针变量操作二维数组
程序如下:
#include <iostream>
#include "func.h"
using namespace std;
using namespace MySpace;
int main()
{
/*
@二维数组指针变量(专有指针)操作二维数组
*/
int a[][3] = { 1,2,3,4,5,6 };
int(*p)[3] = a; //p是行指针
cout << "首地址(dec):" << hex2dec(*p) << "=" << hex2dec(*a) << endl;
cout << "行指针变化则一行(列个):" << hex2dec(*(p + 1)) - hex2dec(*p) << endl; //3元素=12字节
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << "地址:" << hex2dec(*(p + i) + j) << " " << "值:" << p[i][j] << endl;
cout << endl;
}
getchar();
return 0;
}
结果如下:
4 指针数组操作二维数组
程序如下:
#include <iostream>
#include "func.h"
using namespace std;
using namespace MySpace;
int main()
{
/*
@指针数组操作二维数组
*/
int a[2][3] = { 1,2,3,4,5,6 };
int *p[2] = { a[0],a[1] };
cout << "p[1]-p[0]:" << hex2dec(p[1]) - hex2dec(p[0]) << endl; //12字节
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
cout << "地址:" << hex2dec(p[i] + j) << " " << "值:" << p[i][j] << endl;
cout << endl;
}
getchar();
return 0;
}
结果如下:
5 二级指针操作二维数组
程序如下:
#include <iostream>
#include "func.h"
using namespace std;
using namespace MySpace;
int main()
{
/*
@二级指针操作二维数组
*/
int a[2][3] = { 1,2,3,4,5,6 };
int **p, *q; //单个指针过渡(也可用指针数组)
for (int i = 0; i < 2; i++)
{
q = *(a + i); p = &q;
for (int j = 0; j < 3; j++)
cout << *(*p + j) << " ";
cout << endl;
}
getchar();
return 0;
}
结果如下:
那么,能不能将a赋给p呢(int **p=a
)?答案是:不能!p是二级指针,应存放地址的地址,但a是地址(行地址),所以需要强制转换:int **p=(int * *)a
。
#include <iostream>
#include "func.h"
using namespace std;
using namespace MySpace;
int main()
{
/*
@二级指针操作二维数组
*/
int a[3][4] = { 100,1,2,3,4,5,6,7,8,9,10,11 };
int ** p = (int **)a; //强制类型转换
cout << "p:" << p << ",a:" << a << ",&a[0][0]:" << &a[0][0] << endl;//相等
cout << "*p:" << hex2dec(*p) << endl; //100(a[0][0])
//cout << "**p:" << **p << endl; //错误,访问了100的地址*(100)
getchar();
return 0;
}
6 参考文献
[1] 谭浩强.C++程序设计[M].2版.北京:清华大学出版社,2011.
[2] 郭有强,王磊,姚保峰.C++面向对象程序设计[M].北京:清华大学出版社,2009.