一、实验目的及要求
(一)掌握一维与二维数组的定义、初始化、赋值及输入输出的方法;掌握数组名在程序中的地址本质
(二)掌握与一维数组有关的程序和算法;二维数组有关的算法如查找、矩阵转置等;
(三)了解用数组处理大量数据时的优越性。
(四)掌握用二维数组编写程序解决问题的应用与方法。
(五)掌握字符数组的定义、初始化和应用; 掌握字符串处理函数的使用,了解字符串编程的各种应用场景。
二、实验内容、过程和结果(实验主要内容的介绍、主要的操作步骤、程序代码和测试数据及实验结果)
定义方式:类型说明符 数组名 [常量表达式]; 数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。 数组名的书写规则应符合标识符的书写规定。 数组名不能与其它变量名相同 方括号中常量表达式表示数组元素的个数,如a[5]表示数组a有5个元素。但是其下标从0开始计算。因此5个元素分别为a[0], a[1], a[2], a[3], a[4]。 不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。 不能先给变量赋值再在方括号中用变量表示元素个数,这是不合法的 但我们可以利用宏定义巧妙解决这个问题 #define n 10 将n的值全视作10 其后的a[n]会被视为a[10]; 允许在同一个类型说明中,说明多个数组和多个变量。 数组名表示数组存储区的首地址,即数组第一个元素存放的地址
数组元素的一般形式为: 数组名[下标] 不能将数组作为整体引用,只能逐个引用数组元素,因此数组下标十分关键 其中下标只能为整型常量或整型表达式。如为小数时,C编译将自动取整 使用for循环为一个数组赋值,并将数组倒叙输出。
数组初始化赋值是指在数组定义时给数组元素赋予初值。数组初始化是在编译阶段进行的。这样将减少运行时间,提高效率。初始化赋值的一般形式为: 其中在{ }中的各数据值即为各元素的初值,各值之间用逗号间隔。 相当于a[0]=0; a[1]=1 ... a[9]=9; 1可以只给部分元素赋初值。当{ }中值的个数少于元素个数时,只 给前面部分元素赋值 表示只给a[0]~a[4]5个元素赋值,而后5个元素自动赋0值。 对于变量,为赋初值则为随机数,若是未初始化数组元素,int类型则初值为0,char则为空字符 2只能给元素逐个赋值,不能给数组整体赋值。例如给十个元素全部赋1值,只能写为: 不能写成int a[10]=1; 3如给全部元素赋值,则在数组说明中,可以不给出数组元素的个数。例如: 4不允许数组确定的元素少于赋值个数
1从键盘输入十个数字 求出最大与最小值 并按逆序打印出该数组 2输入10个数字并按从大到小的顺序排列。
输入十次数字,之后需要进行(10-1)次循环实现比较,在每一趟时需要进行(10-1-i)次比较 相邻俩个数字比较 3一维数组从小到大排序,第一个与后面数依次比较 4将100以内素数储存在一个数组中
循环时可简化数据减少循环次数 5输出一堆数组中最大值以及下标
6求一维数组中下标为偶数的元素之和并输出 7设置成绩记录班上同学成绩,按成绩从高到低,同时记录班上不及格人数和平均分
二维数组形式:dataType arrayName[length1][length2]; dataType 为数据类型,arrayName 为数组名,length1 为第一维下标的长度,length2 为第二维下标的长度。 length1、length2都为常量表达式,我们可以将二维数组看做一个 Excel 表格,有行有列,length1 表示行数,length2 表示列数,要在二维数组中定位某个元素,必须同时指明行和列。 在C语言中,二维数组是按行排列的。也就是先存放 a[0] 行,再存放 a[1] 行,最后存放 a[2] 行;每行中的 4 个元素也是依次存放。数组 a 为 int 类型,每个元素占用 4 个字节,整个数组共占用 4×(3×4)=48 个字节。 你可以这样认为,二维数组是由多个长度相同的一维数组构成的。
1打印十行杨辉三角 可以根据宏定义改变n的值改变打印行数 第一个for循环是为了定义边界的1 第二个for循环开始是为了设置算法 a[i][j] = a[i - 1][j - 1] + a[i - 1][j]; 第三个for循环是为了打印出这个二维数组 2定义一个5行5列的二维数组a,使下三角的所有元素初始化为1 3求一个4×4矩阵的主对角线元素之和 4统计3个学生,每个学生4门课程的考试成绩,要求输出每个学生的总成绩,每个学生的平均成绩,3个学生的总平均成绩
5矩阵转置
字符数组顾名思义就是数组的元素类型为字符型的数组。它是数组元素为字符的数组。其定义的一般形式和注意事项与之前讲解的一般数组类似,只是其中的类型说明符是char,并不是说类型说明符只能是char,也可以是long、int等,但是由于char型只占用一个字节的大小,使用long型和int型来定义字符数组会造成资源的浪费,因此一般选择使用char型来定义字符数组。 同样内容long所占内存更多,会浪费资源。故用char。
定义的arr数组,其数组长度为20,而初始化的字符元素的个数为12,初始化的字符元素个数小于数组长度,编译器在编译过程中将后面没有初始化的数组元素赋值为‘\0’,这也正是打印输出中含有空字符的原因 初始化字符数组有俩种方法:将字符逐渐赋值给数组中每个元素;直接将字符串常量赋值给数组 直接用字符串常量赋值时,要注意:其默认长度是5+1=6 其会在末尾自动加一个’\0’ 这里要为a数组设置一个‘\0’避免越界; 在这里为a数组末尾设置结束标记,也可在其他地方设置 C语言规定’\0’为字符串结束标志,其占内存空间但不计长度
与整型数组一样,字符数组不能用赋值语句整体赋值,一般对字符数组的输入只能对数组元素逐个进行,字符数组的输出可以逐个进行也可以一次性成串输出 1字符串的输入:scanf()和gets() 这两个函数可以让用户从键盘上输入字符串,它们分别是:
但是,scanf() 和 gets() 是有区别的:
gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束 scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了 用俩个scanf连接起来 2字符串的输出:printf()和puts()
C语言中有一批字符串处理函数,在string.h这个头文件,除puts,gets在外。 C语言里没有string这个类型。 1strlen()字符串长度函数 strlen(字符数组) strlen() 函数计算的是字符串的实际长度,遇到第一个’\0’结束,并不包括\0 这里的字符数组可为字符数组名or字符串 2strcat函数连接字符 原型:strcat(str1,str2); 它会将将字符串str2添加到字符串str1的尾部,也就是拼接两个字符串,自动删除str1字符串结束符’\0’,并将结果放到str1中。该函数的函数值是字符数组1地址. 注意:字符数组1长度要足够容纳字符2中的字符串 原型2:strncat(str1,str2,n); 功能2:将字符串str2的前n个字符添加到字符串str1的尾部 返回:str1 3strcpy函数 原型:strcpy(str1,str2); 该函数的函数值是str1首地址. 功能:将字符串str2复制到字符串str1中,并覆盖str1原始字符串,可以用来为字符串变量赋值 返回:str1 注意:1)字符串str2会覆盖str1中的全部字符,2)字符串str2的长度不能超过str1 原型2:strncpy(str1,str2,n); 功能:将字符串str2中的前n个字符复制到字符串str1的前n个字符中 返回:str1 注意:1)不会清除str1中全部字符串,只会改变前n个字符串,2)n不能大于字符串str1、str2的长度 3)但是如果使用strncpy_s便会清除str1中的全部字符串 VS2019只能用strncpy_s 4.strcmp函数 原型:strcmp(str1,str2); 功能:比较两个字符串,如果两个字符串相等,则返回0;若str1大于str2(对于大于的理解,是指从两个字符串的第一个字符开始比较,若两个字符相同,则继续比较,若发现两个字符不相等,且str1中该字符的ASCII码大于str2中的,则表示str1大于str2),返回一个正数(这个正数不一定是1);若str1小于str2,返回一个负数(不一定是-1);若字符串str1的长度大于str2,且str2的字符与str1前面的字符相同,则也相对于str1大于str2处理 原型2:strncmp(str1,str2,n); 功能2:比较两个字符串的前n个字符 原型3:stricmp(str1,str2); (在Windows中使用stricmp,在Linux中使用strcasecmp) 功能3:忽略两个字符串中的大小写比较字符串,也就是对大小写不敏感 注意:如果在VS2019中直接使用stricmp会提示如下错误: 原因和处理办法见:stricmp错误,即用_stricmp代替 //输入五个字符串,把最大的字符串输出来 //探究比较函数的不同
1不使用strcat函数实现字符连接 2 字符串中的大写字母转为小写字母 3统计字符数 注意:scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。 因此我们用getchar 4编写程序实现在一个字符串中查找指定的字符,并输出指定的字符在字符串中出现的次数及位置,如果该字符串中不包含指定的字符,请输出提示信息。 |
三、实验总结与收获
1不能先给变量赋值再在方括号中用变量表示元素个数,这是不合法的,但我们可以利用宏定义巧妙解决这个问题; 2不能将数组作为整体引用,只能逐个引用数组元素; 3对于变量,为赋初值则为随机数,若是未初始化数组元素,int类型则初值为0,char则为空字符; 4记得为数组设置一个‘\0’避免越界; 5 scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了;gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束。 6要注意askII码在数组中的运用。
1本次实验主要是对数组的一个了解和应用,从一维数组→二维数组→字符数组,感受到了一个循序渐进的过程,也感受到了数组才处理大量数据的优越性,这点在统计学生成绩时有明显感受,通过宏定义,可以去改变数组的元素量,从而实现多个数据处理。 2相较于上次,通过多次练习,对C语言格式掌握得更加到位,虽然有时候还是会犯“==”与“=”弄错的小错误,但犯错次数逐渐减少,还是很开心的。 3能够开始更加独立的编写代码,遇到一个问题开始学会先通过自己的方法尝试,而不是一味的看着指导做,在编写代码成功的那一刻会更加有成就感。 |