中国科技大学C语言讲义.ppt

上传人:xt****7 文档编号:16097503 上传时间:2020-09-19 格式:PPT 页数:51 大小:879KB
返回 下载 相关 举报
中国科技大学C语言讲义.ppt_第1页
第1页 / 共51页
中国科技大学C语言讲义.ppt_第2页
第2页 / 共51页
中国科技大学C语言讲义.ppt_第3页
第3页 / 共51页
点击查看更多>>
资源描述
数组是一组有序数据的集合,数组中每一个元素的类型相同。用数组名和下标来唯一确定数组中的元素。 6.1 1维数组的定义和引用 6.2 2维数组的定义和引用 6.3 字符数组与字符串,第6章 数 组,1、一维数组的定义,定义方式:,存储类型符 数据类型符 数组变量名整型常量表达式;,数组中各元素的存储类别,数组元素的数据类型,合法的标识符,表示元素个数 下标从0开始,用分号结尾,例如: int a10; /定义了有10个数据元素的int型数组a float f20; /定义了有20个数据元素的float型数组f char str110, str220; /定义了有10个和20个数据元素的char型 数组str1和str2,6.1 1维数组的定义和引用,定义说明:,(1) 数组定义时,必须指定数组的大小(或长度),数组大小必须是整型常量表达式,不能是变量或变量表达式。 (2) 数组定义后,系统将给其分配一定大小的内存单元,其所占内存单元的大小与数组元素的类型和数组的长度有关。,数组所占内存单元的字节数 = 数组大小 sizeof(数组元素类型),例如,下面对数组的定义是错误的: int n = 10; int an; /数组的大小不能是变量 int b10.3; /数组的大小不能是浮点常量 int cn+10; /数组的大小不能是变量表达式,例如:short int a20; 则数组a所占内存单元的大小为:20 * sizeof(short) = 20 * 2 = 40(字节),2、一维数组的引用,引用格式:,数组变量名下标,引用说明:,(1) 下标可以是整型常量、整型变量或整型表达式。C语言规定,下标的最小值是0,最大值则是数组大小减1。注意越界问题。 (2) 只能逐个引用数组元素,不能一次引用整个数组 (3) 数组定义以后,数组中的每一个元素其实就相当与一个变量,所以我们有时也把数组元素称为下标变量。对变量的一切操作同样也适合于数组元素。 (4) 数组必须先定义,后使用,存储单元有效地址 = 数组的起始地址 + 下标 sizeof(数组元素类型) short int a10; short x = a10; /引用越界,a10的地址为:2000 + 10 * 2 = 2020, 只能引用a0a9,例 int a10; printf (“%d”, a); () 必须 for (j = 0; j 10; j+) printf (“%dt”, aj); (),例:int a3; a0 = 2; /将数组a的第1个元素赋值为2 a1 = 4; /将数组a的第2个元素赋值为4 a2 = a0 + a1; /将数组a的第1个元素的值与第2个元 素的值相加赋给第3个元素(值为6),例 int x = a1; /错误,应先定义数组a,再引用 int a10;,例 使数组元素a0a9的值为09,然后逆序输出。 #include “stdio.h” void main() int i,a10; for (i=0;i=0; i-) printf(%d ,ai); 运行输出:9 8 7 6 5 4 3 2 1 0,3、一维数组的初始化 1、一般初始化, 例、static int a10 = 0,1,2,3,4,5,6,7,8,9; int array10 = 1,2,3,4,5,6,7,8,9,10; 2、部分元素初始化, 例、static int a10 = 0,1,2,3,4; 3、全部元素均初始化为0,不允许简写。 例、 static int a10 = 0,0,0,0,0,0,0,0,0,0; 不能简写为:static int a10 = 0*10; 4、如果全部元素均指定初值,定义中可以省略元素的个数, 例、static int a = 1,2,3,4,5;,一维数组在程序中赋值,C语言除了在定义数组变量时用初值列表对数组整体赋值以外,无法再对数组变量进行整体赋值。,例 int a5; a = 1, 2, 3, 4, 5; a = 1, 2, 3, 4, 5; a5 = 1, 2, 3, 4, 5;,错误!,数组定义后,如何对数组进行赋值呢? 只能通过C语句对数组中的数组元素逐一赋值。,使用赋值语句来逐一赋值,例 int a4; a0 = 1; a1 = 2; a2 = 3; a3 = 4; char str80; str0 = b; str1 = y; str2 = e; str3 = 0; /将数组str赋值为一字符串bye,这种方法是一种简单而且行之有效的方法,它适用于长度较小的数组或对长度较大的数组部分元素赋值,而且可对每个数组元素赋不同的值。,一维数组在程序中赋值,使用循环语句来逐一赋值,例如,将数组a的各元素赋值成奇数序列。 int a10, i; for (i = 0; i 10; i+) ai = 2* i + 1;,例如,接受用户键盘输入赋值给数组各元素。 int a10, i; for (i = 0; i 10; i+) scanf(%d, ,判断下列赋值是否正确? int a3; scanf (%d%d%d, a);,这种方法是在编程中普遍使用的一种方法,它适用于对某数组元素进行有规律的赋值或接受用户通过键盘输入对数组元素的赋值 。,4、一维数组应用举例,【例1】输入一行字符,统计其中各个大写字母出现的次数。,#include void main ( void ) char ch; int num26=0, i; while (ch = getchar( ) != n) /输入字符串,判断统计 if (ch = A ,运行结果: AABBCCxyYzEEE A(2) B(2) C(2) D(0) E(3) F(0) G(0) H(0) I(0) J(0) K(0) L(0) M(0) N(0) O(0) P(0) Q(0) R(0) S(0) T(0) U(0) V(0) W(0) X(0) Y(1) Z(0),4、一维数组应用举例,【例2】用冒泡排序法将10个整数按照从小到大的顺序排序,排序过程: (1) 比较第一个数与第二个数,若为逆序a0a1,则交换;然后比较第二个数与第三个数;依次类推,直至第n-1个数和第n个数比较为止第一趟冒泡排序,结果最大的数被安置在最后一个元素位置上; (2) 对前n-1个数进行第二趟冒泡排序,结果使次大的数被安置在第n-1个元素位置; (3) 重复上述过程,共经过n-1趟冒泡排序后,排序结束,38,49,76,97,97,97,97,13,27,30,13,76,76,76,27,30,13,65,65,65,27,30,13,49,49,49,27,30,13,38,38,38,27,30,冒泡排序图示效果,#include #define NUM 10 void main ( ) int aNUM, i, j, t; printf (input %d numbers: n, NUM); for (i = 0; i aj+1) /交换aj和aj+1 t = aj; aj = aj+1; aj+1 = t; /输出排好序的数据 printf (the sorted numbers:n); for (i = 0; i NUM; i+) printf (%d , ai); ,运行结果: input 10 numbers: 10 1 2 7 6 8 9 3 4 5 the sorted numbers: 1 2 3 4 5 6 7 8 9 10,不足之处:对已排好序的序列仍然要进行9轮冒泡操作,尽管不会有任何数据交换操作。,如何修改呢?,对冒泡排序的改进: 当一次冒泡过程中发现没有交换操作时,表明序列已经排好序了,便终止冒泡操作。为了标记在比较过程中是否发生了数据交换,在程序中设立一个标志变量flag,在每趟比较前,把flag变量置为0,如果在这趟比较过程中发生了交换,把变量flag的值置为1。在这一趟比较结束后判断如果flag变量取值等于0表示可以结束排序过程,否则进行下一趟比较。,#include #define NUM 10 void main ( ) int aNUM, i, j, t, flag; printf (input %d numbers: n, NUM); for (i = 0; i aj+1) /交换aj和aj+1 t = aj; aj = aj+1; aj+1 = t; flag = 1; if (flag = = 0) break; printf (the sorted numbers:n); /输出排好序的数据 for (i = 0; i NUM; i+) printf (%d , ai); ,4、一维数组应用举例,【例3】用选择排序法将10个整数按照从小到大的顺序排序,排序过程: (1) 首先通过n-1次比较,从n个数中找出最小的, 将它与第一个数交换第一趟选择排序,结果最小的数被安置在第一个元素位置上; (2) 再通过n-2次比较,从剩余的n-1个数中找出关键字次小的记录,将它与第二个数交换第二趟选择排序; (3) 重复上述过程,共经过n-1趟排序后,排序结束。,初始: 49 38 65 97 76 13 27 ,i = 1,13,49,一趟: 13 38 65 97 76 49 27 ,i = 2,27,38,二趟: 13 27 65 97 76 49 38 ,三趟: 13 27 38 97 76 49 65 ,四趟: 13 27 38 49 76 97 65 ,五趟: 13 27 38 49 65 97 76 ,六趟: 13 27 38 49 65 76 97 ,选择排序图示效果,#include void main( ) int a11, i, j, k, x; printf (Input 10 numbers: n); for (i = 1; i 11; i+) scanf (%d, ,【例4】 用数组求Fibonacci数列 前20个数,#include void main( ) int i; int f20 = 1, 1; for (i = 2; i 20; i+) fi = fi-2 + fi-1; for (i = 0; i 20; i+) if (i % 5 = 0) printf (n); printf (%12d, fi); ,4、一维数组应用举例,1、 二维数组的定义 定义方式: 数据类型数组名常量表达式1常量表达式2;,数组元素的存放顺序 原因:内存是一维的 二维数组:按行序优先 多维数组:最右下标变化最快,例 int a34; float b25; int c234; int a3,4; (),行数,列数,元素个数=行数*列数,6.2 2维数组的定义和引用,二维数组理解,二维数组a是由3个元素组成,每个元素ai由包含4个元素 的一维数组组成,2、二维数组元素的引用 形式: 数组名下标1下标2 3、二维数组元素的初始化 分行初始化:,存储类型符 数据类型 数组变量名行常量表达式列常量表达式 第0行初值表,第1行初值表,最后1行初值表;,按元素排列顺序初始化,存储类型符 数据类型 数组变量名行常量表达式列常量表达式 初值表 ;,4、二维数组在程序中赋值,例: 通过键盘输入对二维数组a各元素赋值 int i, j, a23; for (i = 0; i 2; i+) for (j = 0; j 3; j+) scanf (%d, ,5、二维数组的应用举例,【例1】 输入多个学生多门课程的成绩,分别求每个学生的平均成绩和每门课程的平均成绩。,程序设计思想: 要满足上述程序的要求,必须定义一个二维数组,用来存放学生各门课的成绩。这个数组的每一行表示某个学生的各门课的成绩及其平均成绩,每一列表示某门课的所有学生成绩及该课程的平均成绩。因此,在定义这个学生成绩的二维数组时行数和列数要比学生人数及课程门数多1。成绩数据的输入输出以及每个学生的平均成绩、各门课程的平均成绩的计算方法比较简单。,#include #define NUM_std 5 /定义符号常量学生人数为5 #define NUM_course 4 /定义符号常量课程门数为4 void main ( ) int i, j; /定义成绩数组,各元素初值为0 float scoreNUM_std+1NUM_course+1 = 0; for (i = 0; i NUM_std; i+) for (j = 0; j NUM_course; j+) printf (input the mark of %dth courseof %dth student: , j+1, i+1); scanf (%f, /输入第i个学生的第j门课的成绩 ,for (i = 0; i NUM_std; i+) for (j = 0; j NUM_course; j+) scoreiNUM_course += scoreij; /求第i个学生的总成绩 scoreNUM_stdj += scoreij; /求第j门课的总成绩 scoreiNUM_course /= NUM_course; /求第i个人的平均成绩 for (j = 0; j NUM_course; j+) scoreNUM_stdj /= NUM_std; /求第j门课的平均成绩,printf ( NO. C1 C2 C3 C4 AVERn); /输出每个学生的各科成绩和平均成绩 for (i = 0; i NUM_std; i+) printf (STU%dt, i+1); for (j = 0; j NUM_course+1; j+) printf (%6.1ft, scoreij); printf (n); printf (-); /输出1条短划线 printf (nAVER_C ); for (j = 0; j NUM_course; j+) /输出每门课程的平均成绩 printf (%6.1ft, scoreNUM_stdj); printf (n); ,【例2】读入下表中值到数组,分别求各行、各列及表中所有数之和,#include void main ( ) int x54, i, j; for (i = 0; i 4; i+) for (j = 0; j 3; j+) scanf (%d, ,for (i = 0; i 5; i+) for (j = 0; j 4; j+) printf (%5dt, xij); printf (n); ,例 有一个34的矩阵,要求编程序以求出其中值最大的那个元素的值及其所在的行号和列号。 算法: 首先把第一个元素a00作为 临时最大值max,然后把临时最 大值max与每一个元素aij进 行比较,若aijmax, 把aij作为新的临时最大值, 并记录下其下标i和j。 当全部元素比较完后, max是整个矩阵全部元素的最大值。,main() int i,j,row=0,colum=0,max; static int a34=1,2,3,4,9,8,7,6,-10,10,-5,2; max = a00; for(i=0; i max ) max = aij;row = i;colum = j; printf(max=%d, row=%d, colum=%dn,max,row,colum); ,6.3 字符数组与字符串,一、定义字符数组 例、 char c10; /* 定义c为字符数组,包含10个元素 */ c0=I; c1= ; c2=a; c3=m; c4= ; c5=h; c6=a; c7=p; c8=p; c9=y; 注意: 字符型与整型可以通用,但有区别: char c10; /* 在内存中占10字节 */ int c10; /* 在内存中占20字节 */,二、字符数组的初始化 1、逐个字符赋初值 static char c10 = I, ,a,m, ,h,a,p,p,y; static char c10 = c, ,p,r,o,g,r,a,m; /* 9 */ static char c = I, ,a,m, ,h,a,p,p,y; 注意: 初始化数据少于数组长度,多余元素自动为“空”(0,二进制0)。 指定初值时,若未指定数组长度,则长度等于初值个数。 花括号中字符的个数数组长度,语法错,以字符串常量赋初值 static char c11 = I am happy; static char c11 = I am happy; 注意: 数组长度字符串中的字符数 若数组长度字符串中的字符数,则出错 若数组长度字符串中的字符数,则后加 数组长度可省略,static char c = I am happy; static char c = I, ,a,m, ,h,a,p,p,y; 这两种初始化不等价为何? 字符数组本身不要求最后是 而字符串常量一定最后是,三、引用 引用一个元素,得到一个字符。 例:c2,四、字符数组的输入输出 1、用“%c”格式符逐个输入输出。 2、用“%s”格式符按字符串输入输出 注意: %c 输出,常用于字符数组中无标记的情况 %s输出,用于字符数组中有标记的情况,。,void main() char c10; int i ; for( i =0; i10; i+ ) scanf(“%c”, */ ,scanf(“%s”, c);,printf(“%s”, c);,例 输出一个钻石图形。 void main() static char diamond5= , ,*, ,*, ,*, *, , , ,*, ,*, ,*, , ,* ; int i, j; for(i=0;i5;i+) for(j=0;j5;j+) printf(%c,diamondij); printf(n); ,void main() static char diamond= “ *n*n *n *n *n”; printf(“%s”,diamond); ,案例 字符数组的整体输入与输出。 /*功能:将2维字符数组进行初始化,并在屏幕上输出*/ void main() int i; char name59= 张三山, 李四季, 王五魁, 刘六顺, 赵七巧; for(i=0;i5;i+) printf(n%st,namei); /*namei代表该行数组元素的首地址*/ ,字符串的输入,格式:gets(字符数组) /应包含的.h文件为stdio.h 功能:从键盘输入一以回车结束的字符串放入字符数组中, 并自动加0 说明:输入串长度应小于字符数组维数,例:char str80; gets (str); 当输入:Ilovechina!(表示空格,表示回车)时,str中的字符串将是:I love china!,gets函数,scanf函数,格式:scanf(%s, 字符数组) /应包含的.h文件为stdio.h 功能:从键盘输入一以空格或回车结束的字符串放入字符数 组中,并自动加0 说明:输入串长度应小于字符数组维数,例:char str80; scanf (%s, str); 当输入:hellochina时,str将是:hello,注意与gets的区别!,常用的字符串处理函数,scanf函数的使用:,例:利用scanf函数可以连续输入多个字符串,输入时,字符串间用空格分隔。 char str140, str240, str40; scanf (%s%s%s, str1, str2, str3); 输入:Ilovechina! str1:I,str2:love,str3:china!。,例:使用%ns格式控制符 限制输入的字符个数。 char str10; scanf (%9s, str); /最多可读入9个非空格字符到str中,字符串的输出,格式:puts(字符串地址) /应包含的.h文件为stdio.h 功能:向显示器输出字符串(输出完,换行) 说明:如果是字符数组,则必须以0结束,puts函数,printf函数,格式:printf(%s, 字符串地址) /应包含的.h文件为stdio.h 功能:依次输出字符串中的每个字符直到遇到字符0 (0不会被输出),例: char name = John Smith; printf (The name is: %sn, name); printf (Last name is: %sn, ,输出结果: The name is: John Smith Last name is: Smith First name is: John,3、字符及字符串操作的常用函数,字符串的长度,格式:strlen(字符串地址) /应包含的.h文件为string.h 功能:计算字符串长度 返值:返回字符串实际长度,不包括0在内,strlen函数,例: char str = 0123456789; printf (%d, strlen(str); /输出结果为10 printf (%d, strlen( /输出结果为5,3、字符及字符串操作的常用函数,字符串的复制,格式:strcpy (字符数组1,字符串2) /应包含的.h文件为string.h 功能:将字符串2拷贝到字符数组1中去 返值:返回字符数组1的首地址 说明:字符数组1必须足够大 拷贝时0一同拷贝 不能使用赋值语句为一个字符数组赋值,strcpy函数,例: char str120, str220; scanf (%s, str2); strcpy (str1, str2);,例: char str120, str220; str1 = Hello!; () str2 = str1; (),3、字符及字符串操作的常用函数,字符串比较,格式:strcmp (字符串1, 字符串2) /应包含的.h文件为string.h 功能:比较两个字符串 比较规则:对两串从左向右逐个字符比较(ASCII码), 直到遇到不同字符或0为止 返值:返回int型整数。a. 若字符串1 字符串2, 返回正整数 c. 若字符串1= 字符串2, 返回零 说明:字符串比较不能用“=”,必须用strcmp,strcmp函数,例: strcmp (“abcd”, “abCD”); /将返回一正整数; strcmp (“1234”, “12345”); /将返回一负整数; strcmp (hello, hello); /将返回0。,例:下面的程序要求用户输入密码,如果输入正确,则进行相应的程序运行,否则返回。 char password20; printf (input the password: ); scanf (%15s, password); if ( strcmp(password, administrator) != 0 ) return; ,不能写成 if (password=administrator),3、字符及字符串操作的常用函数,字符串的连接,格式:strcat (字符数组1, 字符数组2) /应包含的.h文件为string.h 功能:把字符数组2连到字符数组1后面 返值:返回字符数组1的首地址 说明:字符数组1必须足够大 连接前,两串均以0结束;连接后,串1的0取 消,新串最后加0,例:char str120 = 12345, str2 = 6789; strcat (str1, str2); printf (%s, str1); /将输出123456789,将字符串中大写字母转换成小写strlwr()函数 (1)调用方式:strlwr(字符串) (2)函数功能:将字符串中的大写字母转换成小写,其它字符(包括小写字母和非字母字符)不转换。 将字符串中小写字母转换成大写strupr()函数 (1)调用方式:strupr(字符串) (2)函数功能:将字符串中小写字母转换成大写,其它字符(包括大写字母和非字母字符)不转换。,【例】输入一行字符,统计其中单词的个数,单词之间用空格间隔。,设计分析: 按照题义,连续的一段不含空格类字符的字符串就是单词。将连续的若干个空格作为出现一次空格,那么单词的个数可以由空格出现的次数(连续的若干个空格看作一次空格,一行开头的空格不统计)来决定。如果当前字符是非空格类字符,而它的前一个字符是空格,则可看作是“新单词”开始,累计单词个数的变量加1;如果当前字符是非空格类字符,而前一个字符也是非空格类字符,则可看作是“旧单词”的继续,累计单词个数的变量取值保持不变。,#include #define IN 1 #define OUT 0 void main ( ) char string80, c; int i, num=0, word = OUT; gets (string); for (i = 0; (c = stringi) != 0; i+) if (c = ) /判断c是否为空格 word = OUT; else if (word = OUT) word = IN; num+; printf (There are %d words in the line.n, num); ,运行结果: I am a student There are 4 words in the line,2维字符数组存放字符串,例:char city 10 = BeiJing, ShangHai, TianJin, GuangZhou, WuHan ;,字符串结束标志,多余空位补0,【例2】输入多个城市的名字,按升序排列输出 。,#include #include #define CITYNUM 10 void main ( ) int i, j, k, num; char cityCITYNUM20; char str80; num = 0; /实际输入的城市数初始化为0 /输入城市名字符串(长度不能超过19) for (i = 0; i 19) /城市名字符串超过19时,重输 i-; continue; strcpy (cityi, str); /将输入的城市名保存到字符串数组中 num+; /实际输入的城市数增1 ,for (i = 0; i 0) k = j; if (k != i) /将最小城市名的字符串cityk与cityi交换 strcpy (str, cityi); strcpy (cityi, cityk); strcpy (cityk, str); for (i = 0; i num; i+) /显示排序后的结果 printf (%s , cityi); printf (n); ,运行结果: 输入为:beijing wuhan shanghai guangzhou tianjin beijing guangzhou shanghai tianjin wuhan,常见错误,int a10,i ; for(i=1;i=10;i+) .,下标越界,上机: 教材:P168-169, 1,7,8,9 实验:P144, 7,补充,求解幻方问题。 幻方是一种古老的数字游戏,n阶幻方就是把整数1n2排成nn的方阵,使得每行中的各元素之和,每列中各元素之和,以及两条对角线上的元素之和都是同一个数S,S称为幻方的幻和。在中世纪的欧洲,对幻方有某种神秘的概念,许多人配戴幻方以图避邪,奇数阶幻方的构造方法很简单,我们先来看一个三阶幻方:,各数在方阵中的位置可以这样确定: 首先把1放在最上一行正中间的方格中,然后把下一个整数放置到右上方,如果到达最上一行,下一个整数放在最后一行,就好象它在第一行的上面,如果到达最右端,则下一个整数放在最左端,就好象它在最右一列的右侧。当到达的方格中填上数值时,下一个整数就放在刚填写上数码的方格的正下方,照着三阶幻方,从1至9走一下,就可以明白它的构造方法。,#include #define MAX 15 void main ( ) int m, mm, i, j, k, ni, nj; int magicMAXMAX = 0; printf (Enter the number you wanted: ); scanf (%d, ,for (k = 1; k = mm; k+) magicij = k; /求右上方方格的坐标 if (i = = 0) /最上一行 ni = m - 1; /下一个位置在最下一行 else ni = i - 1; if (j = = m - 1) /最右端 nj = 0; /下一个位置在最左端 else nj = j + 1; /判断右上方方格是否已有数 if (magicninj = 0) /右上方无值 i = ni; j = nj; else /右上方方格已填上数 i+; ,for (i = 0; i m; i+) /显示填充的结果 for (j = 0; j m; j+) printf (%4d, magicij); printf (n); ,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!