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

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

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

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

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

如何声明一个数组

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

int a[3];

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

struct{
 int p[4];
 double x;
}b[17];

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

现在考虑下面的例子:

int calendar[12][31];

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

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

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

*a=84;

这个语句将数组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;

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

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

p=calendar[4];

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

i = calendar[4][7];

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

i = *(calendar[4]+7);

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

i = *(*(calendar+4)+7);

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

p = calendar;

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

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

int (*ap)[31];

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

int(*monthp)[31];
Monthp = calendar;

这样,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;
}

上面的代码段如果才用指针应该如何表示呢?我们很容易地把 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;
}

 

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c语言
, 二维数组
, 数组声明
, 入门
C语言入门
c语言声明二维数组、c 声明二维数组、js声明二维数组、java声明二维数组、二维数组声明,以便于您获取更多的相关知识。

时间: 2025-01-21 12:43:26

C语言数组入门之数组的声明与二维数组的模拟_C 语言的相关文章

C++实现二维图形的傅里叶变换_C 语言

本文实例讲述了C++实现二维图形的傅里叶变换的方法.有一定的借鉴价值.分享给大家供大家参考. 具体代码如下: // Fourier.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "stdio.h" #include "math.h" #include <cv.h> #include <highg

二维数组-新手, C语言寻找三维数组正切面最大和的值,测试对但WA, 有题目和代码, 望大神指点

问题描述 新手, C语言寻找三维数组正切面最大和的值,测试对但WA, 有题目和代码, 望大神指点 Description 给出一个长方体,求该长方体每个正切面上的元素之和的最大值. 正切面的意思就是与长方体某一面平行的切面.如果把长方体看作是一个三维数组,那么每个切面就是一个二维数组. Input 第一行是3个正整数a.b.c,分别表示长方体的长.宽.高.0 < a, b, c ≤ 60 接下来是 c 块数据,每一块数据有a行.每行b个整数. Output 输出切面元素和的最大值. Sample

关于js二维数组和多维数组的定义声明(详解)_javascript技巧

声明一维数组:var goodsArr = []; 赋值:goodsArr[0] = 'First Value'; 这个毫无争议,因为平时使用PHP比较多,而php语法是可以直接使用goodsArr[0] = 'First Value'; 这种方法声明数组并赋值的,但js不能这样使用,必须先声明数组存在.同理,如果是二维和多维数组在使用前也必须声明二维和多维的数组,举例二维数组: var goodsArr[0] = []; 必须先这样声明一下二维数组才能使用二维数组,否则会出错的. 以上就是小编

C语言及程序设计提高例程-33 二维数组元素的引用

贺老师教学链接  C语言及程序设计提高 本课讲解 输入输出二维数组元素 #include <stdio.h> int main() { int s[3][5], i, j; printf("Input 3*5 numbers\n"); for (i=0; i<3; i++) for(j=0; j<5; j++) scanf("%d", &s[i][j]); for (i=0; i<3; i++) { for(j=0; j<

详解C++中的一维数组和二维数组_C 语言

C++一维数组 定义一维数组 定义一维数组的一般格式为:     类型标识符  数组名[常量表达式]; 例如: int a[10]; 它表示数组名为a,此数组为整型,有10个元素. 关于一维数组的几点说明: 1) 数组名定名规则和变量名相同,遵循标识符定名规则. 2) 用方括号括起来的常量表达式表示下标值,如下面的写法是合法的: int a[10]; int a[2*5]; int a[n*2]; //假设前面已定义了n为常变量 3) 常量表达式的值表示元素的个数,即数组长度.例如,在"int

C++指针数组、数组指针、数组名及二维数组技巧汇总_C 语言

本文较为详细的分析了关于理解C++指针数组,数组指针,数组名,二维数组的一些技巧.是比较重要的概念,相信对于大家的C++程序设计有一定的帮助作用. 一.关于数组名 假设有数组: int a[3] = {1, 2, 3} 1.数组名代表数组第一个元素的地址,注意,不是数组地址(虽然值相等),是数组第一个元素地址,a 等同于 &a[0]; a+1是第二个元素的地址.比第一个元素地址a(或者&a[0])超出了一个整型指针的大小,在这里是4个字节(byte) cout << a <

c++读取txt文件里的数据,然后保存在二维数组中进行处理

问题描述 c++读取txt文件里的数据,然后保存在二维数组中进行处理 我写的程序是把数据自己输入在主函数里,但是如果想实际的应用应该是有一个数据文件,然后提取出数据文件的数据保存在二维数组中才对,而且这个二维数组要根据具体文件的大小定数组的行列数,有谁能帮我做一下吗,谢谢! #include #include #include using namespace std; #define M 10//二维数组的行 #define N 6//二维数组的列 class Data { double a[M

2013级C++第15周项目——二维数组

课程主页在:http://blog.csdn.net/sxhelijian/article/details/11890759 [项目1-折腾二维数组]创建一个长度为5行4列的二维整型数组,通过初始化,为数组中的前两列的10个元素赋初值,然后通过键盘输入,使后两列的10个元素获得值,将所有元素值乘以3后保存在数组中.输出数组时,按行序优先输出,再按列序优先输出(输出的第一行是数组中的第一列--,其实输出的就是"转置"),再将数组"倒"着输出(即最后一行最后一列的最先输

唉,老有问题,水平太菜,二维数组问题

问题描述 声明了二维数组DimList(,)asstring下面redimList(2,10)引用的时候List(0,)无效List(0,0)貌似有效但是到了ListBox.copyto功能又不行了这句Listbox1.Items.CopyTo(List,0)报错说,List不是一个对象莫非又要我自己循环copy? 解决方案 解决方案二:可能有误解,这个copyto功能,我是想copy到List(0,X)里面去的解决方案三:DimList()asstring'动态数组并不需要预先确定维数下面re