声明:1. 文章如有不妥的地方,请您指正,谢谢.
2.另外文中有些细节可能引用您的内容却未给出参考,请原谅我的疏忽,你的共享我不会忘记.
3. Email:lizhiguo0532@163.com 李枝果/lizgo
4.转载请保留该部分信息
二维数组在多维数组中算是简单的了,但是如果二维数组不清楚,就很难理解多维数组是怎么个概念了。
在这里还是要提到一个重要的c语言关键字:tepydef,可以说,任何复杂的类型申明都可以用typedef
来拆解成简单易懂的申明。
定义多维数组,以四维数组int a[5][4][3][2]定义为例,可以这样
typedef int ONE[2];
typedef ONE TWO[3];
typedef TWO THREE[4];
typedef THREE FOUR[5];
到此已经将类型申明完成,下面就可以用FOUR来定义int a[][4][3][2]这种结构的四维数组了
FOUR a;<--------->int a[5][4][3][2];
不过这样声明之后定义数组就比较局限了,我们做一下如下改动:
将typedef THREE FOUR[5];换成typedef THREE FOUR;之后就可以定义了:
FOUR a[5];
FOUR b[10];
...
那a这个多维数组的结构是怎么样的呢?
int a[5][4][3][2];
首先先不要管前面的int 关键字,从数组名a开始往右看,遇到第一个[5],说明a是一个具有5个元素的数组,那里面的元素是什么类型呢?
暂时先不管,再往右看,右是一个[4],说明前面具有5个元素的数组的每个元素又是一个具有4个元素的数组,那具有4个元素的数组的每个元素是什么
类型呢?还是先不管,继续往右看,哦,右遇到了一个[3],这说明前面具有4个元素的数组的每个元素又是一个具有3个元素的数组,那具有3个元素的数组
的每一个元素又是什么类型呢?还是不管,继续往右看,又遇到了[2],这说明具有3个元素的数组的每个元素又是一个具有2个元素的数组,那这个具有2个
元素的数组的每个元素又是什么类型呢?到这个时候再朝往看已经找不到[]了,这个时候就看看前面的类型修饰符是什么,这里是int ,这个就说明具有2个
元素的数组的每个元素都是int型数据。
上面的一大段话着实让人看来很晕,所以简
言之,就是利用递归的思想取看。下面看看这个多维数组初始化的时候的情况,以加深理解:
int a[5][4][3][2]={{},{},{},{},{}};//a是个数组,里面右5个元素
={{{},{},{},{}},{...},{...},{...},{...}};//5元素数组的每一个元素又是具有4个元素的数组 ,后面四个{...}和第一个{{},{},{},{}}一样
={{{{},{},{}},{...},{...},{...}},{...},{...},{...},{...}};//4元素数组的每个元素又是具有3个元素的数组
={{{{{},{}},{...},{...}},{...},{...},{...}},{...},{...},{...},{...}};//3元素数组的每个元素又是具有2个元素的数组
={{{{{1,2},{3,4}},{...},{...}},{...},{...},{...}},{...},{...},{...},{...}};//2元素数组的每个元素是int数据
二维数组
比如要定义一个int b[4][3];这个数组,当然你可以在程序中这样写,另外也可以利用typedef来简化类型声明。
typedef int A[3];//A 为具有3个元素的数组类型
A b[4];//b为具有四个元素的数组,其中每个元素的类型是A,即每个元素又是一个具有3个int型数据的数组
A c;//相当与int c[3];
A *p=&c;//p是一个数组指针,具体的说是具有3个int型数据的数组指针变量,这是上一篇文章里讨论一维数组时提及的
这里重提两句关于数组名的两句重要的话:数组名的内容是其首元素的首地址;数组名的类型是其元素类型的指针类型。另外数组名的基类型就是数组元素的类型
b[0][0] 类型:int 基类型:无
&b[0][0] 类型:int * 基类型:int
b[0] 类型:int * 基类型:int
&b[0] 类型:int (* )[3] 基类型:int [3]
b 类型:int (* )[3] 基类型:int [3]
&b 类型:int (* )[4][3] 基类型:int [4][3]
1.利用指针数组访问b
int *p[4];//[]先于*与p结合,说明p是一个具有4个元素的数组,但是每个元素又是一个int指针变量,可以这么来看,假设有个变量叫p[0],int p[0],
//(和int a;没什么本质差别,只是名字变了而已,如果int *a;那a就是一个int指针了),同理int *p[0],那p[0]也是一个int指针了。
那定义来一个int指针数组,我们怎么利用他来访问二维数组呢?
要知道在二维数组里面b[4][3],b[0],...,b[3]都表示3int元素的一维数组名,这些一维数组名的类型都是int *,在语言中类型(基类型)相同时,赋值
运算是合法的
有以下循环来初始化我们的int指针数组:
for(int i=0;i<4;i++)
p[i]=b[i];
//b[i]是一维数组名,是地址常量,不能出现在=号的左边,同时它们的值也不能改变
这样我们就可以通过p来引用b数组的元素:i是a的游标,j是a每个元素(一位数组)的游标
*(p[i]+j)<------>*(b[i]+j)
*(*(p+i)+j)<---->*(*(b+i)+j)
(*(p+i))[j]<---->(*(b+i))[j]
p[i][j]<------->b[i][j]
这里需要注意一点的是:p=b;这样是不合法的,因为p和b的类型不一样。b的类型是int (* )[3],而p的类型是int * [4]或者int **(int指针的指针类型)
这里我们可以定义一个int二级指针来指向p数组
int **pp;
pp=p;
这样就可以用pp来访问b数组了。另外还要注意的是数组名不能被修改,也就是不能参与指针运算。pp,p[i]可以参与指针运算。
2.利用数组指针访问b
int (*pa)[3];//pa首先是一个指针,这个指针指向的类型(基类型)是具有3个int元素的数组
pa的类型是int (* )[3],恰好与b的类型相同,所以
pa=b;是合法的赋值表达式。
我们可以用下面的方法来引用二维数组b
*(pa[i]+j)<------>*(b[i]+j)
*(*(pa+i)+j)<---->*(*(b+i)+j)
(*(pa+i))[j]<---->(*(b+i))[j]
pa[i][j]<------->b[i][j]
只是pa的内容可以改变,而b的内容不能变。
3.二维数组名和指针数组在函数传参时的实质性问题
这里需要提到的一点是,在c语言中,函数之间不能传递数组,但是可以传递结构体变量。所以在某些地方实在避免不了函数件传数组的话,就可以利用
结构体来进行封装
另外,在函数的形参列表里面,无论出现什么形式的数组声明,在最后进入函数体内部的时候都会退化成指针
二维数组名作为实参传递给函数时,函数的形参列表可以是以下形式:
fun(int (*a)[N]);
fun(int a[][N]);
fun(int a[M][N]);
指针数组名作为实参传递给函数时,函数的形参列表可以是以下形式:
fun(int *a[M]);
fun(int *a[]);
fun(int **a);
实例
利用数组指针数组访问一个二维数组,求出二维数组所有元素的和
#include <stdio.h>//a[4][3]
typedef int (*array_p)[3];
typedef array_p (pointer[4]);
//或者
typedef int (array)[3];
typedef array *(pointer_a[4]);
int a[4][3];
int main(int argc,char *argv[])
{
int i,j;
int sum=0;
int (*p[4])[3];
array_p ap[4];
pointer po;
pointer_a pa;
for(i=0;i<4;i++)
for(j=0;j<3;j++)
scanf("%d",&a[i][j]);
for(i=0;i<4;i++)
p[i]=&a[i];//ap[i]的类型是int (* )[3],&a[i]的类型也是int (* )[3]
//将此处的p换成po或者pa或者ap类型是一样的
for(i=0;i<4;i++)
for(j=0;j<3;j++)
sum+=*((*p[i])+j);
printf("%d\n",sum);
return 0;
}
分享到:
相关推荐
在C语言中数组和指针之间存在一些千丝万缕的联系,搞不清楚的情况下非常容易出错,在前一段时间我写过关于数组和指针的分析,但是还是存在很多不清楚的问题,特别是当出现一些复杂的问题时,这种情况更加的复杂。...
此实例解释了new动态创建多维数组的用法,还有包涵了多维数组指针的用法···
本文给大家分享了C语言初学者入门讲座 第十二讲 多维数组的指针变量。
C/C++的函数中传递多维数组的各种方法,包括数组和指针的各种用法.
在C++中,通过多维数据的指针作为函数参数传递源程序
C语言数组与指针操作
数组与指针 利用数组表示一组相关 数据项 声明数组、初始化数组、 应用数组中的单个元素 将数组传递给函数 声明和使用多维数组
C语言多维数组与多级指针[参照].pdf
一组新的多维数组模板类 by chen3feng(RoachCock@smth) email: chen3feng@163.com, chen3fengx@163.com, chen3fengx@hotmail.com [引言] 在C/C++开发中,多维数组是一个让很多人感到棘手的问题.原因...
多维数组与多级指针是初学者经常感觉迷糊的一个地方。超过二维的数组和超过二级的指针其实并不多用。但只要掌握一定的方法,理解多级指针和“多维”数组完全可以像理解一级指针和一维数组那样简单。
本书针对程序设计的初学者,以面向对象的程序设计思想为主线,以通俗易懂的方法介绍C++语言,引导读者以最自然的方式,将人类习惯的面向对象的思维方法运用到程序设计中。主要内容包括程序设计基础知识、类与对象的...
C语言中指针引用多维数组的教学实践.pdf
如果要给二维数组(m*n)分配空间,代码可以写成下面: 代码如下:char **a, i; // 先分配m个指针单元,注意是指针单元 // 所以每个单元的大小是sizeof(char *) a = (char **) malloc(m * sizeof(char * )); // 再分配n...
掌握数组的使用 了解多维数组的使用 掌握指针的概念和使用 了解多级指针的概念
“深入学习数组包括多维数组的知识和应用,以及它们与指针的关系。 C++语言拥有在运行时获得变量地址和操纵地址的能力,这种可用来操纵地址的变量类型就是指针。指针可以用于数组,用于内存访问,还可作为函数的...
在C语言中数组和指针之间存在一些千丝万缕的联系,搞不清楚的情况下非常容易出错,在前一段时间我写过关于数组和指针的分析,但是还是存在很多不清楚的问题,特别是当出现一些复杂的问题时,这种情况更加的复杂。...
● 如何声明和使用多维数组 ● 指针及其使用方法 ● 如何声明和初始化不同类型的指针 ● 数组和指针之间的关系 ● 引用的概念及声明方法,关于使用引用的几点初步建议 ● 如何在本地C++程序中给变量...
下面来讲讲多维数组与指针的关系。与普通数组一样,使用多维数组时,实际上将其自动转换为指向该数组第一个元素的指针
比较实用的一个C语言编程的练习,其中包含多种存住形式,以及一些... //数组名 int dim; //数组维数 int *lower; //各维下界表指针 int *upper; //各维上界表指针 int *Constants; //各维常量因子表指针 }Array;