学数组,这一篇就够了

每日一句:

伤害人的并非事件本身,而是他对事件的看法。

戴尔·卡耐基—《人性的弱点》


今日,我们请来了一位老大,别看他只是个人,他能装的东西比你还要多呢。

老大的简介:

(array)是按顺序储存的一系列相同的值,可以是10个char类型的字符或15个int类型的值。没错,这位老大便是数组。这位老大还是有许多小弟的,这些小弟姓什么呢,有个专门的名字叫元素。没错,整个数组有一个数组名,通过整数下标访问数组中单独的项或元素(element)。

如何定义数组呢:

int name[10];//说明可存储10个int类型整数的数组char name[10];//说明可存储10个字符的数组

老大介绍得差不多了,那么接下来便是介绍小弟(数组里的元素)了。小弟可是很厉害的呢,它可以是任意数据类型哦。

我们将用于识别数组元素的数字称为下标(subscript),索引(indice),或偏移量(offset)。需要注意的是下标必须是整数哦,下标中的整数也代表了数组中有多少元素,而且要从0开始计数。下标也是存在陷阱的,因为怕影响到执行的速度,C编译器是不会检查数组的下标是否正确的哦。而且数组的元素是被依次存在内存中相邻的位置。

int name[10];//元素为name[0]~name[9]name[10]=55;//这个便是错的,该数组元素不存在

注意:每个int为2字节,char为1字节。顺便扩展一下位、字,字节与KB的关系:

KB  1KB=1024B

MB  1MB=1024KB

GB  1GB=1024MB

TB  1TB=1024GB

int类型数组元素的用法和int类型变量的用法类似,比如要读取int类型变量name,应该这样写

scanf("%d",&name);//读取变量scanf("%d",&name[n]);//读取数组

昨天我们运用了许多的for循环,就有小伙伴跟我说那么多for可以独立出来写么,独立的for循环我个人不建议。将for循环合并成一个循环可以使程序显得更加紧凑,但我们也要遵循模块化的原理。模块化主要是把程序划分为一些独立的单元,每个单元执行一个任务,这样也能提高程序的可读性。更重要的是模块化使程序的不同部分彼此独立,方便以后对程序的修改。

如何能更好的提高程序的可读性呢?见下:

如何全面提高程序的可读性

当我们定义数组后,该如何赋值呢:

int name[5]={1,2,3,4,5};int name[5]={1,2,3,4};

我们认真看就会发现第一行和第二行的差别,第一行将5个值赋给了name,而第二行却只有4个数值,那么还差一个怎么办呢?不用怕,编译器会为它补上0的,但也只能补0哦。

接下来我们就来更加详细的介绍数组:

初始化数组

数组通常被用来存储程序需要的数据。比如一个内含12个整数元素的数组就可以存储12个月的天数。在这种情况下,在程序一开始就初始化数组比较好。大家知道什么是标量变量么,简单说就是只存储单个值的变量。接下来我们来初始化这种变量:

float flax=PI*2;/*PI已定义为宏*/

初始化数组:

int main(){int name[5]={1,2,3,4,5};...}

如上所示,我们用以逗号分隔的值列表(用花括号括起来的)来初始化数组,各值之间用逗号分隔,在逗号和值之间可以有空格。上面的初始化是把1赋值给数组的首元素(即name[0])。

下面给大家展示一个简单的程序:

#include<stdio.h>int main(){ const int days[]={31,28,31,30,31,30,31,31,30,31};int index;for(index=0;index<sizeof day/sizeof days[0];index++)printf("Month %2d has %d days.\n",index+1,days[index]);return 0;}

运行结果如图:

这里需要注意如下几点:

NO.1我们在上面初始化数组时是省略了方括号中的数字,编译器会根据初始化列表中的项数来确定数组的大小。

NO.2 Sizeof运算符给了它运算对象的大小(以字节为单位)。使用Sizeof days 是整个数组的大小,Sizeof day[0]是数组中元素的大小。整个数组的大小除以单个元素的大小就是数组元素的个数。

指定初始化器

C99多了一个新特性:指定初始化器。利用该特性可以初始化指定的数组元素。

