C++ | 高维数组、指针、返回指向数组的指针的函数

对于1维数组,指针和数组的对应关系很好搞明白。
对于2维的,也凑合。
对于更高纬度的,就开始乱套了,特别是返回该高维数组指针的函数的声明。不过从3d往后又是同样的规律了。

这一次,花时间捋顺它:

  • 数组
  • 指针
  • 返回指向数组的指针的函数的声明和定义。
//数组指针:指向数组的指针
int (*p)[2]; // 按结合性,(*p)表示一个指针,指向的是[2]表示2元素,元素是int

//指针数组:指针构成的数组
int *p[2]; //按结合性,p[2] 表示一个2元素数组,元素内容是指针,指向int

1d 数组

/*
* 摘    要:返回 1d数组、指针、返回指向数组指针的函数
*/
#include  <iostream>
using namespace std;

int arr[4]= {0, 10, 20, 30};

//声明返回 数组元素的 函数
int *getInt(int index);

//声明 参数是概述组的函数
void print(int *, int);

int main(){ 
	//定义指针,和数组平级
	int *pArr = arr; //目测,看着消失掉一个维度信息
	
	//1. 输出数组元素和指针
	cout << "\nPart I: print array" << endl;
	print(arr, sizeof(arr)/sizeof(int) );
	
		
	//2. 对数组, [] 与 * 具有相同的作用,获取内层,获取值。
	cout << "\nPart II: [] and * are the same for array" << endl;
	cout << " arr[1]=" << arr[1] << ",  *(arr+1)=" << *(arr+1) << endl;
	cout << "pArr[1]=" << pArr[1] << ", *(pArr+1)=" << *(pArr+1) << endl;

	//3. 数组名不能自增,但是指向它的数组可以
	cout << "\nPart III: array name can NOT increase, pointer can" << endl;
	//arr++; //error: lvalue required as increment operand
	pArr++;
	cout << "after: pArr++" << endl;
	cout << "pArr[0]=" << pArr[0] << ": "<< &pArr[0] << endl;
	cout << "pArr[-1]=" << pArr[-1] << ": "<< &pArr[-1] << endl; //下标还可以是负数,只要地址有效
	
	//4. 返回元素的函数
	cout << "\nPart IV: function return element of array" << endl;
	int *result = getInt(3);
	cout << *result << ": " << result << endl; 
	
	return 0;	
}

// 函数定义
// 根据下标,返回子元素
int *getInt(int index){
	return &arr[index];
}

// 打印数组
void print(int *p2Int, int len){
	for(int i=0; i<4; i++){
		cout << p2Int[i] << " (" << &p2Int[i] << ")\t";
	}
	cout << endl;
}

$ g++ -std=c++11 a8_1d.cpp
输出结果:
在这里插入图片描述

2d array

/*
* 摘    要:2d数组、指针、返回指向数组指针的函数
*/
#include  <iostream>
using namespace std;

int arr[4][2]= {
	{0,1}, 
	{2,3},
	{4,5},
	{6,7}
};

//声明返回 数组元素(1d数组) 的函数
int *getElement(int index);

//声明 参数是该数组的函数:数组不能作为参数,但是指向它的指针可以
void print(int (*p)[2], int);

int main(){
	cout << ">> For 2d-array" << endl;
	//定义指针,和数组平级
	int (*pArr)[2] = arr; //目测,看着消失掉一个(最高)维度信息
	//定义指向多维数组的指针,一定要先把指针加圆括号 (*p),然后剩下的是该数组包含的内元素
	
	//1. 输出数组元素和指针
	cout << "\nPart I: print array" << endl;
	int length= sizeof(arr)/sizeof(int[2]);
	print( arr, length);
	
	//2. 对数组, [] 与 * 具有相同的作用,获取内层,获取值。
	cout << "\nPart II: [] and * are the same for array" << endl;
	cout << " arr[2][1]=" << arr[2][1] << ",  *(arr+1)=" << *(*(arr+2)+1) << endl;
	cout << "pArr[2][1]=" << pArr[2][1] << ", *(pArr+1)=" << *(*(pArr+2)+1) << endl;
	
	//3. 数组名不能自增,但是指向它的数组可以
	cout << "\nPart III: array name can NOT increase, pointer can" << endl;
	//arr++; //error: lvalue required as increment operand
	pArr++;
	cout << "after: pArr++" << endl; //走过的是其子元素
	cout << "pArr[0][0]=" << pArr[0][0] << ": "<< &pArr[0][0] << endl;
	cout << "pArr[-1][0]=" << pArr[-1][0] << ": "<< &pArr[-1][0] << endl; //下标还可以是负数,只要地址有效
	
	//4. 返回元素的函数
	cout << "\nPart IV: function return element of array" << endl;
	int *result = getElement(3);
	cout << "add: " << result << endl; 
	for(int i=0; i<2; i++){
		cout << result[i] << " (" << &result[i] << ")\t";
	}
	
	return 0;	
}

// 函数定义
// 打印数组
void print(int (*p2)[2], int len){
	for(int i=0; i<len; i++){
		for(int j=0; j<2; j++){
			cout << p2[i][j] << " (" << &p2[i][j] << ")\t";
		}
		cout << endl;
	}
}

// 根据下标,返回子元素
int *getElement(int index){
	return arr[index];
}

$ g++ -std=c++11 a8_2d.cpp
输出结果:
在这里插入图片描述

