二维数组简介与使用
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
⼆维数组简介与使⽤
前⾔
本⽂将探讨⼀下关于⼆维数组在内存中的存储和⼆维数组在参数传递时的使⽤。
⼀、⼆维数组在内存中的存储
如果定义⼀个这样的⼆维数组int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};则其在内存中的表⽰可能下⾯这样的。
由上图可以看出,在内存中⼆维数组是按照⾏主序进⾏存储的,从内存的⾓度上看,⼆维数组本质就是⼀个⼀维数组。
如果把⼆维数组的每⼀⾏看成⼀个整体,即看成⼀个数组中的⼀个元素,那么整个⼆维数组就是⼀个⼀维数组。
⽽⼆维数组的名字代表⼆维数组第0⾏的⾸地址(注意它是代表⼀⾏元素的⾸地址,⽽不是第0⾏第0列元素的⾸地址,虽然是相等的,但不能这么理解,所以在没有强制转换的情况下,⼆维数据要么通过⾏指针进⾏参数传递,要么通过⼆维指针进⾏参数传递)。
⼆、⼆维数组在参数传递时的使⽤
1、可以⽤⼆维数组名作为实参或者形参,在被调⽤函数中对形参数组定义时可以指定所有维数的⼤⼩,也可以省略第⼀维的⼤⼩说明,如:
void Func(int array[3][10]);
void Func(int array[][10]);
但是不能把第⼆维或者更⾼维的⼤⼩省略,如下⾯的定义是不合法的:
如 void Func(int array[3][]);
因为从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(⾏主序),⽽并不区分⾏和列,如果在形参中不说明列数,则系统⽆法决定应为多少⾏,多少列,不能只指定⼀维⽽不指定第⼆维。
2、将⼆维数组作为指针进⾏参数传递
(1)直接作为⾏指针(数组指针)来传递参数(⼆维数组的名字代表⼆维数组第0⾏的⾸地址)
1 #include "stdafx.h"
2 #include<iostream>
3using namespace std;
4
5void test(int (*a)[4],int m,int n)
6 {
7 cout<<*(*(a+m)+n);
8 }
9
10int _tmain(int argc, _TCHAR* argv[])
11 {
12int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
13 test(a,1,1);
14return0;
15 }
上述程序中int (*a)[4],可以理解为⼆维数组的⾏指针(这个指针指向⼆维数组的⾏,⽽每⼀⾏最多有4列),a[n]表⽰⼆维数组的第n⾏,所以cout<<*(*(a+m)+n);先定位出a数组的第m⾏的位置,然后再求出第m⾏第n列的值
(2)参数传递时将⼆维数组的强制转换为⼀维指针,然后按照内存中存储的⽅法计算⼆维数组对应成⼀维数组的下标
1 #include "stdafx.h"
2 #include<iostream>
3using namespace std;
4void test(int *a,int row,int column,int m,int n)
5 {
6 cout<<a[m*column+n];
7 }
8
9int _tmain(int argc, _TCHAR* argv[])
10 {
11int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
12 test((int*)a,3,4,1,1);
13return0;
14 }
注意参数传递时将⼆维数组的强制转换为⼀维指针,如上述程序中的第12⾏
注意:切不可将⼆维数组直接转换成⼆维指针作为形参传递,因为在这样⼦函数中不知道每⼀个⼀维元素含有多少个⼆维元素。
如,下⾯这样写就是错误的:
#include<iostream>
using namespace std;
void test(int **a,int m,int n)
{
cout<<*(*(a+m)+n);
}
int main()
{
int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}; test((int **)a,1,1);
return0;
}。