例如可以在初始化列表中使用带方括号的下标指明待初始化的元素:

  • int shu[6]={[5]=55};//把shu[5]初始化为55

    一般来说,在初始化一个元素后,没有被初始化的元素都会被设置为0。以下面程序为例:#include<stdio.h>#define months 12int main (){ int days[months]={31,28,[4]=31,30,31,[1]=29};int i;for(i=0;i<months;i++){printf("%2d %d\n",i+1,days[i]);}return 0;}

    运行如下:

    该程序需要注意以下几点(需要多多思考哦):

    NO.1 如果指定初始化器后面有更多的值,如该例中的初始化列表中的片段:[4]=31,30,31,那么后面这些值将被用于初始化为30和31.

    NO.2 如果再次初始化指定的元素,那么最后的初始化将会取代之前的初始化。比如上面的程序中初始化列表开始时把days[1]初始化为28,,但是days[1]又被后面的指定初始化[1]=29初始化为29.

    NO.3 说到如果没有指定元素大小会怎样呢?如下:

  • int shu[]={1,[6]=2};//该数组有7个元素int shu[]={1,[6]=2,3};//该数组有8个元素

    即:编译器会把数组的大小设置为足够装得下初始化的值。

    数组边界

    我们在使用数组时,要防止数组下标越过边界。简单来说就是确保下标是有效的值。比如:

  • int you[20];

    在使用该数组时,就需要注意在程序中使用的数组下标在0~19的范围内,况且编译器不会检查出这种错误。前面也说到过。

    因此,使用越界的数组下标会导致程序改变其他变量的值。不同的编译器运行该程序的结果可能也会不同哦,有的甚至会导致程序异常中止。

    还要记住一点就是数组元素的编号是从0开始的哦,最好是在声明数组时使用符号常量来表示数组的大小。

    数组下标

    C99标准允许了一种新型的声明方式:

  • int a1[n];//c99之前是不允许这样的哦

    这创建了一种新型数组,称为变长数组。简称VLA(C11放弃了这一举措,把VLA设定为可选,而不是语言必备的特性)

    C99引入变长数组主要是为了让C成为更好的数值计算语言。

    注意:变长数组是指用整型变量或表达式声明或定义的数组,而不是说数组的长度会随时变化,变长数组在其生存期内的长度同样是固定的。

    多维数组

    上面把数组介绍得差不多了,那么下面就开始介绍二维和多维数组。我们可以把一维数组想象成一行数据,把二维数组想象成数据表,把三维数组想象成一叠数据表。

    现在用一个项目来讲解二维数组:

    如果有一个气象员想要收集5年内每个月的降水量数据,那么他要如何表示数据呢?一个方案是创建60个变量,每个变量存储一个数据项,显然这个方法太麻烦。那么我们就可以用到二维数组来解决,即创建一个主数组,主数组含有5个元素,每个元素是内含12个元素的数组(每个元素表示一个月)。

    声明数组如下:

  • float rain[5][12];//内含5个数组元素的数组,每个数组元素内含12个float类型的元素

    float rain[5][12]  //颜色部分是指rain是一个内含5个元素的数组;非颜色部分则是指一个含有12个float类型元素的数组。

    这说明每个元素的类型都是float[12],简单说也就是rain的每个元素本身都是一个内含12个float类型值的数组。那么rain[0]是一个数组,它的首元素就是rain[0][0],第二个便是rain[0][1],以此类推。

    该项目代码如下:

    #include<stdio.h>#define months 12//12个月#define years 5//年数int main(){const float rain[years][months]={{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},{4.1,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},{4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},};//初始化时可省略内部的花括号,只要保证初始化的数值个数正确int year,month;float subtot,total;printf("year    rainfall   (inches)\n");for (year=0,total=0;year<years;year++)//每一年,各月的降水量总和{ for(month=0,subtot=0;month<months;month++)subtot+=rain[year][month];printf("%5d %15.1f\n",2015+year,subtot);total+=subtot;} //5年的总降水量printf("\nThe yearly average is %.1f inches.\n\n",total/years);printf("monthly averages:\n\n");printf("Jan Feb Mar Apr May Jun Jul Aug Sep Oct");printf("Nov Dec\n");for(month=0;month<months;month++){for(year=0,subtot=0;year<years;year++)subtot+=rain[year][month];printf("%4.1f",subtot/years);}printf("\n");return 0;}

    运行结果如下:

    此程序计算了每年的总降水量,年平均降水量和月平均降水量。

    该程序使用了两个嵌套for循环,第一个是嵌套for循环的内层循环,在year不变的情况下,遍历month计算某年的总降水量;外层循环则改变year的值,重复遍历month,计算五年的总降水量。

    这里我们可以看到处理二维数组需要处理用到2重嵌套循环,通常来说,处理三维数组需要用到3重嵌套循环,四维则需要用到4重嵌套循环。

    我们说的二维数组的许多相关内容都适用于三维或者多维数组。比如声明一个三维数组如下:

  • int name [3][3][3];

    最后的话

    相信你学到这里或多或少都对数组有了一定的了解,想要更好的理解数组,建议多看几遍哦。这也是经过多次阅读书籍从而整理出来数组里最重要的一些知识点。希望大家看完这篇文章后对数组有更好的了解。

    5个超正经的网站

    让它助你完成假期“超车”

    一个正在学习C语言的人,致力于将C讲得更透彻!

    点赞关注~谢谢你~

    长按下图二维码关注,和你一起领悟程序员的魅力。


  • ©著作权归作者所有,转载或内容合作请联系作者
    • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
      沈念sama阅读 214,922评论 6 497
    • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
      沈念sama阅读 91,591评论 3 389
    • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
      开封第一讲书人阅读 160,546评论 0 350
    • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
      开封第一讲书人阅读 57,467评论 1 288
    • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
      茶点故事阅读 66,553评论 6 386
    • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
      开封第一讲书人阅读 50,580评论 1 293
    • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
      沈念sama阅读 39,588评论 3 414
    • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
      开封第一讲书人阅读 38,334评论 0 270
    • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
      沈念sama阅读 44,780评论 1 307
    • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
      茶点故事阅读 37,092评论 2 330
    • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
      茶点故事阅读 39,270评论 1 344
    • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
      沈念sama阅读 34,925评论 5 338
    • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
      茶点故事阅读 40,573评论 3 322
    • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
      开封第一讲书人阅读 31,194评论 0 21
    • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
      开封第一讲书人阅读 32,437评论 1 268
    • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
      沈念sama阅读 47,154评论 2 366
    • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
      茶点故事阅读 44,127评论 2 352

    推荐阅读更多精彩内容

    • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
      夏天再来阅读 3,340评论 0 2
    • 数组在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称...
      朱森阅读 3,917评论 2 13
    • 转载:在开发中,数组的使用场景非常多,平日中也涉及到很多数组的api/相关操作,一直也没有对这块内容进行一块整理总...
      七色烟火阅读 3,214评论 0 3
    • 0.linux启动的步骤 设备加电----》BIOS自检-----》grub引导启动-----》加载内核----》...
      萌面大叔2阅读 776评论 0 1
    • 创意无处不在,关键在于你是否细心观察,是否能大胆想象。很多时候都是我们自己把自己固化了,每天跳不出思维的陷阱,所以...
      环盈阅读 100评论 1 0