• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > C语言数组入门之数组的声明与二维数组的模拟

C语言数组入门之数组的声明与二维数组的模拟

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c语言声明数组,c语言如何声明数组,c语言声明字符数组,c语言二维数组声明,c语言声明一个数组等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

语言中指针与数组这两个概念之间的联系是密不可分的,以至于如果不能理解一个概念,就无法彻底理解另一个概念。

C语言中的数组值得注意的地方有以下两点:

C语言中只有一维数组,而且数组的大小必须在编译期就作为一个常数确定下来。然而,C语言中数组的元素可以是任何类型的对象,当然也可以是另外一个数组。这样,要“仿真”出一个多维数组就不是一件难事。
对于一个数组,我们只能够做两件事:确定该数组的大小,以及获得指向该数组下标为0的元素的指针。其他有关数组的操作,哪怕它们看上去是以数组下标进行运算的,实际上都是通过指针进行的。换句话说,任何一个数组下标运算都等同于一个对应的指针运算,因此我们完全可以依据指针行为定义数组下标的行为。
一旦我们彻底弄懂了这两点以及它们所隐含的意思,那么理解C语言的数组运算就不过是“小菜一碟”。如果不清楚上述两点内容,那么C语言数组运算就可能会给编程者带来许多困惑。需要特别指出的是,编程者应该具备将数组运算与它们对应的指针运算融汇贯通的能力,在思考有关问题时大脑中对这两种运算能够自如切换。毫无滞碍。

任何程序设计语言中都内建有索引运算,在C语言中索引运算是以指针算术的形式来定义的。

如何声明一个数组

要理解C语言中数组的运作机制,我们首先必须理解如何声明一个数组,例如:

int a[3];
</div>

这个语句声明了a是一个拥有了3个整型元素的数组,类似的,

struct{
 int p[4];
 double x;
}b[17];
</div>

声明了b是一个拥有17个元素的数组,其中每个元素都是一个结构,该结构中包括了一个拥有4个整形元素的数组(命名为p)和一个双精度类型的变量(命名为x)。

现在考虑下面的例子:

int calendar[12][31];
</div>

这个语句声明了calendar是一个数组,该数组拥有12个数组类型的元素,其中每个元素都是拥有31个整型元素的数组(而不是一个拥有31个数组类型的元素的数组,其中每个元素又是一个拥有12个整型数组元素的数组)因此sizeof(calendar)的值是372(31*12)与sizeof(int)的乘积。

如果calendar不是用于sizeof的操作数,而是用于其他的场合,那么calendar总是被替换成一个指向calendar数组的起始元素的指针。要理解上面这句话的含义,我们首先必须理解有关指针的一些细节。

二维数组模拟
*a即数组a中下标为0的元素的引用。例如,我们可以这样写:

*a=84;
</div>

这个语句将数组a中下标为0的元素的值设置为84.同样道理,*(a+1)数组a中下标为1的的元素的引用,以此类推,概而言之,*(a+i)即数组中下标为i的元素的引用,这种写法是如此常用,因此被简记为a[i].

正是这一概念让C语言新手难于理解,实际上,由于a+i与i+a的含义一样,因此a[i]和i[a]也具有同样的含义。也许某些汇编语言程序员会发现后一种写法很熟悉,但我们绝对不推荐这种写法。

现在我们可以考虑二维数组了,正如前面所讨论的,它实际上是以数组为元素的数组,尽管我们也可以完全依据指针编写操纵一维数组的程序,这样做在一维情形下并不困难,但是对于二维数组从记法上的便利性来说采用下述形式就几乎是不可替代了。还有,如果我们仅仅使用指针来操纵二维数组,我们将不得不与C语言中最为“晦暗不明”的部分打交道,并常常遭遇到潜伏着的编译器bug。

让我们回过头来再看几个声明:

int calendar[12][31];
int *p
int i;
</div>

然后考一考自己,calendar[4]的含义是什么?

