第七章数组 本章重点 妆处理好循环与数组下标的关系,就掌握了数组的核心技术 数组的赋值方法 ↓一些典型算法:排序,查找,插入的过程 字符数组和字符串的根本区别在于程序在处理字符串时是以0 作为结束标志的 ↓字符串不能用赋值语句 7.1一维数组的定义和引用 1.一维数组的定义 定义方式为 类型说明符数组名[常量表达式] 例如:inta[10 1204609398050 a[o]a[1]a[2]a[3]a[4]a[5]a[6]a[T]a[8]a[9] 说明: 常量表达式用中括号括起 下标从0开始,inta[10] a[0],a[1] a[9] ·常量表达式必须是常量,不能是变量。 ●数组名后面的常量表达式只能用“[]”括起来,不能用“()” 号 2.一维数组元素的引用 每次可引用一个数组元素,不能引用整个数组。 个数组元素就如同一个简单变量 引用时应注意下标的值不要超过数组长度的范围 a[0}=a5]+a门7]-a[2*3]常量和表达式做下标 aj=a[+1; 变量做下标 aa[0=>a[ll 数组元素做下标 例7.1程序自已输入0-9,然后按逆序输出。 maino
第七章 数 组 本章重点: 处理好循环与数组下标的关系,就掌握了数组的核心技术. 数组的赋值方法. 一些典型算法:排序,查找,插入的过程 字符数组和字符串的根本区别在于程序在处理字符串时是以\0 作为结束标志的. 字符串不能用赋值语句. 7.1 一维数组的定义和引用 1.一维数组的定义 定义方式为: 类型说明符 数组名[常量表达式] 例如:int a[10]; ⚫ 数组名后面的常量表达式只能用“[ ]”括起来,不能用“( )” 号。 2. 一维数组元素的引用 每次可引用一个数组元素,不能引用整个数组。 一个数组元素就如同一个简单变量. 引用时应注意下标的值不要超过数组长度的范围。 a[0]=a[5]+a[7]-a[2*3] 常量和表达式做下标 a[i]=a[i]+1; 变量做下标 a[a[0]]=>a[1] 数组元素做下标 例 7.1 程序自已输入 0-9,然后按逆序输出。 main() {
for(i=0=9;计+)a[=i, for(i=9;1>=0;-) printf(" %od, ali); 3.一维数组的初始化 (1)在定义数组时对各元素指定初始值 inta[10}={1,2,34,5,6,78,9,10}; 等价于 int a[10 a0}1:a[l=2;a[2]=3;…a[9}=10; (2)可只对一部分元素赋以初值。 a[S}{1,3,5 a[0}=1;a]=3a[2]=5;a[3]a4]未确定 (3)数组可以不规定维数,在初始化赋值时,数组维数从0开始 被连续赋值。 例如 char fl=(a,b,'c') a[]={1,3,5}; (4)数组不赋初值,系统自动给所有实数组元素赋以0值。数 组元素的赋值可以通过赋值语句或 scant函数输入 例7.2:求一组数(10个)的平均与总和。E51a maino i int i, sum, a[10]; float av for(i=0;i<10; scanf("%d",&a[),*数据输入* sum=o for(i=0;1<10;i++){ printf"%d"a[j);/*数据输出。并求和* sum=sum+al Iv=Sum/10.0 printf("%odn", sum) printf("%fn", av);
int i, a[10]; for (i=0;i=0;i--) printf(“%d”,a[i]); } 3.一维数组的初始化 (1)在定义数组时对各元素指定初始值。 int a[10]={1,2,3,4,5,6,7,8,9,10}; 等价于 int a[10]; a[0]=1;a[1]=2;a[2]=3; … a[9]=10; (2)可只对一部分元素赋以初值。 int a[5]={1,3,5}; a[0]=1;a[1]=3;a[2]=5; a[3],a[4]未确定 (3)数组可以不规定维数, 在初始化赋值时, 数组维数从 0 开始 被连续赋值。 例如: char f[]={'a', 'b', 'c'}; int a[ ]={1,3,5}; (4)数组不赋初值,系统自动给所有实数组元素赋以 0 值。数 组元素的赋值可以通过赋值语句或 scanf 函数输入。 例 7.2:求一组数(10 个)的平均与总和。E5_1a main() { int i,sum,a[10]; float av; for(i=0;i<10;i++) scanf("%d",&a[i]); /*数据输入*/ sum=0; for(i=0;i<10;i++) { printf("%d ",a[i]); /*数据输出。并求和*/ sum=sum+a[i]; } av=sum/10.0; printf("%d\n",sum); printf("%f\n",av); }
4.一维数组举例 例7.3:对10个数由小到大排序(冒泡排序)。 冒泡排序法的基本思想: 将相邻两个数相比较,将小的调到前头。不断比较,直 到将最后两数比较处理完毕。每进行一轮,把剩下的数 中最大的一个移到最后位置。 9854206137第1次,a[0和a[1比较 8954206137第2次,a[1和a[2]比较 8594206137 8549206137 第次,;和a[i+1比较 8542906137 8542096137 or (j=0;jalj+1) 8542069137 i temp=aljI 8542061937 aLJ 8542061397 Lj+1]=temp: 1 8542061379 # include“ stdio.h no {inta[10={9,854,2,0,6,1,3,7 nt in=10 for (i=0; i<n-1; i++) for〔=0;n-ij++) if (ajaj+iD i temp=ajl, alj=alj+l; temp; 1 for(i0; i<9; i+ p %3d",a[i) 例7.4:对N个数由小到大排序(选择排序)。 选择法的基本思想 从所有元素中选择一个最小元素放在a0],作为第一轮,第 二轮从a[]开始到最后的各元素中选择一个最小元素,放在a[1 中,依次类推,n个数进行n-1轮
4.一维数组举例 例 7.3:对 10 个数由小到大排序(冒泡排序)。 冒泡排序法的基本思想: 将相邻两个数相比较,将小的调到前头。不断比较,直 到将最后两数比较处理完毕。每进行一轮,把剩下的数 中最大的一个移到最后位置。 #include “stdio.h” main() { int a[10]={9,8,5,4,2,0,6,1,3,7} int i, n=10; for (i=0;ia[j+1]) { temp=a[j],a[j]=a[j+1];a[j+1]=temp;} for (i=0;i<9;i++) printf(“%3d”,a[i]); } 例 7.4:对 N 个数由小到大排序(选择排序)。 选择法的基本思想: 从所有元素中选择一个最小元素放在 a[0],作为第一轮,第 二轮从 a[1]开始到最后的各元素中选择一个最小元素,放在 a[1] 中,依次类推,n 个数进行 n-1 轮
351472 第一轮:1857310 第二轮:1357810 for(i=0,1ay &&xaly-ID) printf("no find! ) break; l if (x<ayD
3 5 1 4 7 2 第一轮:1 8 5 7 3 10 第二轮:1 3 5 7 8 10 for(i=0,ia[y] && xa[y-1])) {printf("no find!");break;} if (x<a[y]) m=y;
if(x>alyD if(x==ayd printf"%d at the position %d", x, y+ 1); break; 3 while(1); 7.2二维数组 721.二维数组 (1)一般说明格式是: 类型数组名[第1维长度第2维长度] 2).例如 int m32 *定义一个整数型的二维数组* char c[3[4],/*定义一个字符型的三维数组* 数组m[32共有3*2=6个元素,顺序为 mO[oJ,m[oj[1l,m[1oj,m[1[l,m[2]o],m[2][1] 数组c34共有3*4=12个元素,顺序为 [0J10]c[oJ[1] c[02], c0J3 cl1JoJcllll c[12], c[l3 c{2][o]c[2u1l.c[22],c[2[3 (3).数组占用的内存空间(即字节数)的计算式为 字节数=第1维长度*第2维长度*该数组数据类型占用的字节数 722二维数组的初始化 intp[2]3}={{2,-9,0},{8,2,-5}};/定义数组p并初始化/ intm②2][4}={{27,-5,19,3},{1,8,-14,-2}} (2)多维数组存储是连续的,因此可以用一维数组初始化的办法 来初始化多维数组。 例如 intx[2[3}={1,2,3,4,5,6};/用一维数组来初始化二维数组* 对数组初始化时,如果初值表中的数据个数比数组元素少,则 不足的数组元素自动用0来填补 3.二维数组的引用 行号和列号都是从0开始的,并注意行号和列号不要超过数组 定义的范围 a[]=2 maino intm[21[2];
if (x>a[y]) n=y; if (x==a[y]) printf("%d at the position %d",x,y+1);break;} } while (1); } 7.2 二维数组 7.2.1.二维数组 (1)一般说明格式是: 类型 数组名[第 1 维长度][第 2 维长度] (2).例如: int m[3][2]; /*定义一个整数型的二维数组*/ char c[3][4]; /*定义一个字符型的三维数组*/ 数组 m[3][2]共有 3*2=6 个元素, 顺序为: m[0][0], m[0][1], m[1][0], m[1][1], m[2][0], m[2][1]; 数组 c[3][4]共有 3*4=12 个元素, 顺序为: c[0][0] c[0][1], c[0][2], c[0][3] c[1][0] c[1][1], c[1][2], c[1][3] c[2][0] c[2][1], c[2][2], c[2][3] (3). 数组占用的内存空间(即字节数)的计算式为: 字节数=第1 维长度*第2 维长度*该数组数据类型占用的字节数 7.2.2.二维数组的初始化 ( 1) int p[2][3]={{2, -9, 0}, {8, 2, -5}}; /*定义数组 p 并初始化/* int m[2][4]={{27, -5, 19, 3}, {1, 8, -14, -2}}; (2) 多维数组存储是连续的, 因此可以用一维数组初始化的办法 来初始化多维数组。 例如: int x[2][3]={1, 2, 3, 4, 5, 6}; /*用一维数组来初始化二维数组*/ (3) 对数组初始化时, 如果初值表中的数据个数比数组元素少, 则 不足的数组元素自动用 0 来填补。 3. 二维数组的引用 行号和列号都是从 0 开始的,并注意行号和列号不要超过数组 定义的范围。 a[0][0]=1; a[0][1]=2;…. main() { int m[2][2];
float 3 m[ojoj=0,m[OI[=17,m[1]o=21;/*数组元素赋值* n[0=109.5,n[1]=-829,n[2}=0.7; 例76二维数组元素的输入。 例77将一个2x3矩阵转置。 i=123 b=25 456 36 分析:对数组a,列先与行变化对于数组b行先于列变化 for(〔i=0;i<2;i++) for〔=0j<3++) bili=all 4.多维数组 多维数组的一般说明格式是 类型数组名[第n维长度][第n1维长度]…第1维长度 char c[2][2J3,/*定义一个字符型的三维数组* 数组c[2D2[3共有2*2*3=12个元素,顺序为 [0J1OJOL c[[[0J0J2 cOJ1JoJ cloD[], c[0J[12 c1oJoclloJ1c1oJ21 c[1o,[[]c[l[12] 7.3字符数组和字符串 问题 (1)什么是字符串?字符串与字符常量有何区别? 1.字符数组 (1)字符数组的定义
float n[3]; m[0][0]=0, m[0][1]=17, m[1][0]=21;/*数组元素赋值*/ n[0]=109.5, n[1]=-8.29, n[2]=0.7; . . . } 例 7.6 二维数组元素的输入。 例 7.7 将一个 2x3 矩阵转置。 分析:对数组 a,列先与行变化,对于数组 b,行先于列变化. for (i=0;i<2;i++) for (j=0;j<3;j++) b[j][i]=a[i][j] 4.多维数组 多维数组的一般说明格式是: 类型 数组名[第 n 维长度][第 n-1 维长度]......[第 1 维长度]; char c[2][2][3]; /*定义一个字符型的三维数组*/ 数组 c[2][2][3]共有 2*2*3=12 个元素, 顺序为: c[0][0][0], c[0][0][1], c[0][0][2], c[0][1][0], c[0][1][1], c[0][1][2], c[1][0][0], c[1][0][1], c[1][0][2], c[1][1][0], c[1][1][1], c[1][1][2], 7.3 字符数组和字符串 问题: (1)什么是字符串?字符串与字符常量有何区别? 1.字符数组 (1) 字符数组的定义
ar (2)字符数组的初始化 ①.逐个为数组各元素指定一个初值字符 char c10=fc,'h,a') 注意:初始化字符个数大于字符数组长度,则出现语法错误。 如果初始个数小于数组长度,则其余的元素自动定为空 字符(即“0°) char“0“0’“0 40 410410 ②对一个字符数组指定一个字符串初值 char cl={ I am a student”}或 char c=' I am a student” 些时数组的长度应为字符串个数加1。(为什么?) (3)字符数组的输入输出。 ①单个字符数组元素的输入输出用 scanf、 printf函数的“%c” 格式 ②将整个字符串一次输入或输出,用 scanf、 printf函数的“%s” 格式 char st[10]; scanf(“%os3”str),/用数组名代表数组的起始地址,因此不需要 地址符号 printf(" %s”,str) ③输入一个字符串时,从键盘直接输入,然后按回车。不需 要输入双引号。若输入的字符串中有空格,只接收空格前的字符。输 入的字符串中有空格,可用gets函数输入 ④若数组长度大于字符串实际长度,也是输出到遇“0’结束 ⑤若字符数组中包含多个03,则遇第一个)0时输出结束。 ⑥输出字符不包括结束符“\0 例输入输出字符串。 输入 windows&c∠的输出结果如何? 3.字符数组与字符串 (1)字符数组不一定有结束标志“0;有结束标志的字符数组 是字符串。 (2)字符串可以存放在字符数组中,但字符串与字符数组可以 长度不相等 char cl={char”};
char s[10]; (2)字符数组的初始化 ①. 逐个为数组各元素指定一个初值字符 char c[10]={‘c’,’ ‘,’h’,’a’} 注意:初始化字符个数大于字符数组长度,则出现语法错误。 如果初始个数小于数组长度,则其余的元素自动定为空 字符(即‘\0’). ② 对一个字符数组指定一个字符串初值 char c[]={”I am a student”}或 char c[]=”I am a student” 些时数组的长度应为字符串个数加 1。(为什么?) (3)字符数组的输入输出。 ①单个字符数组元素的输入输出用 scanf、 printf 函数的“%c” 格式。 ②将整个字符串一次输入或输出,用 scanf、printf 函数的“%s” 格式 char st[10]; scanf(“%s”,str); /*用数组名代表数组的起始地址,因此不需要 地址符号。*/ printf(“%s”,str); ③输入一个字符串时,从键盘直接输入,然后按回车。不需 要输入双引号。若输入的字符串中有空格,只接收空格前的字符。输 入的字符串中有空格,可用 gets 函数输入。 ④若数组长度大于字符串实际长度,也是输出到遇‘\0’结束。 ⑤若字符数组中包含多个’\0’,则遇第一个’\0’时输出结束。 ⑥输出字符不包括结束符‘\0’. 例:输入输出字符串。 输入 windows & c↙的输出结果如何? 3.字符数组与字符串 (1) 字符数组不一定有结束标志‘\0’;有结束标志的字符数组 是字符串。 (2) 字符串可以存放在字符数组中,但字符串与字符数组可以 长度不相等。 char c[]={“char”};
等价于 static char cl[5}{c,h,a','r;0}; 不等价于 static char c2[4}={ch’;a,r} 7.4字符串的处理函数 1.puts0和 gets函数 (1).putO函数 pusO函数用来向标准输出设备(屏幕)写字符串并换行, 其调用格式为 puts(s); 其中s为字符串变量(字符串数组名) puts函数的作用与语 printf("sn",s)相同。 例 maino char s20=" Thank you";/*定义字符串数组和指针变量* puts(s) 说明 ① puts函数只能输出字符串,不能输出数值或进行格式变 换 ②可以将字符串直接写入 puts函数中。如 puts("Hello, Turbo C2.0") (2). gets函数 gets函数用来从标准输入设备(键盘)读取字符串直到回车结束, 但回车符不属于这个字符串。其调用格式为 gets(s) 其中s为字符串变量(字符串数组名) 例:78 main char s]: printf("What's your name? n") gets(s) 等待输入字符串直到 回车结束* puts(s) *将输入的字符串输出* puts("How old are you? " puts(f)
等价于 static char c1[5]={‘c’,’h’,’a’,’r’,’\0’}; 不等价于 static char c2[4]={‘c’,’h’,’a’,’r’}; 7.4 字符串的处理函数 1.puts()和 gets()函数 (1). puts()函数 puts()函数用来向标准输出设备(屏幕)写字符串并换行, 其调用格式为: puts(s); 其中 s 为字符串变量(字符串数组名)。 puts()函数的作用与语 printf("%s\n", s)相同。 例: main() { char s[20]= "Thank you"; /*定义字符串数组和指针变量*/ puts(s); } 说明: ① puts()函数只能输出字符串, 不能输出数值或进行格式变 换。 ② 可以将字符串直接写入 puts()函数中。如: puts("Hello, Turbo C2.0"); (2). gets()函数 gets()函数用来从标准输入设备(键盘)读取字符串直到回车结束, 但回车符不属于这个字符串。其调用格式为: gets(s); 其中 s 为字符串变量(字符串数组名)。 例:7.8 main() { char s[20]; printf("What's your name?\n"); gets(s); /*等待输入字符串直到 回车结束*/ puts(s); /*将输入的字符串输出*/ puts("How old are you?"); puts(f); }
2、字符串运算函数 字符串运算函数在头文件 string h中,因些程序中要用字符串运算 函数,必须用# Include"string. h (1)字符串拷贝函数 ① strcpy(字符数组1,字符串2 ②作用:将字符串2拷贝到字符数组1中 Char strl[loj, str2[=( china) Strcpy(strI,sr2),/*问strl= china;srl=st2对不对?) ③ strcpy(strl,st2,2)的作用。/*拷贝前2个字符* ↓不能用赋值语句将一个字符串常量或字符数组直接赋给一个字 符数组。但可以给一个字符变量或字符数组元素赋值。 如下面的赋值是不合法的。 x static char str1=("China"), str2/201 c str2=strl; (X) 下面的赋值是合法的 x char a[5],cl, c2 妆cl=A,c2=B a[=C';a[l=ih',a[2=i';a3}=n;a[4]=a (2)字符串连接函数 stra(字符数组1,字符数组2 作用:将两个字符串连接成为一个字符串。 (3)字符串比较函数 strcmp(strl, str 2) 功能:当strl与st2完全相同,返回值为0 当strl>st2,则返回值为正整数 当strl<st2,则返回值为负整数 比较规则:一个一个比较,直到出现不同的字符或遇到“0” 为止。 注意:两个字符串不能用关系运算符比较,如下面的写法是 不合法的 8 if(strI==str2)printf("yes' 应写成if( strcmp(str1st2=0) &printf(" yes")
2、字符串运算函数 字符串运算函数在头文件 string.h 中,因些程序中要用字符串运算 函数,必须用 #include “string.h”。 (1)字符串拷贝函数 ①strcpy(字符数组 1,字符串 2) ②作用:将字符串 2 拷贝到字符数组 1 中。 Char str1[10],str2[]={“china”}; Strcpy(str1,str2); /* 问 str1=”china”; str1=str2 对不对?); ③ strcpy(str1,str2,2)的作用。/*拷贝前 2 个字符*/ 不能用赋值语句将一个字符串常量或字符数组直接赋给一个字 符数组。但可以给一个字符变量或字符数组元素赋值。 如下面的赋值是不合法的。 static char str1={“China”},str2[20]; str2=str1;(╳) 下面的赋值是合法的。 char a[5],c1,c2; c1=‘A’; c2=‘B’; a[0]=‘C’;a[1]=‘h’,a[2]=‘i’;a[3]=’n’;a[4]=’a’ (2)字符串连接函数 strcat(字符数组 1,字符数组 2) 作用:将两个字符串连接成为一个字符串。 (3)字符串比较函数 strcmp(str1,str2) 功能:当 str1 与 str2 完全相同,返回值为 0。 当 str1>str2,则返回值为正整数 当 str1<str2,则返回值为负整数 比较规则:一个一个比较,直到出现不同的字符或遇到“\0” 为止。 注意:两个字符串不能用关系运算符比较, 如下面的写法是 不合法的: if (str1==str2) printf(”yes”); 应写成 if (strcmp(str1,str2)==0) printf(“yes”);
(4)求字符串长度函数 strlen( computer”) 注意:函数返回值不包括0在内,即测出字符串的实际字 符个数。 例7.9:输入一行字符,统计出有多少个单词。单词字间用空隔分 隔 #include"stdio. h maino char stringl81 int inum=0 word=0 C gets(string) for(i=0 (c=string!=0; 1++) if(c==word= else if (word==0 i word=l; num++, printf("there are %d words in the linen",num) 小经验: 当处理的数据很多,又希望用循环来控制时使用数组 当运算的中间结果需要保存时使用数组 维数组典型用法 排序 查找 插入 删除 分类统计
(4)求字符串长度函数 strlen(“computer”) 注意:函数返回值不包括’\0’在内,即测出字符串的实际字 符个数。 例 7.9:输入一行字符,统计出有多少个单词。单词字间用空隔分 隔。 #include "stdio.h" main() { char string[81]; int i,num=0,word=0; char c; gets(string); for(i=0;(c=string[i])!='\0';i++) if (c==' ') word=0; else if (word==0) { word=1;num++;} printf("there are %d words in the line\n",num); } 小经验: – 当处理的数据很多,又希望用循环来控制时,使用数组 – 当运算的中间结果需要保存时,使用数组 一维数组典型用法 – 排序 – 查找 – 插入 – 删除 – 分类统计