【C++学习笔记】指针数组和数组指针(含数组作为形参在函数间传递的几种方法)

前言

小白一个,这是我的第一篇文章。写文章的主要目的是用于记录一些学习笔记(当然,包含个人理解,有问题欢迎通过多种途径进行交流指正)

一年前认认真真地学习了C++,并靠此初步入门了编程。最近开始回来复习和巩固,以下是本次笔记的主要内容。

  • 数组指针和指针数组的区别

事实上,从英文角度便可以很容易的理解这个问题。

数组指针是 a pointer to an array (to 指向嘛),指的是一个指针,其指向一个数组(例如,指向数组的首地址)

指针数组是 array of pointers (of 后是修饰成分),指的是一个数组,其内部存储的变量类型是指针。

很显然,数组指针是指向数组的指针,指针数组是储存指针的数组。(中文角度也可以,中文里一般把主语放最后面,定语前面),感觉这样理解东西很有意思。

举例:

	int (*a)[2] = {}; // 数组指针
	int * b[3] = {}; // 指针数组
	
	std::cout << typeid(a).name() << std::endl;
	std::cout << typeid(b).name() << std::endl;

结果: PA2_i 代表“指针数组,大小为2”,A2_Pi代表“数组指针,大小为3”

  •  数组作为形参在函数间传递的几种方法

数组传入的方式大致是分为两种思路,为了介绍全面,这里以二维数组为例
一种是静态的,一种是动态的(但总的来说都是传递初始位置的地址,列数、行数等)

 这里就不再多废话,说明直接贴注释里。先附上主函数

#include<iostream>
#include<typeinfo>

using namespace std;

int main()
{
	int arr1[2][3] = {}; // 全为0
	int arr2[3][3][3] = {};
	array1(arr1);
	array2(arr1[0],2,3);
	array3(arr1,2);
	array4(arr2,3);
	
	return 0;
}

 第一种:静态数组(直接把信息写死,传入的数组只能为2行3列)

void array1(int arr[2][3]) 
{
	cout << endl;
	for(int t1=0; t1<2; t1++)
	{
		for(int t2=0; t2<3; t2++)
		{
			cout << arr[t1][t2] ;
		}
		cout << endl;
	}
}

第二种:动态数组,利用指针进行传入,采用更多参数的好处是更灵活,其行数,列数等信息由实际传入数值决定,但代价是需要更多储存空间。

​
// 上面的表达等价于void array1(int rows, int cols, int *arr) 
void array2(int * arr, int rows, int cols) 
{
	cout << endl;
	for(int t1=0; t1<rows; t1++)
	{
		for(int t2=0; t2<cols; t2++)
		{
			cout << arr[t1*rows + cols] ; 
// 可以发现,当作一维的数组来处理了(二维数组本质是一维数组,存储空间是连续的)
		}
		cout << endl;
	}
}
// 与void array1(int a[2][3])原理相同
void array3(int arr[][3],int rows) 
// 形参部分等价于 int (*arr)[3],int rows,这里的(*arr)[3]就是一个数组指针(可以互换验证)
{
	cout << endl;
	for(int t1=0; t1<rows; t1++)
	{
		for(int t2=0; t2<3; t2++)
		{
			cout << arr[t1][t2] ;
		}
		cout << endl;
	}
}

​

来个推广到三维数组的例子

// 形参部分等价于 int (*arr)[3],int rows,这里的(*arr)[3]就是一个数组指针(可以互换验证)
void array4(int arr[][3][3],int rows) 
{
	cout << endl;
	for(int t1=0; t1<rows; t1++)
	{
		for(int t2=0; t2<3; t2++)
		{
			for(int t3=0; t3<3; t3++)
			{
				cout << arr[t1][t2][t3] << ' ';
			}
			cout << endl;
		}
		cout << endl;
	}
}

几个有趣的问题

问题1

	cout << arr1 << endl; // 地址一样,但类型不一样
	cout << arr1[0] << endl;
	cout << typeid(arr1).name() << endl;
	cout << typeid(arr1[0]).name() << endl;

问题1 的运行结果是

问题2

对于函数

void array5(int a[],int len){}
	int a[2];
	array5(a,2);
//	array5(a[0],2); // 编译不通过,因为是值。

// 对于二维的情况
    int b[2][2];
//  b[0][0] 是值,但b[0]不是,而是子数组的指针

拓展知识可以参考如下链接:

c++二维数组a[m][n]中为何a的值和a[0]的值相同? - 知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值