C语言数组
先来看一个需求,超女选秀一共有5人参加,输入每位超女的体重并保存在变量中,最后计算出超女的的平均体重。
示例(book40.c)
1 | /* |
如果有100名超女,这个程序将会很长很烦锁。
一、数组
数组(array)是一组数据类型相同的变量,可以存放一组数据,它定义的语法是:
1 | 数据类型 数组名[数组长度]; |
例如:
1 | double money[20]; |
money是一个数组,包含了20个元素,每个元素都一个double类型的变量,可以通过下标访问数组中元素(element),数组下标的编号从0开始,数组的第1个元素是money[0],第2个元素是money[1],以此类推,直到第20个元素money[19]。
给每个元素赋double类型的值,可以这样写:
1 | money[0] = 10.55; |
定义数组的时候,数组的长度必须是整数,可以是常量,也可以是变量。
数据的下标也必须是整数,可以是常量,也可以是变量。
使用数组元素和使用同类型的变量一样。
1 | scanf("%lf", &money[4]); // 把一个值读入数组的第5个元素 |
数组的类型可以是任意数据类型。
1 | int no[22]; // 可储存22个int类型整数的数组 |
二、占用内存的大小
我们已经知道如何获取单个变量占用内存大小的方法。
1 | int ii; // 定义一个整型变量 |
数组是有多个变量组成,占用内存总空间的大小为多个变量占用的内存空间之和,用sizeof(数组名)就可以得到整个数组占用内存的大小,如下:
1 | int ii[10]; // 定义一个整型数组变量 |
三、数组的初始化
采用memset函数对数组进行初始化,如下:
1 | int no[10]; |
第一个参数是数组名,第二个参数填0,第三个参数是数组占用的内存总空间,用sizeof(变量名)获取。
四、注意事项
1)定义数组的时候,数组的长度必须是整数,可以用常量和变量。
1 | int size=100; |
2)使用数组的时候,数组的下标也必须是整数,可以用常量和变量。
3)使用数组的时候,编译器不会检查数组的下标是否正确,但是在程序中下标一定不能越界,如果程序运行时数组下标越界,就相当于访问了其它程序的内存,可能会导致程序异常中断(Core dump),后果非常严重。
示例(book41.c)
1 | /* |
运行效果
段错误,就是程序非法操作内存,引起程序的崩溃。
如果数组的下标越界了,是不是一定会引起程序的崩溃呢?不一定,如果把book41.c的循环改为6,可能就不会出现段错误。
五、在for循环中数组
在学习了数组的知识以后,本章节开始时的那个需求有了更好的解决方法,程序book40.c必须修改。
示例(book42.c)
1 | /* |
运行效果
for循环提供了一个简单直接的方法来使用数组下标,使用数组和for循环处理数据,这比使用5个单独的scanf语句方便得多。不管是5个还是100个超女,程序也不会再增加代码。
六、二维数组
二维数组定义的语法是:
1 | 数据类型 数组名[第一维的长度][第二维的长度]; |
在我们现实生活中,二维数组到处都是,例如超女选秀,一共有5个小组,每组4人,如果要指明某位超女,必须同时指明该超女的小组编号和她在组内序号。
1 | int girl[5][4]; |
也可以将二维数组看成一个坐标系,有 x 轴和 y 轴,要想在一个平面中确定一个点,必须同时指定 x 和 y 值。
二维数组的初始化也是用memset,例如:
1 | memset(girl,0,sizeof(girl)); |
把本章节刚开始的那个需求增加一点难度:超女选秀有3个组,每组有5名选手,请提供一个界面,输入每个超女的体重,最后计算每组的超女的平均体重。
示例(book43.c)
1 | /* |
运行效果
七、多维数组
从二维数组可以类推出多维数组的用法,在实际开发中,二维以上的数组应用场景很少。
对初学者来说,建议先不要把这个问题复杂化,能掌握一维和二维数组就可以了,等功力提升之后,会发现多维数组其实也很容易。
八、字符串
1、字符串的概念
字符串就是一个以空字符’\0’结束的字符数组,是一个特别的字符数组,这是约定,是规则。
空字符’\0’也可以直接写成0。
因为字符串需要用0结束,所以在定义字符串的时候,要预留多一个字节来存放0。
1 | char name[21]; // 定义一个最多存放20个字符或10个汉字的字符串 |
2、字符串的初始化
字符串是数组,当然可以用初始化数组的方法来初始化字符串。
1 | char strname[21]; |
3、字符串的赋值
如果想在strword中存入字符串“hello”,可以用strcpy函数,也可以采用以下代码:
1 | strcpy(strword,"hello"); |
4、关于字符串结束符0的讨论
您可能会问,如果字符串不用0结束,会有什么样的结果,我们用代码来演示一下。
示例(book44.c)
1 | /* |
运行效果
可以看到,输出abc之后,有乱码,并且每次执行程序输出的结果不可预知。
您可能还会问,如果字符串以0结束了,但是后面的内容并不是0,怎么办?后面的内容将被丢弃。
5、字符串数组
以0结束的一维字符数组是一个字符串。
1 | char strname[21]; // 可以存放20个字符的字符串 |
给一维字符数组加上一维,就是字符串数组了。
1 | char strname[10][21]; // 10个字符串,每个字符串可以存放20个字符 |
十、课后作业
1)编写示例程序,从界面上输入一个字符串,计算字符串的长度。如果输入的是"abcdaaf",显示的结果是7。
2)编写示例程序,从界面上输入一个字符串,把字符串的每个字符从左到右一个一个的显示出来,如果输入的是"abcdaaf",显示的结果是:a b c d a a f。
3)编写示例程序,从界面上输入一个字符串,把字符串的每个字符从右到左一个一个的显示出来,如果输入的是"abcdaaf",显示的结果是:f a a d c b a。
4)编写示例程序,某班有10个学生,定义一个一维数组,从界面上输入每个学生的成绩,最后显示这个班的平均成绩。
5)编写示例程序,某年级有两个班,每班有8名学生,定义一个二维数组,从界面上输入每个学生的成绩,最后显示每个班的平均成绩和年级的平均成绩。
6)编写示例程序,定义一个可以存放10个字符串的数组,字符串的有效长度是30个字符,从界面上输入10个字符串并存放在数组中,然后把这10个字符串显示出来。
以下题难难度较大,可以等到以后功力提升的时候再做。
7)如果还觉得不过隐,可以挑战一下三维数组,某学校有两个年级,每个年级有三个班,每个班有四名学生,从界面上输入每个学生的成绩,最后显示每个班的平均成绩、年级的平均成绩和全校的平均成绩。
别玩三维以上的数组,没什么意义。
十一、版权声明
C语言技术网原创文章,转载请说明文章的来源、作者和原文的链接。
来源:C语言技术网(www.freecplus.net)
作者:码农有道