探究二维数组

来源:互联网 发布:ps cc mac怎么安装啊 编辑:程序博客网 时间:2024/06/05 03:56

1. 引言

对N x M的二维数组来讲,设其数组名为array。指针array指向一个数组,该数组存放的是一系列指针,这些指针分别指向相应的一维数组,而这些数组中存放的才是我们的数据。

2. 二维数组声明和定义

2.1 静态分配内存

int array[3][10]; //定义int array[3][10] = {{0},{0},{0}}; //初始化extern int array[3][10];  // 声明在其他的位置存在变量arrayclass Animal{    public:        int array[3][10]; // 仅仅是声明变量array,直到定义了Animal对象,才进行内存的分配};

声明和定义的区别:
声明仅仅是告知编译器存在一个变量叫做XXX,但是不分配内存;而定义除了声明变量,还要分配内存。
定义和初始化的区别:
初始化是在程序声明的地方进行定义,既是声明又是定义,但是又不同的是,它强调第一次声明的时候进行定义(内存分配)。

2.2 动态分配内存
方法一 :

分配N个地址指针,并在循环中为每个指针分配M个int大小的内存.

 #include <stdlib.h>   // 必须包含该 头文件,里面定义了malloc的实现      int ** array = (int **) malloc( N * sizeof(int *) );     for (int k=0;k<N;k++)              array[k] = (int *)malloc( M * sizeof(int) );    

方法二 :

分配N个地址指针,但统一分配M*Nint大小内存,之后为每个指针指定其一位数组起始地址.

#include <stdlib.h>      int ** array = (int **) malloc( N * sizeof(int *) );     array[0] = (int *) malloc( M * N * sizeof(int) );     for (int k=1;k<N;k++)               array[k] = array[0]+M*k;  // array[k] = array[k-1]+M;

上述两种方法的区别在于
方法一在内存中分配的区域有可能是不连续的;而方法二则在内存中的一片连续区域为该数组分配空间。

方法三:
通过一维数组模拟二维数组,即是,实际声明和定义的是一位数组,只是将其看做二维数组。在这中间要进行下标转换。
如对于模拟的NxM数组,访问其第i行,第j列元素时,在一维数组中对应的位置是i*M+j

#include <stdlib.h>      int * array = (int *) malloc( M * N * sizeof(int) );     for (int i=0;i<N;i++)           for (int j=0;j<M;j++)         printf("%d", arrar[i*M+j]);

3. 二维数组作为形参的声明方式

在函数的定义中,可以用二维数组名作为实参或者形参。此时,当二维数组当作参数的时候,必须指明数组所有的维数大小或者省略第一维的,但是不能省略第二维或者更高维的大小,这是由编译器原理限制的。因为从实参传递来的是数组的起始地址,在内存中按数组排列规则存放(按行存放),而并不区分行和列,如果在形参中不说明列数,则系统无法决定应为多少行多少列。

方式一:
在被调用函数中对形参数组定义时可以可以指定所有维数的大小,也可以省略第一维的大小说明,如:

void   Func(int   array[3][10]);              void   Func(int   array[][10]);

二者都是合法而且等价,但是不能把第二维或者更高维的大小省略,如下面的定义是不合法的:

 void   Func(int   array[][]);  // this is the wrong declare type

方式二:
将数组名当作一个普通的指针,再另外加上两个参数指明各个维数,然后我们为二维数组手工寻址。
例如:

void   Func(int   array[3][10]);                void   Func(int   array[][10]);    

变为:

void   Func(int   **array,   int   row,   int   column);   

在转变后的函数中,array[i][j] 这样的式子是不对的。因为编译器不能正确的为它寻址,所以我们需要模仿编译器的行为,把array[i][j]这样的式子手工转变为 *((int*)array + column*i + j);

注意:
1)不能只指定一维而不指定第二维,下面写法是错误的:

void   Func(int   array[3][]);

2)实参数组维数可以大于形参数组,例如形参数组定义为

void   Func(int   array[3][10]);    

而实参数组定义为:

 int   array[5][10];      

说明:
编译器在进行编译时,并不关注形参中第一维数字的大小,其只需知道第二位或者高维的大小,用来对传入的参数进行维度划分,确定是第几行第几列。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 元征升降机泄压怎么办 自拍杆的杆子往下下滑怎么办 小狗被车压了一下拉血怎么办 有鬼给你磕头让你不好怎么办 腿又粗又短怎么办 腿又短又粗怎么办 因跑步小腿变粗怎么办 健身后小腿变粗怎么办 打非洲鼓打的手疼怎么办 无塔供水压力小怎么办 家用增压水塔压力不稳定怎么办 蝴蝶耳堵比较紧怎么办 跑步机踏板坏了怎么办 遥控器电池没电了怎么办 空调遥控器电池没电了怎么办 想要自慰家里没有情趣用品怎么办 对政协提案的答复有意见怎么办 邻居在自建房养殖鳖怎么办 江桥全民健身卡怎么办 南翔全民健身卡怎么办 椭圆机皮带断了怎么办 不小心扭腰了怎么办 扭腰之后腿疼怎么办 扭腰怎么办吃什么补 湖州奥体中心怎么办卡 学车把教练投诉了怎么办 白球鞋鞋边发黄怎么办 公务员体检时心跳过快怎么办 老人心脏跳得慢怎么办 银行月限额10万怎么办 跑步后迎面骨疼怎么办 跑步时迎面骨疼怎么办 爬了楼梯小腿疼怎么办 走路走太多小腿酸痛怎么办 微信转账月限额怎么办 运动后小腿骨疼怎么办 用单杠练腹肌晃怎么办 一跑步小腿就紧怎么办 小腿一跑步就痛怎么办 单杠屈臂悬垂身体摆动怎么办 脸上被打了紫了怎么办