3d array

/*
* 摘    要:3d数组、指针、返回指向数组指针的函数
*/
#include  <iostream>
using namespace std;

int arr[3][4][2] = {
	{
		{0,1},	{2,3},	{4,5},	{6,7}
	},
	{
		{10,11},	{12,13},	{14,15},	{16,17}
	},
	{
		{20,21},	{22,23},	{24,25},	{26,27}
	}
};


//声明返回 数组元素(2d数组) 的函数,开始变得面目可憎:
int (*getElement(int index))[2];

// 返回指向原数组的指针,指针位置移动index位
int (*get3d(int index))[4][2];


//声明 参数是该数组的函数:数组不能作为参数,但是指向它的指针可以
void print(int (*p)[4][2], int); //数组名和最高维作为参数

int main(){
	cout << ">> For 2d-array" << endl;
	//定义指针,和数组平级,大多数时候能替换
	int (*pArr)[4][2] = arr; //目测,看着消失掉一个(最高)维度信息
	//定义指向多维数组的指针,一定要先把指针加圆括号 (*p),然后剩下的是该数组包含的内元素
	
	//1. 输出数组元素和指针
	cout << "\nPart I: print array" << endl;
	int length= sizeof(arr)/sizeof(int[4][2]);
	print( arr, length);
	
	//2. 对数组, [] 与 * 具有相同的作用,获取内层,获取值。
	cout << "\nPart II: [] and * are the same for array" << endl;
	cout << " arr[2][3][1]=" << arr[2][3][1] << ",  *(*(*(arr+2)+3)+1)=" << *(*(*(arr+2)+3)+1) << endl;
	cout << "pArr[2][3][1]=" << pArr[2][3][1] << ", *(*(*(pArr+2)+3)+1)=" << *(*(*(pArr+2)+3)+1) << endl;
	
	
	//3. 数组名不能自增,但是指向它的数组可以
	cout << "\nPart III: array name can NOT increase, pointer can" << endl;
	//arr++; //error: lvalue required as increment operand
	cout << pArr << " ";
	pArr++;
	cout << "after pArr++: "; //走过的是其子元素 [4][2]: 8* 4/int=32
	cout << pArr << endl;
	cout << "pArr[0][0][0]=" << pArr[0][0][0] << ": "<< &pArr[0][0][0] << endl;
	cout << "pArr[-1][0][0]=" << pArr[-1][0][0] << ": "<< &pArr[-1][0][0] << endl; //下标还可以是负数,只要地址有效
	
	//4. 返回元素的函数
	cout << "\nPart IV: function return element of array" << endl;
	int (*result)[2] = getElement(2);
	cout << "result: " << result << endl; 
	for(int i=0; i<4; i++){
		for(int j=0; j<2; j++)
			cout << result[i][j] << " (" << &result[i][j] << ")\t";
		cout << endl;
	}
	
	//5. 返回指向原数组的指针,指针位置有index偏移
	cout << "\nPart V: function return this array, with pointor shift" << endl;
	int (*result3d)[4][2] = get3d(2);
	cout << "result3d: " << result3d << endl;
	cout << result3d[0][2][0] << " (" << &result3d[0][2][0] << ")\t";
	cout << result3d[0][2][1] << " (" << &result3d[0][2][1] << ")\t";
	
	return 0;	
}

// 函数定义
// 打印数组
void print(int (*p2)[4][2], int len){
	for(int i=0; i<len; i++){
		printf("arr[%d][4][2]\n", i);
		for(int j=0; j<4; j++){
			for(int k=0; k<2; k++)
				cout << "\t" << p2[i][j][k] << " (" << &p2[i][j][k] << ")\t";
			cout << endl;
		}
	}
}

// 返回指向子元素的指针
int ( *getElement(int index) )[2]{
	return arr[index];
}

// 返回指向原数组的指针,指针位置移动index位
int (*get3d(int index))[4][2]{
	return arr+index;
}

$ g++ -std=c++11 a8_3d.cpp

输出结果:
在这里插入图片描述

测试题

定义一个返回 指向2d 数组的指针 的函数,并定义变量接收返回值。使用该返回值打印该2d数组。

参考实现:

#include<iostream>
using namespace std;

int arr3d[3][4][2] = {
	{
		{0,1},	{2,3},	{4,5},	{6,7}
	},
	{
		{10,11},	{12,13},	{14,15},	{16,17}
	},
	{
		{20,21},	{22,23},	{24,25},	{26,27}
	}
};

int (*getElement(int index))[2]; // 1.声明函数

int main(){
	int (*result)[2] = getElement(2); // 2.接收返回值
	
	//3.打印结果
	for(int i=0; i<4; i++){
		for(int j=0; j<2; j++)
			cout << result[i][j] << " (" << &result[i][j] << ")\t";
		cout << endl;
	} 
	
	return 0;	
}


// 函数定义 
int ( *getElement(int index) )[2]{
	return arr3d[index];
}

预期效果,打印出3维数组的下标为[2]的维度,是一个 int [4][2] 数组。
截图略。

小结:

  • 数组变指针,实际上就是指向其第一个子元素的。
  • 声明指向数组的指针,要注意加圆括号: int (*parr)[2];
  • 指向高维数组的指针声明,要损失其最高维信息,其余保留
  • 返回指向数组的指针的函数的声明,也要注意加圆括号: int ( *getElement(int index) )[2];
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值