因为calendar是一个有着12个数组类型元素的数组,它的每个数组类型元素又是一个有着31个整型数组,所以calendar[4]是 calendar数组的第五个元素,是calendar数组中12个有着31个整型元素的数组之一,因此calendar[4]的行为也就表现一个有着31个整形元素的数组的行为,例如sizeof(calendar[4])的结果是31与sizeof(int)的乘积。

p=calendar[4];
</div>

这个语句使指针p指向了数组calendar[4]中下标为0的元素。如果calendar[4]是一个数组,我们当然可以通过下标的形式来指定这个数组中的元素,就像下面这样:

i = calendar[4][7];
</div>

我们确实也可以这样做。还是与前面类似的道理,这个语句可以写成下面这样而表达式的意思保持不变:

i = *(calendar[4]+7);
</div>

这个语句还可以进一步写成:

i = *(*(calendar+4)+7);
</div>

从这里我们不难发现,用方括号的下标形式很明显地要比指针来表达简便得多。下面我们再看:

p = calendar;
</div>

这个语句是非法的,因为calendar是一个二维数组,即数组的数组,在此处的上下文中使用calendar名称会将其转化为一个指向数组的指针,而p是一个指向整型变量的指针,这个语句试图将一个类型的指针赋值给另一种类型的指针,所以是非法的。

很显然,我们需要一种声明指向数组的指针的方法,经过了前面对类似问题不厌其烦的讨论,构造出下面的语句应该不需要废多大力气:

int (*ap)[31];
</div>

这个语句的效果是,声明了*ap是一个拥有三十一个整型元素的数组ap就是一个指向这样的数组的指针,因而我们可以这样写:

int(*monthp)[31];
Monthp = calendar;
</div>

这样,monthp将指向数组calendar的第一个元素,也就是数组calendar的12个有着31个元素的数组类型元素之一。

假定在新的一年开始时,我们需要清空calendar数组,用下标形式可以很容易做到:

int month;

for(month=0;month < 12;month++){
 int day;
  for(day=0; day < 31;day++)
   calendar[month][day]=0;
}

</div>

上面的代码段如果才用指针应该如何表示呢?我们很容易地把 calendar[month][day]=0; 表示为*(*(calendar+month)+day)=0;

但是真正有关的部分是哪些呢?

如果指针monthp指向一个拥有31个整型元素的数组,而calendar的元素也是一个拥有31个整型元素的数组,因此就像是在其他情况中我们可以使用一个指针遍历一个数组一样,这里我们同样可以使用指针monthp以步进的方式遍历数组calendar:

int (*monthp)[31];
for(monthp=calendar;monthp < &calendar[12];monthp++){
 int *dayp;
 for(dayp=*monthp;dayp < &(*monthp)[31];dayp++)
 *dayp=0;
}
</div>

 

</div>
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C语言数组入门之数组的声明与二维数组的模拟

相关文章

  • 2017-05-28c++中数字与字符串之间的转换方法(推荐)
  • 2017-05-28C/C++实现字符串模糊匹配
  • 2017-05-28c语言实现顺序表的基本操作
  • 2017-05-28C语言函数的递归和调用实例分析
  • 2017-05-28c++面试题字符串拷贝函数示例
  • 2017-05-28MFC控件大小随窗体大小而改变
  • 2017-05-28深入解析C语言中typedef的四个用途
  • 2017-05-28VC判断一个文件为目录的方法
  • 2017-05-28VS2010 boost标准库开发环境安装教程
  • 2017-09-13k个最小和 K路归并问题

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • c++回调之利用函数指针示例
    • C语言 扫雷程序的实现
    • C语言中强制地址跳转详解
    • C与C++ 无参函数的区别解析
    • c++传递函数指针和bind的示例
    • 如何在二叉树中找出和为某一值的所有路径
    • 浅析C语言中assert的用法
    • Cocos2d-x中背景音乐和音效使用实例
    • 基于linux下C开发中的几点技术经验总结
    • c实现linux下的数据库备份

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有