前言
小白一个,这是我的第一篇文章。写文章的主要目的是用于记录一些学习笔记(当然,包含个人理解,有问题欢迎通过多种途径进行交流指正)
一年前认认真真地学习了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]不是,而是子数组的指针
拓展知识可以参考如下链接: